On Wed, 2023-01-25 at 10:43 -0800, Rick Edgecombe wrote: > Thanks for your comments and ideas here, I'll give the: > pte_t pte_mkwrite(struct vm_area_struct *vma, pte_t pte) > ...solution a try. Well, it turns out there are some pte_mkwrite() callers in other arch's that operate on kernel memory and don't have a VMA. So it needed a new function that can be overridden in arch code. I ended up with x86 versions of these, like this: pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma) { if (!(vma->vm_flags & VM_WRITE)) return pte; if (vma->vm_flags & VM_SHADOW_STACK) return pte_mkwrite_shstk(pte); return pte_mkwrite(pte); } pte_t pte_mkwrite_vma(pte_t pte, struct vm_area_struct *vma) { if (vma->vm_flags & VM_SHADOW_STACK) return pte_mkwrite_shstk(pte); return pte_mkwrite(pte); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) { if (!(vma->vm_flags & VM_WRITE)) return pmd; if (vma->vm_flags & VM_SHADOW_STACK) return pmd_mkwrite_shstk(pmd); return pmd_mkwrite(pmd); } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ All the other pte_mkdirty()s, etc remain the same. Previously, there was a suggestion to not override the maybe_mkwrite()'s and put the logic in core MM by having a generic version of pte_mkwrite_shstk() that does nothing. But given what we are trying to do with pte_mkwrite_vma() it seemed better to hide all the shadow stack PTE changes in arch code again. After the changes, the only shadow stack specific bits in core mm are the bit in GUP to require FOLL_FORCE, the memory accounting, and these warnings: https://lore.kernel.org/lkml/20230119212317.8324-26-rick.p.edgecombe@xxxxxxxxx/