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: Hideo Saito <saito@densan.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
ade7a9b4cc
commit
185aed7557
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
31
arch/sh/mm/mmap.c
Normal file
31
arch/sh/mm/mmap.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user