linux/include/asm-x86/pgtable.h
<<
>>
Prefs
   1#ifndef _ASM_X86_PGTABLE_H
   2#define _ASM_X86_PGTABLE_H
   3
   4#define USER_PTRS_PER_PGD       ((TASK_SIZE-1)/PGDIR_SIZE+1)
   5#define FIRST_USER_ADDRESS      0
   6
   7#define _PAGE_BIT_PRESENT       0
   8#define _PAGE_BIT_RW            1
   9#define _PAGE_BIT_USER          2
  10#define _PAGE_BIT_PWT           3
  11#define _PAGE_BIT_PCD           4
  12#define _PAGE_BIT_ACCESSED      5
  13#define _PAGE_BIT_DIRTY         6
  14#define _PAGE_BIT_FILE          6
  15#define _PAGE_BIT_PSE           7       /* 4 MB (or 2MB) page */
  16#define _PAGE_BIT_PAT           7       /* on 4KB pages */
  17#define _PAGE_BIT_GLOBAL        8       /* Global TLB entry PPro+ */
  18#define _PAGE_BIT_UNUSED1       9       /* available for programmer */
  19#define _PAGE_BIT_UNUSED2       10
  20#define _PAGE_BIT_UNUSED3       11
  21#define _PAGE_BIT_PAT_LARGE     12      /* On 2MB or 1GB pages */
  22#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
  23
  24/*
  25 * Note: we use _AC(1, L) instead of _AC(1, UL) so that we get a
  26 * sign-extended value on 32-bit with all 1's in the upper word,
  27 * which preserves the upper pte values on 64-bit ptes:
  28 */
  29#define _PAGE_PRESENT   (_AC(1, L)<<_PAGE_BIT_PRESENT)
  30#define _PAGE_RW        (_AC(1, L)<<_PAGE_BIT_RW)
  31#define _PAGE_USER      (_AC(1, L)<<_PAGE_BIT_USER)
  32#define _PAGE_PWT       (_AC(1, L)<<_PAGE_BIT_PWT)
  33#define _PAGE_PCD       (_AC(1, L)<<_PAGE_BIT_PCD)
  34#define _PAGE_ACCESSED  (_AC(1, L)<<_PAGE_BIT_ACCESSED)
  35#define _PAGE_DIRTY     (_AC(1, L)<<_PAGE_BIT_DIRTY)
  36#define _PAGE_PSE       (_AC(1, L)<<_PAGE_BIT_PSE)      /* 2MB page */
  37#define _PAGE_GLOBAL    (_AC(1, L)<<_PAGE_BIT_GLOBAL)   /* Global TLB entry */
  38#define _PAGE_UNUSED1   (_AC(1, L)<<_PAGE_BIT_UNUSED1)
  39#define _PAGE_UNUSED2   (_AC(1, L)<<_PAGE_BIT_UNUSED2)
  40#define _PAGE_UNUSED3   (_AC(1, L)<<_PAGE_BIT_UNUSED3)
  41#define _PAGE_PAT       (_AC(1, L)<<_PAGE_BIT_PAT)
  42#define _PAGE_PAT_LARGE (_AC(1, L)<<_PAGE_BIT_PAT_LARGE)
  43
  44#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
  45#define _PAGE_NX        (_AC(1, ULL) << _PAGE_BIT_NX)
  46#else
  47#define _PAGE_NX        0
  48#endif
  49
  50/* If _PAGE_PRESENT is clear, we use these: */
  51#define _PAGE_FILE      _PAGE_DIRTY     /* nonlinear file mapping, saved PTE; unset:swap */
  52#define _PAGE_PROTNONE  _PAGE_PSE       /* if the user mapped it with PROT_NONE;
  53                                           pte_present gives true */
  54
  55#define _PAGE_TABLE     (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
  56#define _KERNPG_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
  57
  58#define _PAGE_CHG_MASK  (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
  59
  60#define PAGE_NONE       __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
  61#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
  62
  63#define PAGE_SHARED_EXEC        __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
  64#define PAGE_COPY_NOEXEC        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
  65#define PAGE_COPY_EXEC          __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
  66#define PAGE_COPY               PAGE_COPY_NOEXEC
  67#define PAGE_READONLY           __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
  68#define PAGE_READONLY_EXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
  69
  70#ifdef CONFIG_X86_32
  71#define _PAGE_KERNEL_EXEC \
  72        (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
  73#define _PAGE_KERNEL (_PAGE_KERNEL_EXEC | _PAGE_NX)
  74
  75#ifndef __ASSEMBLY__
  76extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
  77#endif  /* __ASSEMBLY__ */
  78#else
  79#define __PAGE_KERNEL_EXEC                                              \
  80        (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
  81#define __PAGE_KERNEL           (__PAGE_KERNEL_EXEC | _PAGE_NX)
  82#endif
  83
  84#define __PAGE_KERNEL_RO                (__PAGE_KERNEL & ~_PAGE_RW)
  85#define __PAGE_KERNEL_RX                (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
  86#define __PAGE_KERNEL_EXEC_NOCACHE      (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
  87#define __PAGE_KERNEL_NOCACHE           (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
  88#define __PAGE_KERNEL_UC_MINUS          (__PAGE_KERNEL | _PAGE_PCD)
  89#define __PAGE_KERNEL_VSYSCALL          (__PAGE_KERNEL_RX | _PAGE_USER)
  90#define __PAGE_KERNEL_VSYSCALL_NOCACHE  (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
  91#define __PAGE_KERNEL_LARGE             (__PAGE_KERNEL | _PAGE_PSE)
  92#define __PAGE_KERNEL_LARGE_EXEC        (__PAGE_KERNEL_EXEC | _PAGE_PSE)
  93
  94#ifdef CONFIG_X86_32
  95# define MAKE_GLOBAL(x)                 __pgprot((x))
  96#else
  97# define MAKE_GLOBAL(x)                 __pgprot((x) | _PAGE_GLOBAL)
  98#endif
  99
 100#define PAGE_KERNEL                     MAKE_GLOBAL(__PAGE_KERNEL)
 101#define PAGE_KERNEL_RO                  MAKE_GLOBAL(__PAGE_KERNEL_RO)
 102#define PAGE_KERNEL_EXEC                MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
 103#define PAGE_KERNEL_RX                  MAKE_GLOBAL(__PAGE_KERNEL_RX)
 104#define PAGE_KERNEL_NOCACHE             MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
 105#define PAGE_KERNEL_UC_MINUS            MAKE_GLOBAL(__PAGE_KERNEL_UC_MINUS)
 106#define PAGE_KERNEL_EXEC_NOCACHE        MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE)
 107#define PAGE_KERNEL_LARGE               MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
 108#define PAGE_KERNEL_LARGE_EXEC          MAKE_GLOBAL(__PAGE_KERNEL_LARGE_EXEC)
 109#define PAGE_KERNEL_VSYSCALL            MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
 110#define PAGE_KERNEL_VSYSCALL_NOCACHE    MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
 111
 112/*         xwr */
 113#define __P000  PAGE_NONE
 114#define __P001  PAGE_READONLY
 115#define __P010  PAGE_COPY
 116#define __P011  PAGE_COPY
 117#define __P100  PAGE_READONLY_EXEC
 118#define __P101  PAGE_READONLY_EXEC
 119#define __P110  PAGE_COPY_EXEC
 120#define __P111  PAGE_COPY_EXEC
 121
 122#define __S000  PAGE_NONE
 123#define __S001  PAGE_READONLY
 124#define __S010  PAGE_SHARED
 125#define __S011  PAGE_SHARED
 126#define __S100  PAGE_READONLY_EXEC
 127#define __S101  PAGE_READONLY_EXEC
 128#define __S110  PAGE_SHARED_EXEC
 129#define __S111  PAGE_SHARED_EXEC
 130
 131#ifndef __ASSEMBLY__
 132
 133/*
 134 * ZERO_PAGE is a global shared page that is always zero: used
 135 * for zero-mapped memory areas etc..
 136 */
 137extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
 138#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 139
 140extern spinlock_t pgd_lock;
 141extern struct list_head pgd_list;
 142
 143/*
 144 * The following only work if pte_present() is true.
 145 * Undefined behaviour if not..
 146 */
 147static inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_DIRTY; }
 148static inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
 149static inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_RW; }
 150static inline int pte_file(pte_t pte)           { return pte_val(pte) & _PAGE_FILE; }
 151static inline int pte_huge(pte_t pte)           { return pte_val(pte) & _PAGE_PSE; }
 152static inline int pte_global(pte_t pte)         { return pte_val(pte) & _PAGE_GLOBAL; }
 153static inline int pte_exec(pte_t pte)           { return !(pte_val(pte) & _PAGE_NX); }
 154
 155static inline int pmd_large(pmd_t pte) {
 156        return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) ==
 157                (_PAGE_PSE|_PAGE_PRESENT);
 158}
 159
 160static inline pte_t pte_mkclean(pte_t pte)      { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); }
 161static inline pte_t pte_mkold(pte_t pte)        { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); }
 162static inline pte_t pte_wrprotect(pte_t pte)    { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW); }
 163static inline pte_t pte_mkexec(pte_t pte)       { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX); }
 164static inline pte_t pte_mkdirty(pte_t pte)      { return __pte(pte_val(pte) | _PAGE_DIRTY); }
 165static inline pte_t pte_mkyoung(pte_t pte)      { return __pte(pte_val(pte) | _PAGE_ACCESSED); }
 166static inline pte_t pte_mkwrite(pte_t pte)      { return __pte(pte_val(pte) | _PAGE_RW); }
 167static inline pte_t pte_mkhuge(pte_t pte)       { return __pte(pte_val(pte) | _PAGE_PSE); }
 168static inline pte_t pte_clrhuge(pte_t pte)      { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_PSE); }
 169static inline pte_t pte_mkglobal(pte_t pte)     { return __pte(pte_val(pte) | _PAGE_GLOBAL); }
 170static inline pte_t pte_clrglobal(pte_t pte)    { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); }
 171
 172extern pteval_t __supported_pte_mask;
 173
 174static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 175{
 176        return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
 177                      pgprot_val(pgprot)) & __supported_pte_mask);
 178}
 179
 180static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
 181{
 182        return __pmd((((phys_addr_t)page_nr << PAGE_SHIFT) |
 183                      pgprot_val(pgprot)) & __supported_pte_mask);
 184}
 185
 186static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 187{
 188        pteval_t val = pte_val(pte);
 189
 190        /*
 191         * Chop off the NX bit (if present), and add the NX portion of
 192         * the newprot (if present):
 193         */
 194        val &= _PAGE_CHG_MASK & ~_PAGE_NX;
 195        val |= pgprot_val(newprot) & __supported_pte_mask;
 196
 197        return __pte(val);
 198}
 199
 200#define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX))
 201
 202#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
 203
 204#ifdef CONFIG_PARAVIRT
 205#include <asm/paravirt.h>
 206#else  /* !CONFIG_PARAVIRT */
 207#define set_pte(ptep, pte)              native_set_pte(ptep, pte)
 208#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte)
 209
 210#define set_pte_present(mm, addr, ptep, pte)                            \
 211        native_set_pte_present(mm, addr, ptep, pte)
 212#define set_pte_atomic(ptep, pte)                                       \
 213        native_set_pte_atomic(ptep, pte)
 214
 215#define set_pmd(pmdp, pmd)              native_set_pmd(pmdp, pmd)
 216
 217#ifndef __PAGETABLE_PUD_FOLDED
 218#define set_pgd(pgdp, pgd)              native_set_pgd(pgdp, pgd)
 219#define pgd_clear(pgd)                  native_pgd_clear(pgd)
 220#endif
 221
 222#ifndef set_pud
 223# define set_pud(pudp, pud)             native_set_pud(pudp, pud)
 224#endif
 225
 226#ifndef __PAGETABLE_PMD_FOLDED
 227#define pud_clear(pud)                  native_pud_clear(pud)
 228#endif
 229
 230#define pte_clear(mm, addr, ptep)       native_pte_clear(mm, addr, ptep)
 231#define pmd_clear(pmd)                  native_pmd_clear(pmd)
 232
 233#define pte_update(mm, addr, ptep)              do { } while (0)
 234#define pte_update_defer(mm, addr, ptep)        do { } while (0)
 235#endif  /* CONFIG_PARAVIRT */
 236
 237#endif  /* __ASSEMBLY__ */
 238
 239#ifdef CONFIG_X86_32
 240# include "pgtable_32.h"
 241#else
 242# include "pgtable_64.h"
 243#endif
 244
 245#ifndef __ASSEMBLY__
 246
 247enum {
 248        PG_LEVEL_NONE,
 249        PG_LEVEL_4K,
 250        PG_LEVEL_2M,
 251        PG_LEVEL_1G,
 252};
 253
 254/*
 255 * Helper function that returns the kernel pagetable entry controlling
 256 * the virtual address 'address'. NULL means no pagetable entry present.
 257 * NOTE: the return type is pte_t but if the pmd is PSE then we return it
 258 * as a pte too.
 259 */
 260extern pte_t *lookup_address(unsigned long address, unsigned int *level);
 261
 262/* local pte updates need not use xchg for locking */
 263static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
 264{
 265        pte_t res = *ptep;
 266
 267        /* Pure native function needs no input for mm, addr */
 268        native_pte_clear(NULL, 0, ptep);
 269        return res;
 270}
 271
 272static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr,
 273                                     pte_t *ptep , pte_t pte)
 274{
 275        native_set_pte(ptep, pte);
 276}
 277
 278#ifndef CONFIG_PARAVIRT
 279/*
 280 * Rules for using pte_update - it must be called after any PTE update which
 281 * has not been done using the set_pte / clear_pte interfaces.  It is used by
 282 * shadow mode hypervisors to resynchronize the shadow page tables.  Kernel PTE
 283 * updates should either be sets, clears, or set_pte_atomic for P->P
 284 * transitions, which means this hook should only be called for user PTEs.
 285 * This hook implies a P->P protection or access change has taken place, which
 286 * requires a subsequent TLB flush.  The notification can optionally be delayed
 287 * until the TLB flush event by using the pte_update_defer form of the
 288 * interface, but care must be taken to assure that the flush happens while
 289 * still holding the same page table lock so that the shadow and primary pages
 290 * do not become out of sync on SMP.
 291 */
 292#define pte_update(mm, addr, ptep)              do { } while (0)
 293#define pte_update_defer(mm, addr, ptep)        do { } while (0)
 294#endif
 295
 296/*
 297 * We only update the dirty/accessed state if we set
 298 * the dirty bit by hand in the kernel, since the hardware
 299 * will do the accessed bit for us, and we don't want to
 300 * race with other CPU's that might be updating the dirty
 301 * bit at the same time.
 302 */
 303#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 304#define ptep_set_access_flags(vma, address, ptep, entry, dirty)         \
 305({                                                                      \
 306        int __changed = !pte_same(*(ptep), entry);                      \
 307        if (__changed && dirty) {                                       \
 308                *ptep = entry;                                          \
 309                pte_update_defer((vma)->vm_mm, (address), (ptep));      \
 310                flush_tlb_page(vma, address);                           \
 311        }                                                               \
 312        __changed;                                                      \
 313})
 314
 315#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 316#define ptep_test_and_clear_young(vma, addr, ptep) ({                   \
 317        int __ret = 0;                                                  \
 318        if (pte_young(*(ptep)))                                         \
 319                __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,          \
 320                                           &(ptep)->pte);               \
 321        if (__ret)                                                      \
 322                pte_update((vma)->vm_mm, addr, ptep);                   \
 323        __ret;                                                          \
 324})
 325
 326#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
 327#define ptep_clear_flush_young(vma, address, ptep)                      \
 328({                                                                      \
 329        int __young;                                                    \
 330        __young = ptep_test_and_clear_young((vma), (address), (ptep));  \
 331        if (__young)                                                    \
 332                flush_tlb_page(vma, address);                           \
 333        __young;                                                        \
 334})
 335
 336#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 337static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 338{
 339        pte_t pte = native_ptep_get_and_clear(ptep);
 340        pte_update(mm, addr, ptep);
 341        return pte;
 342}
 343
 344#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
 345static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
 346{
 347        pte_t pte;
 348        if (full) {
 349                /*
 350                 * Full address destruction in progress; paravirt does not
 351                 * care about updates and native needs no locking
 352                 */
 353                pte = native_local_ptep_get_and_clear(ptep);
 354        } else {
 355                pte = ptep_get_and_clear(mm, addr, ptep);
 356        }
 357        return pte;
 358}
 359
 360#define __HAVE_ARCH_PTEP_SET_WRPROTECT
 361static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 362{
 363        clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte);
 364        pte_update(mm, addr, ptep);
 365}
 366
 367#include <asm-generic/pgtable.h>
 368#endif  /* __ASSEMBLY__ */
 369
 370#endif  /* _ASM_X86_PGTABLE_H */
 371
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.