From 8dbb653322f87451b11b085a4bcf5a924c7a4179 Mon Sep 17 00:00:00 2001 From: tao zeng Date: Tue, 20 Nov 2018 12:14:57 +0800 Subject: [PATCH] mm: check phys_to_xxxx macro on 32bit OS [1/1] PD#SWPL-1909 Problem: If physical address of a memory location is not in linear mapping range, then any caller with phys_to_xxxx to get a pointer will cause bug. Solution: Check input address range for phys_to_xxxx to get a BUG output. This change is used for debug Verify: P212 Change-Id: I13bcaa3983e2d730b8d2bc03cd28c62585f49969 Signed-off-by: tao zeng --- arch/arm/include/asm/memory.h | 13 +++++++++++++ arch/arm/mm/mmu.c | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 76cbd9c674df..5ecadde3b02c 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -238,14 +238,27 @@ static inline unsigned long __phys_to_virt(phys_addr_t x) #define PHYS_OFFSET PLAT_PHYS_OFFSET #define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT)) +#ifdef CONFIG_AMLOGIC_MODIFY +extern unsigned long phys_check(phys_addr_t x); +extern unsigned long virt_check(unsigned long x); +extern int scheduler_running; +#endif static inline phys_addr_t __virt_to_phys(unsigned long x) { +#ifdef CONFIG_AMLOGIC_MODIFY + return virt_check(x); +#else return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; +#endif } static inline unsigned long __phys_to_virt(phys_addr_t x) { +#ifdef CONFIG_AMLOGIC_MODIFY + return phys_check(x); +#else return x - PHYS_OFFSET + PAGE_OFFSET; +#endif } #endif diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index f7c741358f37..7099113b1aa8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1640,3 +1640,39 @@ void __init paging_init(const struct machine_desc *mdesc) empty_zero_page = virt_to_page(zero_page); __flush_dcache_page(NULL, empty_zero_page); } + +#ifdef CONFIG_AMLOGIC_MODIFY +unsigned long notrace phys_check(phys_addr_t x) +{ + unsigned long addr; + struct page *page; + + addr = x - PHYS_OFFSET + PAGE_OFFSET; + if (scheduler_running) { + page = phys_to_page(x); + + /* + * if physical address is not in linear mapping range, + * then this will cause BUG + */ + if (is_vmalloc_or_module_addr((const void *)addr) || + PageHighMem(page)) { + pr_err("BAD USING of phys_to_virt, addr:%x, page:%lx\n", + x, page_to_pfn(page)); + dump_stack(); + } + } + return addr; +} +EXPORT_SYMBOL(phys_check); + +unsigned long notrace virt_check(unsigned long x) +{ + if (scheduler_running && (x >= VMALLOC_START || x <= PAGE_OFFSET)) { + pr_err("bad input of virt:%lx\n", x); + dump_stack(); + } + return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; +} +EXPORT_SYMBOL(virt_check); +#endif -- 2.20.1