Re: [PATCH v4 15/29] arm64: handle PKEY/POE faults
flat view
From: Kevin Brodsky <hidden>
Date: 2024-07-09 13:03:53
Also in:
kvmarm, linux-arm-kernel, linux-fsdevel, linux-mm
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.
quoted hunk ↗ jump to hunk
+} + 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