1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/memblock.h> !! 2 #include <linux/bug.h> 3 #include <linux/mmdebug.h> << 4 #include <linux/export.h> 3 #include <linux/export.h> >> 4 #include <linux/types.h> >> 5 #include <linux/mmdebug.h> 5 #include <linux/mm.h> 6 #include <linux/mm.h> 6 7 >> 8 #include <asm/sections.h> >> 9 #include <asm/io.h> 7 #include <asm/page.h> 10 #include <asm/page.h> 8 #include <linux/vmalloc.h> !! 11 #include <asm/dma.h> 9 << 10 #include "physaddr.h" << 11 12 12 #ifdef CONFIG_X86_64 !! 13 static inline bool __debug_virt_addr_valid(unsigned long x) 13 << 14 #ifdef CONFIG_DEBUG_VIRTUAL << 15 unsigned long __phys_addr(unsigned long x) << 16 { 14 { 17 unsigned long y = x - __START_KERNEL_m !! 15 /* high_memory does not get immediately defined, and there 18 !! 16 * are early callers of __pa() against PAGE_OFFSET 19 /* use the carry flag to determine if !! 17 */ 20 if (unlikely(x > y)) { !! 18 if (!high_memory && x >= PAGE_OFFSET) 21 x = y + phys_base; !! 19 return true; >> 20 >> 21 if (high_memory && x >= PAGE_OFFSET && x < (unsigned long)high_memory) >> 22 return true; >> 23 >> 24 /* >> 25 * MAX_DMA_ADDRESS is a virtual address that may not correspond to an >> 26 * actual physical address. Enough code relies on >> 27 * virt_to_phys(MAX_DMA_ADDRESS) that we just need to work around it >> 28 * and always return true. >> 29 */ >> 30 if (x == MAX_DMA_ADDRESS) >> 31 return true; 22 32 23 VIRTUAL_BUG_ON(y >= KERNEL_IMA !! 33 return false; 24 } else { << 25 x = y + (__START_KERNEL_map - << 26 << 27 /* carry flag will be set if s << 28 VIRTUAL_BUG_ON((x > y) || !phy << 29 } << 30 << 31 return x; << 32 } 34 } 33 EXPORT_SYMBOL(__phys_addr); << 34 35 35 unsigned long __phys_addr_symbol(unsigned long !! 36 phys_addr_t __virt_to_phys(volatile const void *x) 36 { 37 { 37 unsigned long y = x - __START_KERNEL_m !! 38 WARN(!__debug_virt_addr_valid((unsigned long)x), 38 !! 39 "virt_to_phys used for non-linear address: %pK (%pS)\n", 39 /* only check upper bounds since lower !! 40 x, x); 40 VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE) << 41 41 42 return y + phys_base; !! 42 return __virt_to_phys_nodebug(x); 43 } 43 } 44 EXPORT_SYMBOL(__phys_addr_symbol); !! 44 EXPORT_SYMBOL(__virt_to_phys); 45 #endif << 46 45 47 bool __virt_addr_valid(unsigned long x) !! 46 phys_addr_t __phys_addr_symbol(unsigned long x) 48 { 47 { 49 unsigned long y = x - __START_KERNEL_m !! 48 /* This is bounds checking against the kernel image only. 50 !! 49 * __pa_symbol should only be used on kernel symbol addresses. 51 /* use the carry flag to determine if !! 50 */ 52 if (unlikely(x > y)) { !! 51 VIRTUAL_BUG_ON(x < (unsigned long)_text || 53 x = y + phys_base; !! 52 x > (unsigned long)_end); 54 << 55 if (y >= KERNEL_IMAGE_SIZE) << 56 return false; << 57 } else { << 58 x = y + (__START_KERNEL_map - << 59 << 60 /* carry flag will be set if s << 61 if ((x > y) || !phys_addr_vali << 62 return false; << 63 } << 64 53 65 return pfn_valid(x >> PAGE_SHIFT); !! 54 return __pa_symbol_nodebug(x); 66 } 55 } 67 EXPORT_SYMBOL(__virt_addr_valid); !! 56 EXPORT_SYMBOL(__phys_addr_symbol); 68 << 69 #else << 70 << 71 #ifdef CONFIG_DEBUG_VIRTUAL << 72 unsigned long __phys_addr(unsigned long x) << 73 { << 74 unsigned long phys_addr = x - PAGE_OFF << 75 /* VMALLOC_* aren't constants */ << 76 VIRTUAL_BUG_ON(x < PAGE_OFFSET); << 77 VIRTUAL_BUG_ON(__vmalloc_start_set && << 78 /* max_low_pfn is set early, but not _ << 79 if (max_low_pfn) { << 80 VIRTUAL_BUG_ON((phys_addr >> P << 81 BUG_ON(slow_virt_to_phys((void << 82 } << 83 return phys_addr; << 84 } << 85 EXPORT_SYMBOL(__phys_addr); << 86 #endif << 87 << 88 bool __virt_addr_valid(unsigned long x) << 89 { << 90 if (x < PAGE_OFFSET) << 91 return false; << 92 if (__vmalloc_start_set && is_vmalloc_ << 93 return false; << 94 if (x >= FIXADDR_START) << 95 return false; << 96 return pfn_valid((x - PAGE_OFFSET) >> << 97 } << 98 EXPORT_SYMBOL(__virt_addr_valid); << 99 << 100 #endif /* CONFIG_X86_64 */ << 101 57
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.