maybe_mkwrite creates PTEs with WRITE encodings for underlying arch if VM_WRITE is turned on in vma->vm_flags. Shadow stack memory is a write- able memory except it can only be written by certain specific instructions. This patch allows maybe_mkwrite to create shadow stack PTEs if vma is shadow stack VMA. Each arch can define which combination of VMA flags means a shadow stack. Additionally pte_mkshdwstk must be provided by arch specific PTE construction headers to create shadow stack PTEs. (in arch specific pgtable.h). This patch provides dummy/stub pte_mkshdwstk if CONFIG_USER_SHADOW_STACK is not selected. Signed-off-by: Deepak Gupta <debug@xxxxxxxxxxxx> --- include/linux/mm.h | 23 +++++++++++++++++++++-- include/linux/pgtable.h | 4 ++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 8f857163ac89..a7705bc49bfe 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1093,6 +1093,21 @@ static inline unsigned long thp_size(struct page *page) void free_compound_page(struct page *page); #ifdef CONFIG_MMU + +#ifdef CONFIG_USER_SHADOW_STACK +bool arch_is_shadow_stack_vma(struct vm_area_struct *vma); +#endif + +static inline bool +is_shadow_stack_vma(struct vm_area_struct *vma) +{ +#ifdef CONFIG_USER_SHADOW_STACK + return arch_is_shadow_stack_vma(vma); +#else + return false; +#endif +} + /* * Do pte_mkwrite, but only if the vma says VM_WRITE. We do this when * servicing faults for write access. In the normal case, do always want @@ -1101,8 +1116,12 @@ void free_compound_page(struct page *page); */ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma) { - if (likely(vma->vm_flags & VM_WRITE)) - pte = pte_mkwrite(pte); + if (likely(vma->vm_flags & VM_WRITE)) { + if (unlikely(is_shadow_stack_vma(vma))) + pte = pte_mkshdwstk(pte); + else + pte = pte_mkwrite(pte); + } return pte; } diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 1159b25b0542..94b157218c73 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -1736,4 +1736,8 @@ pgprot_t vm_get_page_prot(unsigned long vm_flags) \ } \ EXPORT_SYMBOL(vm_get_page_prot); +#ifndef CONFIG_USER_SHADOW_STACK +#define pte_mkshdwstk(pte) pte +#endif + #endif /* _LINUX_PGTABLE_H */ -- 2.25.1