arm64: mm: drop VM_FAULT_BADMAP/VM_FAULT_BADACCESS
authorKefeng Wang <wangkefeng.wang@huawei.com>
Thu, 11 Apr 2024 13:09:24 +0000 (21:09 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 6 May 2024 00:53:32 +0000 (17:53 -0700)
Patch series "mm: remove arch's private VM_FAULT_BADMAP/BADACCESS", v2.

Directly set SEGV_MAPRR or SEGV_ACCERR for arm/arm64 to remove the last
two arch's private vm_fault reasons.

This patch (of 2):

If bad map or access, directly set si_code to SEGV_MAPRR or SEGV_ACCERR,
also set fault to 0 and goto error handling, which make us to drop the
arch's special vm fault reason.

Link: https://lkml.kernel.org/r/20240411130925.73281-1-wangkefeng.wang@huawei.com
Link: https://lkml.kernel.org/r/20240411130925.73281-2-wangkefeng.wang@huawei.com
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Aishwarya TCV <aishwarya.tcv@arm.com>
Cc: Cristian Marussi <cristian.marussi@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
arch/arm64/mm/fault.c

index 405f9aa831bd20a81676c7676ee506db83a36545..451ba7cbd5adb008b24e3a57c2e2403c9dd33c0b 100644 (file)
@@ -500,9 +500,6 @@ static bool is_write_abort(unsigned long esr)
        return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM);
 }
 
-#define VM_FAULT_BADMAP                ((__force vm_fault_t)0x010000)
-#define VM_FAULT_BADACCESS     ((__force vm_fault_t)0x020000)
-
 static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
                                   struct pt_regs *regs)
 {
@@ -513,6 +510,7 @@ 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;
+       int si_code;
 
        if (kprobe_page_fault(regs, esr))
                return 0;
@@ -572,9 +570,10 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
 
        if (!(vma->vm_flags & vm_flags)) {
                vma_end_read(vma);
-               fault = VM_FAULT_BADACCESS;
+               fault = 0;
+               si_code = SEGV_ACCERR;
                count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
-               goto done;
+               goto bad_area;
        }
        fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs);
        if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
@@ -599,15 +598,19 @@ lock_mmap:
 retry:
        vma = lock_mm_and_find_vma(mm, addr, regs);
        if (unlikely(!vma)) {
-               fault = VM_FAULT_BADMAP;
-               goto done;
+               fault = 0;
+               si_code = SEGV_MAPERR;
+               goto bad_area;
        }
 
-       if (!(vma->vm_flags & vm_flags))
-               fault = VM_FAULT_BADACCESS;
-       else
-               fault = handle_mm_fault(vma, addr, mm_flags, regs);
+       if (!(vma->vm_flags & vm_flags)) {
+               mmap_read_unlock(mm);
+               fault = 0;
+               si_code = SEGV_ACCERR;
+               goto bad_area;
+       }
 
+       fault = handle_mm_fault(vma, addr, mm_flags, regs);
        /* Quick path to respond to signals */
        if (fault_signal_pending(fault, regs)) {
                if (!user_mode(regs))
@@ -626,13 +629,12 @@ retry:
        mmap_read_unlock(mm);
 
 done:
-       /*
-        * Handle the "normal" (no error) case first.
-        */
-       if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP |
-                             VM_FAULT_BADACCESS))))
+       /* Handle the "normal" (no error) case first. */
+       if (likely(!(fault & VM_FAULT_ERROR)))
                return 0;
 
+       si_code = SEGV_MAPERR;
+bad_area:
        /*
         * If we are in kernel mode at this point, we have no context to
         * handle this fault with.
@@ -667,13 +669,8 @@ done:
 
                arm64_force_sig_mceerr(BUS_MCEERR_AR, far, lsb, inf->name);
        } else {
-               /*
-                * Something tried to access memory that isn't in our memory
-                * map.
-                */
-               arm64_force_sig_fault(SIGSEGV,
-                                     fault == VM_FAULT_BADACCESS ? SEGV_ACCERR : SEGV_MAPERR,
-                                     far, inf->name);
+               /* Something tried to access memory that out of memory map */
+               arm64_force_sig_fault(SIGSEGV, si_code, far, inf->name);
        }
 
        return 0;