Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 185aed75 authored by Paul Mundt's avatar Paul Mundt
Browse files

sh: Provide a sane valid_phys_addr_range() to prevent TLB reset with PMB.



With the PMB enabled, only P1SEG and up are covered by the PMB mappings,
meaning that situations where out-of-bounds physical addresses are read
from will lead to TLB reset after the PMB miss, allowing for use cases
like dd if=/dev/mem to reset the TLB.

Fix this up to make sure the reference is between __MEMORY_START (phys)
and __pa(high_memory). This is coherent across all variants of sh/sh64
with and without MMU, though the PMB bug itself is only applicable to
SH-4A parts.

Reported-by: default avatarHideo Saito <saito@densan.co.jp>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent ade7a9b4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -293,6 +293,10 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 */
#define xlate_dev_kmem_ptr(p)	p

#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
int valid_phys_addr_range(unsigned long addr, size_t size);
int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);

#endif /* __KERNEL__ */

#endif /* __ASM_SH_IO_H */
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
# Makefile for the Linux SuperH-specific parts of the memory manager.
#

obj-y			:= init.o extable_32.o consistent.o
obj-y			:= init.o extable_32.o consistent.o mmap.o

ifndef CONFIG_CACHE_OFF
cache-$(CONFIG_CPU_SH2)		:= cache-sh2.o
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
# Makefile for the Linux SuperH-specific parts of the memory manager.
#

obj-y			:= init.o consistent.o
obj-y			:= init.o consistent.o mmap.o

mmu-y			:= tlb-nommu.o pg-nommu.o extable_32.o
mmu-$(CONFIG_MMU)	:= fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \

arch/sh/mm/mmap.c

0 → 100644
+31 −0
Original line number Diff line number Diff line
/*
 * arch/sh/mm/mmap.c
 *
 * Copyright (C) 2008  Paul Mundt
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/io.h>
#include <linux/mm.h>
#include <asm/page.h>

/*
 * You really shouldn't be using read() or write() on /dev/mem.  This
 * might go away in the future.
 */
int valid_phys_addr_range(unsigned long addr, size_t count)
{
	if (addr < (PAGE_OFFSET + (PFN_START << PAGE_SHIFT)))
		return 0;
	if (addr + count > __pa(high_memory))
		return 0;

	return 1;
}

int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
{
	return 1;
}