linux/arch/x86/mm/physaddr.c
<<
>>
Prefs
   1#include <linux/bootmem.h>
   2#include <linux/mmdebug.h>
   3#include <linux/module.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
  13unsigned 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}
  31EXPORT_SYMBOL(__phys_addr);
  32
  33unsigned 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}
  42EXPORT_SYMBOL(__phys_addr_symbol);
  43#endif
  44
  45bool __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}
  65EXPORT_SYMBOL(__virt_addr_valid);
  66
  67#else
  68
  69#ifdef CONFIG_DEBUG_VIRTUAL
  70unsigned 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}
  83EXPORT_SYMBOL(__phys_addr);
  84#endif
  85
  86bool __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}
  96EXPORT_SYMBOL(__virt_addr_valid);
  97
  98#endif  /* CONFIG_X86_64 */
  99