diff options
Diffstat (limited to 'include/asm-i386/pgtable-3level.h')
| -rw-r--r-- | include/asm-i386/pgtable-3level.h | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index 7a2318f38303..eb0f1d7e96a1 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h | |||
| @@ -42,20 +42,23 @@ static inline int pte_exec_kernel(pte_t pte) | |||
| 42 | return pte_x(pte); | 42 | return pte_x(pte); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | #ifndef CONFIG_PARAVIRT | ||
| 46 | /* Rules for using set_pte: the pte being assigned *must* be | 45 | /* Rules for using set_pte: the pte being assigned *must* be |
| 47 | * either not present or in a state where the hardware will | 46 | * either not present or in a state where the hardware will |
| 48 | * not attempt to update the pte. In places where this is | 47 | * not attempt to update the pte. In places where this is |
| 49 | * not possible, use pte_get_and_clear to obtain the old pte | 48 | * not possible, use pte_get_and_clear to obtain the old pte |
| 50 | * value and then use set_pte to update it. -ben | 49 | * value and then use set_pte to update it. -ben |
| 51 | */ | 50 | */ |
| 52 | static inline void set_pte(pte_t *ptep, pte_t pte) | 51 | static inline void native_set_pte(pte_t *ptep, pte_t pte) |
| 53 | { | 52 | { |
| 54 | ptep->pte_high = pte.pte_high; | 53 | ptep->pte_high = pte.pte_high; |
| 55 | smp_wmb(); | 54 | smp_wmb(); |
| 56 | ptep->pte_low = pte.pte_low; | 55 | ptep->pte_low = pte.pte_low; |
| 57 | } | 56 | } |
| 58 | #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) | 57 | static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, |
| 58 | pte_t *ptep , pte_t pte) | ||
| 59 | { | ||
| 60 | native_set_pte(ptep, pte); | ||
| 61 | } | ||
| 59 | 62 | ||
| 60 | /* | 63 | /* |
| 61 | * Since this is only called on user PTEs, and the page fault handler | 64 | * Since this is only called on user PTEs, and the page fault handler |
| @@ -63,7 +66,8 @@ static inline void set_pte(pte_t *ptep, pte_t pte) | |||
| 63 | * we are justified in merely clearing the PTE present bit, followed | 66 | * we are justified in merely clearing the PTE present bit, followed |
| 64 | * by a set. The ordering here is important. | 67 | * by a set. The ordering here is important. |
| 65 | */ | 68 | */ |
| 66 | static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) | 69 | static inline void native_set_pte_present(struct mm_struct *mm, unsigned long addr, |
| 70 | pte_t *ptep, pte_t pte) | ||
| 67 | { | 71 | { |
| 68 | ptep->pte_low = 0; | 72 | ptep->pte_low = 0; |
| 69 | smp_wmb(); | 73 | smp_wmb(); |
| @@ -72,32 +76,48 @@ static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte | |||
| 72 | ptep->pte_low = pte.pte_low; | 76 | ptep->pte_low = pte.pte_low; |
| 73 | } | 77 | } |
| 74 | 78 | ||
| 75 | #define set_pte_atomic(pteptr,pteval) \ | 79 | static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) |
| 76 | set_64bit((unsigned long long *)(pteptr),pte_val(pteval)) | 80 | { |
| 77 | #define set_pmd(pmdptr,pmdval) \ | 81 | set_64bit((unsigned long long *)(ptep),native_pte_val(pte)); |
| 78 | set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval)) | 82 | } |
| 79 | #define set_pud(pudptr,pudval) \ | 83 | static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) |
| 80 | (*(pudptr) = (pudval)) | 84 | { |
| 85 | set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd)); | ||
| 86 | } | ||
| 87 | static inline void native_set_pud(pud_t *pudp, pud_t pud) | ||
| 88 | { | ||
| 89 | *pudp = pud; | ||
| 90 | } | ||
| 81 | 91 | ||
| 82 | /* | 92 | /* |
| 83 | * For PTEs and PDEs, we must clear the P-bit first when clearing a page table | 93 | * For PTEs and PDEs, we must clear the P-bit first when clearing a page table |
| 84 | * entry, so clear the bottom half first and enforce ordering with a compiler | 94 | * entry, so clear the bottom half first and enforce ordering with a compiler |
| 85 | * barrier. | 95 | * barrier. |
| 86 | */ | 96 | */ |
| 87 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 97 | static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
| 88 | { | 98 | { |
| 89 | ptep->pte_low = 0; | 99 | ptep->pte_low = 0; |
| 90 | smp_wmb(); | 100 | smp_wmb(); |
| 91 | ptep->pte_high = 0; | 101 | ptep->pte_high = 0; |
| 92 | } | 102 | } |
| 93 | 103 | ||
| 94 | static inline void pmd_clear(pmd_t *pmd) | 104 | static inline void native_pmd_clear(pmd_t *pmd) |
| 95 | { | 105 | { |
| 96 | u32 *tmp = (u32 *)pmd; | 106 | u32 *tmp = (u32 *)pmd; |
| 97 | *tmp = 0; | 107 | *tmp = 0; |
| 98 | smp_wmb(); | 108 | smp_wmb(); |
| 99 | *(tmp + 1) = 0; | 109 | *(tmp + 1) = 0; |
| 100 | } | 110 | } |
| 111 | |||
| 112 | #ifndef CONFIG_PARAVIRT | ||
| 113 | #define set_pte(ptep, pte) native_set_pte(ptep, pte) | ||
| 114 | #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) | ||
| 115 | #define set_pte_present(mm, addr, ptep, pte) native_set_pte_present(mm, addr, ptep, pte) | ||
| 116 | #define set_pte_atomic(ptep, pte) native_set_pte_atomic(ptep, pte) | ||
| 117 | #define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd) | ||
| 118 | #define set_pud(pudp, pud) native_set_pud(pudp, pud) | ||
| 119 | #define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) | ||
| 120 | #define pmd_clear(pmd) native_pmd_clear(pmd) | ||
| 101 | #endif | 121 | #endif |
| 102 | 122 | ||
| 103 | /* | 123 | /* |
| @@ -119,7 +139,8 @@ static inline void pud_clear (pud_t * pud) { } | |||
| 119 | #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ | 139 | #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ |
| 120 | pmd_index(address)) | 140 | pmd_index(address)) |
| 121 | 141 | ||
| 122 | static inline pte_t raw_ptep_get_and_clear(pte_t *ptep) | 142 | #ifdef CONFIG_SMP |
| 143 | static inline pte_t native_ptep_get_and_clear(pte_t *ptep) | ||
| 123 | { | 144 | { |
| 124 | pte_t res; | 145 | pte_t res; |
| 125 | 146 | ||
| @@ -130,6 +151,9 @@ static inline pte_t raw_ptep_get_and_clear(pte_t *ptep) | |||
| 130 | 151 | ||
| 131 | return res; | 152 | return res; |
| 132 | } | 153 | } |
| 154 | #else | ||
| 155 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) | ||
| 156 | #endif | ||
| 133 | 157 | ||
| 134 | #define __HAVE_ARCH_PTE_SAME | 158 | #define __HAVE_ARCH_PTE_SAME |
| 135 | static inline int pte_same(pte_t a, pte_t b) | 159 | static inline int pte_same(pte_t a, pte_t b) |
| @@ -146,28 +170,21 @@ static inline int pte_none(pte_t pte) | |||
| 146 | 170 | ||
| 147 | static inline unsigned long pte_pfn(pte_t pte) | 171 | static inline unsigned long pte_pfn(pte_t pte) |
| 148 | { | 172 | { |
| 149 | return (pte.pte_low >> PAGE_SHIFT) | | 173 | return pte_val(pte) >> PAGE_SHIFT; |
| 150 | (pte.pte_high << (32 - PAGE_SHIFT)); | ||
| 151 | } | 174 | } |
| 152 | 175 | ||
| 153 | extern unsigned long long __supported_pte_mask; | 176 | extern unsigned long long __supported_pte_mask; |
| 154 | 177 | ||
| 155 | static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) | 178 | static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) |
| 156 | { | 179 | { |
| 157 | pte_t pte; | 180 | return __pte((((unsigned long long)page_nr << PAGE_SHIFT) | |
| 158 | 181 | pgprot_val(pgprot)) & __supported_pte_mask); | |
| 159 | pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \ | ||
| 160 | (pgprot_val(pgprot) >> 32); | ||
| 161 | pte.pte_high &= (__supported_pte_mask >> 32); | ||
| 162 | pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \ | ||
| 163 | __supported_pte_mask; | ||
| 164 | return pte; | ||
| 165 | } | 182 | } |
| 166 | 183 | ||
| 167 | static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) | 184 | static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) |
| 168 | { | 185 | { |
| 169 | return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \ | 186 | return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | |
| 170 | pgprot_val(pgprot)) & __supported_pte_mask); | 187 | pgprot_val(pgprot)) & __supported_pte_mask); |
| 171 | } | 188 | } |
| 172 | 189 | ||
| 173 | /* | 190 | /* |
| @@ -187,6 +204,4 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) | |||
| 187 | 204 | ||
| 188 | #define __pmd_free_tlb(tlb, x) do { } while (0) | 205 | #define __pmd_free_tlb(tlb, x) do { } while (0) |
| 189 | 206 | ||
| 190 | #define vmalloc_sync_all() ((void)0) | ||
| 191 | |||
| 192 | #endif /* _I386_PGTABLE_3LEVEL_H */ | 207 | #endif /* _I386_PGTABLE_3LEVEL_H */ |
