From dfad83cb7193effb6c853a5c7337ac2274a2e2fc Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 30 Mar 2021 20:22:07 -0700 Subject: MIPS: Add support for CONFIG_DEBUG_VIRTUAL Provide hooks to intercept bad usages of virt_to_phys() and __pa_symbol() throughout the kernel. To make this possible, we need to rename the current implement of virt_to_phys() into __virt_to_phys_nodebug() and wrap it around depending on CONFIG_DEBUG_VIRTUAL. A similar thing is needed for __pa_symbol() which is now aliased to __phys_addr_symbol() whose implementation is either the direct return of RELOC_HIDE or goes through the debug version. Signed-off-by: Florian Fainelli Signed-off-by: Thomas Bogendoerfer --- arch/mips/mm/physaddr.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 arch/mips/mm/physaddr.c (limited to 'arch/mips/mm/physaddr.c') diff --git a/arch/mips/mm/physaddr.c b/arch/mips/mm/physaddr.c new file mode 100644 index 000000000000..a1ced5e44951 --- /dev/null +++ b/arch/mips/mm/physaddr.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static inline bool __debug_virt_addr_valid(unsigned long x) +{ + /* high_memory does not get immediately defined, and there + * are early callers of __pa() against PAGE_OFFSET + */ + if (!high_memory && x >= PAGE_OFFSET) + return true; + + if (high_memory && x >= PAGE_OFFSET && x < (unsigned long)high_memory) + return true; + + /* + * MAX_DMA_ADDRESS is a virtual address that may not correspond to an + * actual physical address. Enough code relies on + * virt_to_phys(MAX_DMA_ADDRESS) that we just need to work around it + * and always return true. + */ + if (x == MAX_DMA_ADDRESS) + return true; + + return false; +} + +phys_addr_t __virt_to_phys(volatile const void *x) +{ + WARN(!__debug_virt_addr_valid((unsigned long)x), + "virt_to_phys used for non-linear address: %pK (%pS)\n", + x, x); + + return __virt_to_phys_nodebug(x); +} +EXPORT_SYMBOL(__virt_to_phys); + +phys_addr_t __phys_addr_symbol(unsigned long x) +{ + /* This is bounds checking against the kernel image only. + * __pa_symbol should only be used on kernel symbol addresses. + */ + VIRTUAL_BUG_ON(x < (unsigned long)_text || + x > (unsigned long)_end); + + return __pa_symbol_nodebug(x); +} +EXPORT_SYMBOL(__phys_addr_symbol); -- cgit