On Thu, Sep 29, 2022 at 03:29:09PM -0700, Rick Edgecombe wrote: > diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h > index 2f2963429f48..58c7bf9d7392 100644 > --- a/arch/x86/include/asm/pgtable.h > +++ b/arch/x86/include/asm/pgtable.h > @@ -1287,6 +1287,23 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, > static inline void ptep_set_wrprotect(struct mm_struct *mm, > unsigned long addr, pte_t *ptep) > { > +#ifdef CONFIG_X86_SHADOW_STACK > + /* > + * Avoid accidentally creating shadow stack PTEs > + * (Write=0,Dirty=1). Use cmpxchg() to prevent races with > + * the hardware setting Dirty=1. > + */ > + if (cpu_feature_enabled(X86_FEATURE_SHSTK)) { > + pte_t old_pte, new_pte; > + > + old_pte = READ_ONCE(*ptep); > + do { > + new_pte = pte_wrprotect(old_pte); > + } while (!try_cmpxchg(&ptep->pte, &old_pte.pte, new_pte.pte)); > + > + return; > + } > +#endif > clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte); > } Okay, this addresses my previous question. The need in cmpxchg is unfortunate, but well. -- Kiryl Shutsemau / Kirill A. Shutemov