__ptep_get() returns a SW PTE value, and __set_pte_nosync() accepts one. When HW PTEs use a distinct hw_pte_t, directly reading or writing *ptep as a SW PTE value no longer satisfies those interfaces. Use __pte_from_hw after READ_ONCE() to obtain a SW PTE value and add __hw_pte before WRITE_ONCE() to form an HW PTE. Define __hw_pte for both the wrapper and alias configurations so the same accessor code works in either case. Signed-off-by: Muhammad Usama Anjum --- arch/arm64/include/asm/pgtable.h | 4 ++-- include/linux/pgtable_types.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 4768ec59de555..67c4a6179e154 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -360,7 +360,7 @@ static inline pte_t pte_clear_uffd(pte_t pte) static inline void __set_pte_nosync(hw_pte_t *ptep, pte_t pte) { - WRITE_ONCE(*ptep, pte); + WRITE_ONCE(*ptep, __hw_pte(pte)); } static inline void __set_pte_complete(pte_t pte) @@ -381,7 +381,7 @@ static inline void __set_pte(hw_pte_t *ptep, pte_t pte) static inline pte_t __ptep_get(hw_pte_t *ptep) { - return READ_ONCE(*ptep); + return __pte_from_hw(READ_ONCE(*ptep)); } extern void __sync_icache_dcache(pte_t pteval); diff --git a/include/linux/pgtable_types.h b/include/linux/pgtable_types.h index ee4eace5c3e1c..b5862a16aa497 100644 --- a/include/linux/pgtable_types.h +++ b/include/linux/pgtable_types.h @@ -9,11 +9,13 @@ #ifdef CONFIG_ARCH_HAS_HW_PTE_T typedef struct __hw_pte_t { pte_t __pte; } hw_pte_t; #define __pte_from_hw(pte) ((pte).__pte) +#define __hw_pte(pte) ((hw_pte_t) { (pte) }) #define hw_pte_val(x) pte_val((x).__pte) #else #define hw_pte_t pte_t #define __pte_from_hw(pte) (pte) +#define __hw_pte(pte) (pte) #define hw_pte_val(x) pte_val(x) #endif -- 2.47.3