Skip to content

Commit fbfdec9

Browse files
Peter Zijlstrahansendc
authored andcommitted
x86/mm/pae: Make pmd_t similar to pte_t
Instead of mucking about with at least 2 different ways of fudging it, do the same thing we do for pte_t. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/20221022114424.580310787%40infradead.org
1 parent 93b3037 commit fbfdec9

File tree

4 files changed

+23
-31
lines changed

4 files changed

+23
-31
lines changed

arch/x86/include/asm/pgtable-3level.h

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
8787
ret |= ((pmdval_t)*(tmp + 1)) << 32;
8888
}
8989

90-
return (pmd_t) { ret };
90+
return (pmd_t) { .pmd = ret };
9191
}
9292

9393
static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
@@ -121,12 +121,11 @@ static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr,
121121
ptep->pte_high = 0;
122122
}
123123

124-
static inline void native_pmd_clear(pmd_t *pmd)
124+
static inline void native_pmd_clear(pmd_t *pmdp)
125125
{
126-
u32 *tmp = (u32 *)pmd;
127-
*tmp = 0;
126+
pmdp->pmd_low = 0;
128127
smp_wmb();
129-
*(tmp + 1) = 0;
128+
pmdp->pmd_high = 0;
130129
}
131130

132131
static inline void native_pud_clear(pud_t *pudp)
@@ -162,25 +161,17 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep)
162161
#define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp)
163162
#endif
164163

165-
union split_pmd {
166-
struct {
167-
u32 pmd_low;
168-
u32 pmd_high;
169-
};
170-
pmd_t pmd;
171-
};
172-
173164
#ifdef CONFIG_SMP
174165
static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp)
175166
{
176-
union split_pmd res, *orig = (union split_pmd *)pmdp;
167+
pmd_t res;
177168

178169
/* xchg acts as a barrier before setting of the high bits */
179-
res.pmd_low = xchg(&orig->pmd_low, 0);
180-
res.pmd_high = orig->pmd_high;
181-
orig->pmd_high = 0;
170+
res.pmd_low = xchg(&pmdp->pmd_low, 0);
171+
res.pmd_high = READ_ONCE(pmdp->pmd_high);
172+
WRITE_ONCE(pmdp->pmd_high, 0);
182173

183-
return res.pmd;
174+
return res;
184175
}
185176
#else
186177
#define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)
@@ -199,17 +190,12 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
199190
* anybody.
200191
*/
201192
if (!(pmd_val(pmd) & _PAGE_PRESENT)) {
202-
union split_pmd old, new, *ptr;
203-
204-
ptr = (union split_pmd *)pmdp;
205-
206-
new.pmd = pmd;
207-
208193
/* xchg acts as a barrier before setting of the high bits */
209-
old.pmd_low = xchg(&ptr->pmd_low, new.pmd_low);
210-
old.pmd_high = ptr->pmd_high;
211-
ptr->pmd_high = new.pmd_high;
212-
return old.pmd;
194+
old.pmd_low = xchg(&pmdp->pmd_low, pmd.pmd_low);
195+
old.pmd_high = READ_ONCE(pmdp->pmd_high);
196+
WRITE_ONCE(pmdp->pmd_high, pmd.pmd_high);
197+
198+
return old;
213199
}
214200

215201
do {

arch/x86/include/asm/pgtable-3level_types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ typedef union {
1818
};
1919
pteval_t pte;
2020
} pte_t;
21+
22+
typedef union {
23+
struct {
24+
unsigned long pmd_low, pmd_high;
25+
};
26+
pmdval_t pmd;
27+
} pmd_t;
2128
#endif /* !__ASSEMBLY__ */
2229

2330
#define SHARED_KERNEL_PMD (!static_cpu_has(X86_FEATURE_PTI))

arch/x86/include/asm/pgtable_64_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef unsigned long pgdval_t;
1919
typedef unsigned long pgprotval_t;
2020

2121
typedef struct { pteval_t pte; } pte_t;
22+
typedef struct { pmdval_t pmd; } pmd_t;
2223

2324
#ifdef CONFIG_X86_5LEVEL
2425
extern unsigned int __pgtable_l5_enabled;

arch/x86/include/asm/pgtable_types.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,9 @@ static inline pudval_t native_pud_val(pud_t pud)
361361
#endif
362362

363363
#if CONFIG_PGTABLE_LEVELS > 2
364-
typedef struct { pmdval_t pmd; } pmd_t;
365-
366364
static inline pmd_t native_make_pmd(pmdval_t val)
367365
{
368-
return (pmd_t) { val };
366+
return (pmd_t) { .pmd = val };
369367
}
370368

371369
static inline pmdval_t native_pmd_val(pmd_t pmd)

0 commit comments

Comments
 (0)