On Mon, Jun 12, 2023 at 5:14 PM Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx> wrote: > > +++ b/arch/x86/include/asm/pgtable.h > @@ -1189,7 +1189,17 @@ 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) > { > - clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte); > + /* > + * Avoid accidentally creating shadow stack PTEs > + * (Write=0,Dirty=1). Use cmpxchg() to prevent races with > + * the hardware setting Dirty=1. > + */ > + pte_t old_pte, new_pte; > + > + old_pte = READ_ONCE(*ptep); > + do { > + new_pte = pte_wrprotect(old_pte); > + } while (!try_cmpxchg((long *)&ptep->pte, (long *)&old_pte, *(long *)&new_pte)); > } Thanks. Much nicer with this all being done just one way and no need for ifdeffery on config options and runtime static branches. Linus