@@ -106,6 +106,9 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
106106#define KFENCE_AREA_START (VMEMMAP_END + 1)
107107#define KFENCE_AREA_END (KFENCE_AREA_START + KFENCE_AREA_SIZE - 1)
108108
109+ #define ptep_get (ptep ) READ_ONCE(*(ptep))
110+ #define pmdp_get (pmdp ) READ_ONCE(*(pmdp))
111+
109112#define pte_ERROR (e ) \
110113 pr_err("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
111114#ifndef __PAGETABLE_PMD_FOLDED
@@ -147,19 +150,19 @@ static inline int p4d_present(p4d_t p4d)
147150 return p4d_val (p4d ) != (unsigned long )invalid_pud_table ;
148151}
149152
150- static inline void p4d_clear (p4d_t * p4dp )
151- {
152- p4d_val (* p4dp ) = (unsigned long )invalid_pud_table ;
153- }
154-
155153static inline pud_t * p4d_pgtable (p4d_t p4d )
156154{
157155 return (pud_t * )p4d_val (p4d );
158156}
159157
160158static inline void set_p4d (p4d_t * p4d , p4d_t p4dval )
161159{
162- * p4d = p4dval ;
160+ WRITE_ONCE (* p4d , p4dval );
161+ }
162+
163+ static inline void p4d_clear (p4d_t * p4dp )
164+ {
165+ set_p4d (p4dp , __p4d ((unsigned long )invalid_pud_table ));
163166}
164167
165168#define p4d_phys (p4d ) PHYSADDR(p4d_val(p4d))
@@ -193,17 +196,20 @@ static inline int pud_present(pud_t pud)
193196 return pud_val (pud ) != (unsigned long )invalid_pmd_table ;
194197}
195198
196- static inline void pud_clear (pud_t * pudp )
199+ static inline pmd_t * pud_pgtable (pud_t pud )
197200{
198- pud_val ( * pudp ) = (( unsigned long ) invalid_pmd_table );
201+ return ( pmd_t * ) pud_val ( pud );
199202}
200203
201- static inline pmd_t * pud_pgtable (pud_t pud )
204+ static inline void set_pud (pud_t * pud , pud_t pudval )
202205{
203- return ( pmd_t * ) pud_val ( pud );
206+ WRITE_ONCE ( * pud , pudval );
204207}
205208
206- #define set_pud (pudptr , pudval ) do { *(pudptr) = (pudval); } while (0)
209+ static inline void pud_clear (pud_t * pudp )
210+ {
211+ set_pud (pudp , __pud ((unsigned long )invalid_pmd_table ));
212+ }
207213
208214#define pud_phys (pud ) PHYSADDR(pud_val(pud))
209215#define pud_page (pud ) (pfn_to_page(pud_phys(pud) >> PAGE_SHIFT))
@@ -231,12 +237,15 @@ static inline int pmd_present(pmd_t pmd)
231237 return pmd_val (pmd ) != (unsigned long )invalid_pte_table ;
232238}
233239
234- static inline void pmd_clear (pmd_t * pmdp )
240+ static inline void set_pmd (pmd_t * pmd , pmd_t pmdval )
235241{
236- pmd_val ( * pmdp ) = (( unsigned long ) invalid_pte_table );
242+ WRITE_ONCE ( * pmd , pmdval );
237243}
238244
239- #define set_pmd (pmdptr , pmdval ) do { *(pmdptr) = (pmdval); } while (0)
245+ static inline void pmd_clear (pmd_t * pmdp )
246+ {
247+ set_pmd (pmdp , __pmd ((unsigned long )invalid_pte_table ));
248+ }
240249
241250#define pmd_phys (pmd ) PHYSADDR(pmd_val(pmd))
242251
@@ -314,7 +323,8 @@ extern void paging_init(void);
314323
315324static inline void set_pte (pte_t * ptep , pte_t pteval )
316325{
317- * ptep = pteval ;
326+ WRITE_ONCE (* ptep , pteval );
327+
318328 if (pte_val (pteval ) & _PAGE_GLOBAL ) {
319329 pte_t * buddy = ptep_buddy (ptep );
320330 /*
@@ -341,16 +351,16 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
341351 : [buddy ] "+m" (buddy -> pte ), [tmp ] "=&r" (tmp )
342352 : [global ] "r" (page_global ));
343353#else /* !CONFIG_SMP */
344- if (pte_none (* buddy ))
345- pte_val (* buddy ) = pte_val (* buddy ) | _PAGE_GLOBAL ;
354+ if (pte_none (ptep_get ( buddy ) ))
355+ WRITE_ONCE (* buddy , __pte ( pte_val (ptep_get ( buddy )) | _PAGE_GLOBAL )) ;
346356#endif /* CONFIG_SMP */
347357 }
348358}
349359
350360static inline void pte_clear (struct mm_struct * mm , unsigned long addr , pte_t * ptep )
351361{
352362 /* Preserve global status for the pair */
353- if (pte_val (* ptep_buddy (ptep )) & _PAGE_GLOBAL )
363+ if (pte_val (ptep_get ( ptep_buddy (ptep ) )) & _PAGE_GLOBAL )
354364 set_pte (ptep , __pte (_PAGE_GLOBAL ));
355365 else
356366 set_pte (ptep , __pte (0 ));
@@ -603,7 +613,7 @@ static inline pmd_t pmd_mkinvalid(pmd_t pmd)
603613static inline pmd_t pmdp_huge_get_and_clear (struct mm_struct * mm ,
604614 unsigned long address , pmd_t * pmdp )
605615{
606- pmd_t old = * pmdp ;
616+ pmd_t old = pmdp_get ( pmdp ) ;
607617
608618 pmd_clear (pmdp );
609619
0 commit comments