0001
0002 #include <linux/memblock.h>
0003 #include <linux/mmdebug.h>
0004 #include <linux/export.h>
0005 #include <linux/mm.h>
0006
0007 #include <asm/page.h>
0008 #include <linux/vmalloc.h>
0009
0010 #include "physaddr.h"
0011
0012 #ifdef CONFIG_X86_64
0013
0014 #ifdef CONFIG_DEBUG_VIRTUAL
0015 unsigned long __phys_addr(unsigned long x)
0016 {
0017 unsigned long y = x - __START_KERNEL_map;
0018
0019
0020 if (unlikely(x > y)) {
0021 x = y + phys_base;
0022
0023 VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE);
0024 } else {
0025 x = y + (__START_KERNEL_map - PAGE_OFFSET);
0026
0027
0028 VIRTUAL_BUG_ON((x > y) || !phys_addr_valid(x));
0029 }
0030
0031 return x;
0032 }
0033 EXPORT_SYMBOL(__phys_addr);
0034
0035 unsigned long __phys_addr_symbol(unsigned long x)
0036 {
0037 unsigned long y = x - __START_KERNEL_map;
0038
0039
0040 VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE);
0041
0042 return y + phys_base;
0043 }
0044 EXPORT_SYMBOL(__phys_addr_symbol);
0045 #endif
0046
0047 bool __virt_addr_valid(unsigned long x)
0048 {
0049 unsigned long y = x - __START_KERNEL_map;
0050
0051
0052 if (unlikely(x > y)) {
0053 x = y + phys_base;
0054
0055 if (y >= KERNEL_IMAGE_SIZE)
0056 return false;
0057 } else {
0058 x = y + (__START_KERNEL_map - PAGE_OFFSET);
0059
0060
0061 if ((x > y) || !phys_addr_valid(x))
0062 return false;
0063 }
0064
0065 return pfn_valid(x >> PAGE_SHIFT);
0066 }
0067 EXPORT_SYMBOL(__virt_addr_valid);
0068
0069 #else
0070
0071 #ifdef CONFIG_DEBUG_VIRTUAL
0072 unsigned long __phys_addr(unsigned long x)
0073 {
0074 unsigned long phys_addr = x - PAGE_OFFSET;
0075
0076 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
0077 VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
0078
0079 if (max_low_pfn) {
0080 VIRTUAL_BUG_ON((phys_addr >> PAGE_SHIFT) > max_low_pfn);
0081 BUG_ON(slow_virt_to_phys((void *)x) != phys_addr);
0082 }
0083 return phys_addr;
0084 }
0085 EXPORT_SYMBOL(__phys_addr);
0086 #endif
0087
0088 bool __virt_addr_valid(unsigned long x)
0089 {
0090 if (x < PAGE_OFFSET)
0091 return false;
0092 if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
0093 return false;
0094 if (x >= FIXADDR_START)
0095 return false;
0096 return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
0097 }
0098 EXPORT_SYMBOL(__virt_addr_valid);
0099
0100 #endif