0001
0002 #ifndef _ASM_X86_PGTABLE_64_H
0003 #define _ASM_X86_PGTABLE_64_H
0004
0005 #include <linux/const.h>
0006 #include <asm/pgtable_64_types.h>
0007
0008 #ifndef __ASSEMBLY__
0009
0010
0011
0012
0013
0014 #include <asm/processor.h>
0015 #include <linux/bitops.h>
0016 #include <linux/threads.h>
0017 #include <asm/fixmap.h>
0018
0019 extern p4d_t level4_kernel_pgt[512];
0020 extern p4d_t level4_ident_pgt[512];
0021 extern pud_t level3_kernel_pgt[512];
0022 extern pud_t level3_ident_pgt[512];
0023 extern pmd_t level2_kernel_pgt[512];
0024 extern pmd_t level2_fixmap_pgt[512];
0025 extern pmd_t level2_ident_pgt[512];
0026 extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM];
0027 extern pgd_t init_top_pgt[];
0028
0029 #define swapper_pg_dir init_top_pgt
0030
0031 extern void paging_init(void);
0032 static inline void sync_initial_page_table(void) { }
0033
0034 #define pte_ERROR(e) \
0035 pr_err("%s:%d: bad pte %p(%016lx)\n", \
0036 __FILE__, __LINE__, &(e), pte_val(e))
0037 #define pmd_ERROR(e) \
0038 pr_err("%s:%d: bad pmd %p(%016lx)\n", \
0039 __FILE__, __LINE__, &(e), pmd_val(e))
0040 #define pud_ERROR(e) \
0041 pr_err("%s:%d: bad pud %p(%016lx)\n", \
0042 __FILE__, __LINE__, &(e), pud_val(e))
0043
0044 #if CONFIG_PGTABLE_LEVELS >= 5
0045 #define p4d_ERROR(e) \
0046 pr_err("%s:%d: bad p4d %p(%016lx)\n", \
0047 __FILE__, __LINE__, &(e), p4d_val(e))
0048 #endif
0049
0050 #define pgd_ERROR(e) \
0051 pr_err("%s:%d: bad pgd %p(%016lx)\n", \
0052 __FILE__, __LINE__, &(e), pgd_val(e))
0053
0054 struct mm_struct;
0055
0056 #define mm_p4d_folded mm_p4d_folded
0057 static inline bool mm_p4d_folded(struct mm_struct *mm)
0058 {
0059 return !pgtable_l5_enabled();
0060 }
0061
0062 void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte);
0063 void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte);
0064
0065 static inline void native_set_pte(pte_t *ptep, pte_t pte)
0066 {
0067 WRITE_ONCE(*ptep, pte);
0068 }
0069
0070 static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr,
0071 pte_t *ptep)
0072 {
0073 native_set_pte(ptep, native_make_pte(0));
0074 }
0075
0076 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
0077 {
0078 native_set_pte(ptep, pte);
0079 }
0080
0081 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
0082 {
0083 WRITE_ONCE(*pmdp, pmd);
0084 }
0085
0086 static inline void native_pmd_clear(pmd_t *pmd)
0087 {
0088 native_set_pmd(pmd, native_make_pmd(0));
0089 }
0090
0091 static inline pte_t native_ptep_get_and_clear(pte_t *xp)
0092 {
0093 #ifdef CONFIG_SMP
0094 return native_make_pte(xchg(&xp->pte, 0));
0095 #else
0096
0097
0098 pte_t ret = *xp;
0099 native_pte_clear(NULL, 0, xp);
0100 return ret;
0101 #endif
0102 }
0103
0104 static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
0105 {
0106 #ifdef CONFIG_SMP
0107 return native_make_pmd(xchg(&xp->pmd, 0));
0108 #else
0109
0110
0111 pmd_t ret = *xp;
0112 native_pmd_clear(xp);
0113 return ret;
0114 #endif
0115 }
0116
0117 static inline void native_set_pud(pud_t *pudp, pud_t pud)
0118 {
0119 WRITE_ONCE(*pudp, pud);
0120 }
0121
0122 static inline void native_pud_clear(pud_t *pud)
0123 {
0124 native_set_pud(pud, native_make_pud(0));
0125 }
0126
0127 static inline pud_t native_pudp_get_and_clear(pud_t *xp)
0128 {
0129 #ifdef CONFIG_SMP
0130 return native_make_pud(xchg(&xp->pud, 0));
0131 #else
0132
0133
0134
0135 pud_t ret = *xp;
0136
0137 native_pud_clear(xp);
0138 return ret;
0139 #endif
0140 }
0141
0142 static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d)
0143 {
0144 pgd_t pgd;
0145
0146 if (pgtable_l5_enabled() || !IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) {
0147 WRITE_ONCE(*p4dp, p4d);
0148 return;
0149 }
0150
0151 pgd = native_make_pgd(native_p4d_val(p4d));
0152 pgd = pti_set_user_pgtbl((pgd_t *)p4dp, pgd);
0153 WRITE_ONCE(*p4dp, native_make_p4d(native_pgd_val(pgd)));
0154 }
0155
0156 static inline void native_p4d_clear(p4d_t *p4d)
0157 {
0158 native_set_p4d(p4d, native_make_p4d(0));
0159 }
0160
0161 static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
0162 {
0163 WRITE_ONCE(*pgdp, pti_set_user_pgtbl(pgdp, pgd));
0164 }
0165
0166 static inline void native_pgd_clear(pgd_t *pgd)
0167 {
0168 native_set_pgd(pgd, native_make_pgd(0));
0169 }
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 #define SWP_TYPE_BITS 5
0215
0216 #define SWP_OFFSET_FIRST_BIT (_PAGE_BIT_PROTNONE + 1)
0217
0218
0219 #define SWP_OFFSET_SHIFT (SWP_OFFSET_FIRST_BIT+SWP_TYPE_BITS)
0220
0221 #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
0222
0223
0224 #define __swp_type(x) ((x).val >> (64 - SWP_TYPE_BITS))
0225
0226
0227 #define __swp_offset(x) (~(x).val << SWP_TYPE_BITS >> SWP_OFFSET_SHIFT)
0228
0229
0230
0231
0232
0233
0234 #define __swp_entry(type, offset) ((swp_entry_t) { \
0235 (~(unsigned long)(offset) << SWP_OFFSET_SHIFT >> SWP_TYPE_BITS) \
0236 | ((unsigned long)(type) << (64-SWP_TYPE_BITS)) })
0237
0238 #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })
0239 #define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val((pmd)) })
0240 #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
0241 #define __swp_entry_to_pmd(x) ((pmd_t) { .pmd = (x).val })
0242
0243 extern int kern_addr_valid(unsigned long addr);
0244 extern void cleanup_highmap(void);
0245
0246 #define HAVE_ARCH_UNMAPPED_AREA
0247 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
0248
0249 #define PAGE_AGP PAGE_KERNEL_NOCACHE
0250 #define HAVE_PAGE_AGP 1
0251
0252
0253 #define kc_vaddr_to_offset(v) ((v) & __VIRTUAL_MASK)
0254 #define kc_offset_to_vaddr(o) ((o) | ~__VIRTUAL_MASK)
0255
0256 #define __HAVE_ARCH_PTE_SAME
0257
0258 #define vmemmap ((struct page *)VMEMMAP_START)
0259
0260 extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
0261 extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
0262
0263 #define gup_fast_permitted gup_fast_permitted
0264 static inline bool gup_fast_permitted(unsigned long start, unsigned long end)
0265 {
0266 if (end >> __VIRTUAL_MASK_SHIFT)
0267 return false;
0268 return true;
0269 }
0270
0271 #include <asm/pgtable-invert.h>
0272
0273 #endif
0274 #endif