| 1 |
|
| 2 | #ifndef _ASM_X86_PGTABLE_2LEVEL_H
|
| 3 | #define _ASM_X86_PGTABLE_2LEVEL_H
|
| 4 |
|
| 5 | #define pte_ERROR(e) \
|
| 6 | pr_err("%s:%d: bad pte %08lx\n", __FILE__, __LINE__, (e).pte_low)
|
| 7 | #define pgd_ERROR(e) \
|
| 8 | pr_err("%s:%d: bad pgd %08lx\n", __FILE__, __LINE__, pgd_val(e))
|
| 9 |
|
| 10 | |
| 11 | * Certain architectures need to do special things when PTEs
|
| 12 | * within a page table are directly modified. Thus, the following
|
| 13 | * hook is made available.
|
| 14 |
|
| 15 | static inline void native_set_pte(pte_t *ptep , pte_t pte)
|
| 16 | {
|
| 17 | *ptep = pte;
|
| 18 | }
|
| 19 |
|
| 20 | static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
|
| 21 | {
|
| 22 | *pmdp = pmd;
|
| 23 | }
|
| 24 |
|
| 25 | static inline void native_set_pud(pud_t *pudp, pud_t pud)
|
| 26 | {
|
| 27 | }
|
| 28 |
|
| 29 | static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
|
| 30 | {
|
| 31 | native_set_pte(ptep, pte);
|
| 32 | }
|
| 33 |
|
| 34 | static inline void native_pmd_clear(pmd_t *pmdp)
|
| 35 | {
|
| 36 | native_set_pmd(pmdp, __pmd(0));
|
| 37 | }
|
| 38 |
|
| 39 | static inline void native_pud_clear(pud_t *pudp)
|
| 40 | {
|
| 41 | }
|
| 42 |
|
| 43 | static inline void native_pte_clear(struct mm_struct *mm,
|
| 44 | unsigned long addr, pte_t *xp)
|
| 45 | {
|
| 46 | *xp = native_make_pte(0);
|
| 47 | }
|
| 48 |
|
| 49 | #ifdef CONFIG_SMP
|
| 50 | static inline pte_t native_ptep_get_and_clear(pte_t *xp)
|
| 51 | {
|
| 52 | return __pte(xchg(&xp->pte_low, 0));
|
| 53 | }
|
| 54 | #else
|
| 55 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp)
|
| 56 | #endif
|
| 57 |
|
| 58 | #ifdef CONFIG_SMP
|
| 59 | static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
|
| 60 | {
|
| 61 | return __pmd(xchg((pmdval_t *)xp, 0));
|
| 62 | }
|
| 63 | #else
|
| 64 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)
|
| 65 | #endif
|
| 66 |
|
| 67 | #ifdef CONFIG_SMP
|
| 68 | static inline pud_t native_pudp_get_and_clear(pud_t *xp)
|
| 69 | {
|
| 70 | return __pud(xchg((pudval_t *)xp, 0));
|
| 71 | }
|
| 72 | #else
|
| 73 | #define native_pudp_get_and_clear(xp) native_local_pudp_get_and_clear(xp)
|
| 74 | #endif
|
| 75 |
|
| 76 |
|
| 77 | static inline unsigned long pte_bitop(unsigned long value, unsigned int rightshift,
|
| 78 | unsigned long mask, unsigned int leftshift)
|
| 79 | {
|
| 80 | return ((value >> rightshift) & mask) << leftshift;
|
| 81 | }
|
| 82 |
|
| 83 | |
| 84 | * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
|
| 85 | * are !pte_none() && !pte_present().
|
| 86 | *
|
| 87 | * Format of swap PTEs:
|
| 88 | *
|
| 89 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
| 90 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
| 91 | * <----------------- offset ------------------> 0 E <- type --> 0
|
| 92 | *
|
| 93 | * E is the exclusive marker that is not stored in swap entries.
|
| 94 |
|
| 95 | #define SWP_TYPE_BITS 5
|
| 96 | #define _SWP_TYPE_MASK ((1U << SWP_TYPE_BITS) - 1)
|
| 97 | #define _SWP_TYPE_SHIFT (_PAGE_BIT_PRESENT + 1)
|
| 98 | #define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1)
|
| 99 |
|
| 100 | #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > 5)
|
| 101 |
|
| 102 | #define __swp_type(x) (((x).val >> _SWP_TYPE_SHIFT) \
|
| 103 | & _SWP_TYPE_MASK)
|
| 104 | #define __swp_offset(x) ((x).val >> SWP_OFFSET_SHIFT)
|
| 105 | #define __swp_entry(type, offset) ((swp_entry_t) { \
|
| 106 | (((type) & _SWP_TYPE_MASK) << _SWP_TYPE_SHIFT) \
|
| 107 | | ((offset) << SWP_OFFSET_SHIFT) })
|
| 108 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low })
|
| 109 | #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
|
| 110 |
|
| 111 |
|
| 112 | #define _PAGE_SWP_EXCLUSIVE _PAGE_PSE
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 | static inline u64 protnone_mask(u64 val)
|
| 117 | {
|
| 118 | return 0;
|
| 119 | }
|
| 120 |
|
| 121 | static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask)
|
| 122 | {
|
| 123 | return val;
|
| 124 | }
|
| 125 |
|
| 126 | static inline bool __pte_needs_invert(u64 val)
|
| 127 | {
|
| 128 | return false;
|
| 129 | }
|
| 130 |
|
| 131 | #endif
|