[RFC PATCH v1 2/2] arm64/mm: use VMA lock for kernel faults on user addresses

Barry Song baohua at kernel.org
Sun Aug 2 01:49:04 PDT 2026


On Sun, Aug 2, 2026 at 3:40 PM Barry Song (Xiaomi) <baohua at kernel.org> wrote:
>
> Use the VMA lock for kernel faults on user addresses. This also
> makes the existing code below meaningful:
>
> /* Quick path to respond to signals */
> if (fault_signal_pending(fault, regs)) {
>         if (!user_mode(regs))
>                 goto no_context;
>         return 0;
> }
>
> Right now, the code above is dead because !user_mode always
> takes the mmap_lock path.
>
> Co-developed-by: Bo Zhang <zhangbo56 at xiaomi.com>
> Signed-off-by: Bo Zhang <zhangbo56 at xiaomi.com>
> Signed-off-by: Barry Song (Xiaomi) <baohua at kernel.org>
> ---
>  arch/arm64/mm/fault.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 85e23388f9bb..241f1ab07ab3 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -607,6 +607,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;
> +       bool uaccess = false;
>         int si_code;
>         int pkey = -1;
>
> @@ -663,6 +664,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
>                 if (!insn_may_access_user(regs->pc, esr))
>                         die_kernel_fault("access to user memory outside uaccess routines",
>                                          addr, esr, regs);
> +               uaccess = true;

https://sashiko.dev/#/patchset/20260802074018.73887-1-baohua%40kernel.org

"Does this conditional bypass translation faults? Because this block is
guarded by:
if (is_ttbr0_addr(addr) && is_el1_permission_fault(addr, esr, regs)) {
it appears uaccess is only set for permission faults like CoW or PAN
violations.
If a kernel uaccess routine accesses an unmapped user address, a translation
fault occurs, making is_el1_permission_fault() evaluate to false.
Would this cause demand paging in uaccess routines to fall back to the slow
lock_mmap path, missing the intended optimization?"

Good catch! I should have only modified a single line. Then
unmapped PTEs would also benefit from the VMA lock:

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 85e23388f9bb..e1b406d667aa 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -674,7 +674,7 @@ static int __kprobes do_page_fault(unsigned long
far, unsigned long esr,

        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);

-       if (!(mm_flags & FAULT_FLAG_USER))
+       if (!(mm_flags & FAULT_FLAG_USER) && !is_ttbr0_addr(addr))
                goto lock_mmap;

        vma = lock_vma_under_rcu(mm, addr);



More information about the linux-arm-kernel mailing list