On 03/05/2024 15:01, Joey Gouly wrote: > [...] > > +static bool fault_from_pkey(unsigned long esr, struct vm_area_struct *vma, > + unsigned int mm_flags) > +{ > + unsigned long iss2 = ESR_ELx_ISS2(esr); > + > + if (!arch_pkeys_enabled()) > + return false; > + > + if (iss2 & ESR_ELx_Overlay) > + return true; > + > + return !arch_vma_access_permitted(vma, > + mm_flags & FAULT_FLAG_WRITE, > + mm_flags & FAULT_FLAG_INSTRUCTION, > + mm_flags & FAULT_FLAG_REMOTE); This function is only called from do_page_fault(), so the access cannot be remote. The equivalent x86 function (access_error()) always sets foreign to false. > +} > + > static vm_fault_t __do_page_fault(struct mm_struct *mm, > struct vm_area_struct *vma, unsigned long addr, > unsigned int mm_flags, unsigned long vm_flags, > @@ -529,6 +547,8 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, > unsigned int mm_flags = FAULT_FLAG_DEFAULT; > unsigned long addr = untagged_addr(far); > struct vm_area_struct *vma; > + bool pkey_fault = false; > + int pkey = -1; > > if (kprobe_page_fault(regs, esr)) > return 0; > @@ -590,6 +610,12 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, > vma_end_read(vma); > goto lock_mmap; > } > + > + if (fault_from_pkey(esr, vma, mm_flags)) { > + vma_end_read(vma); > + goto lock_mmap; > + } > + > fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs); > if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED))) > vma_end_read(vma); > @@ -617,6 +643,11 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, > goto done; > } > > + if (fault_from_pkey(esr, vma, mm_flags)) { > + pkey_fault = true; > + pkey = vma_pkey(vma); > + } > + > fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, regs); We don't actually need to call __do_page_fault()/handle_mm_fault() if the fault was caused by POE. It still works since it checks arch_vma_access_permitted() early, but we might as well skip it altogether (like on x86). On 6.10-rcX, we could handle it like a missing vm_flags (goto bad_area). Kevin