1 #include <linux/bootmem.h> 2 #include <linux/mmdebug.h> 3 #include <linux/export.h> 4 #include <linux/mm.h> 5 6 #include <asm/page.h> 7 8 #include "physaddr.h" 9 10 #ifdef CONFIG_X86_64 11 12 #ifdef CONFIG_DEBUG_VIRTUAL 13 unsigned long __phys_addr(unsigned long x) 14 { 15 unsigned long y = x - __START_KERNEL_map; 16 17 /* use the carry flag to determine if x was < __START_KERNEL_map */ 18 if (unlikely(x > y)) { 19 x = y + phys_base; 20 21 VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE); 22 } else { 23 x = y + (__START_KERNEL_map - PAGE_OFFSET); 24 25 /* carry flag will be set if starting x was >= PAGE_OFFSET */ 26 VIRTUAL_BUG_ON((x > y) || !phys_addr_valid(x)); 27 } 28 29 return x; 30 } 31 EXPORT_SYMBOL(__phys_addr); 32 33 unsigned long __phys_addr_symbol(unsigned long x) 34 { 35 unsigned long y = x - __START_KERNEL_map; 36 37 /* only check upper bounds since lower bounds will trigger carry */ 38 VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE); 39 40 return y + phys_base; 41 } 42 EXPORT_SYMBOL(__phys_addr_symbol); 43 #endif 44 45 bool __virt_addr_valid(unsigned long x) 46 { 47 unsigned long y = x - __START_KERNEL_map; 48 49 /* use the carry flag to determine if x was < __START_KERNEL_map */ 50 if (unlikely(x > y)) { 51 x = y + phys_base; 52 53 if (y >= KERNEL_IMAGE_SIZE) 54 return false; 55 } else { 56 x = y + (__START_KERNEL_map - PAGE_OFFSET); 57 58 /* carry flag will be set if starting x was >= PAGE_OFFSET */ 59 if ((x > y) || !phys_addr_valid(x)) 60 return false; 61 } 62 63 return pfn_valid(x >> PAGE_SHIFT); 64 } 65 EXPORT_SYMBOL(__virt_addr_valid); 66 67 #else 68 69 #ifdef CONFIG_DEBUG_VIRTUAL 70 unsigned long __phys_addr(unsigned long x) 71 { 72 unsigned long phys_addr = x - PAGE_OFFSET; 73 /* VMALLOC_* aren't constants */ 74 VIRTUAL_BUG_ON(x < PAGE_OFFSET); 75 VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x)); 76 /* max_low_pfn is set early, but not _that_ early */ 77 if (max_low_pfn) { 78 VIRTUAL_BUG_ON((phys_addr >> PAGE_SHIFT) > max_low_pfn); 79 BUG_ON(slow_virt_to_phys((void *)x) != phys_addr); 80 } 81 return phys_addr; 82 } 83 EXPORT_SYMBOL(__phys_addr); 84 #endif 85 86 bool __virt_addr_valid(unsigned long x) 87 { 88 if (x < PAGE_OFFSET) 89 return false; 90 if (__vmalloc_start_set && is_vmalloc_addr((void *) x)) 91 return false; 92 if (x >= FIXADDR_START) 93 return false; 94 return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT); 95 } 96 EXPORT_SYMBOL(__virt_addr_valid); 97 98 #endif /* CONFIG_X86_64 */ 99