• Mark Rutland's avatar
    arm64: mm: use die_kernel_fault() in do_mem_abort() · 6f6cfa58
    Mark Rutland authored
    If we take an unhandled fault from EL1, either:
    
    a) The xFSC handler calls die_kernel_fault() directly. In this case,
       die_kernel_fault() calls:
    
       pr_alert(..., msg, addr);
       mem_abort_decode(esr);
       show_pte(addr);
       die();
       bust_spinlocks(0);
       do_exit(SIGKILL);
    
    b) The xFSC handler returns to do_mem_abort(), indicating failure. In
       this case, do_mem_abort() calls:
    
       pr_alert(..., addr);
       mem_abort_decode(esr);
       show_pte(addr);
       arm64_notify_die() {
         die();
       }
    
    This inconstency is unfortunatem, and in theory in case (b) registered
    notifiers can prevent us from terminating the faulting thread by
    returning NOTIFY_STOP, whereupon we'll end up returning from the fault,
    replaying, and almost certainly get stuck in a livelock spewing errors
    into dmesg. We don't expect notifers to fix things up, since we dump
    state to dmesg before invoking them, so it would be more sensible to
    consistently terminate the thread in this case.
    
    This patch has do_mem_abort() call die_kernel_fault() for unhandled
    faults taken from EL1. Where we would previously have logged a messafe
    of the form:
    
    | Unhandled fault at ${ADDR}
    
    ... we will now log a message of the form:
    
    | Unable to handle kernel ${FAULT_NAME} at virtual address ${ADDR}
    
    ... and we will consistently terminate the thread from which the fault
    was taken.
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Cc: Will Deacon <will@kernel.org>
    Tested-by: default avatarAndrey Konovalov <andreyknvl@gmail.com>
    Acked-by: default avatarWill Deacon <will@kernel.org>
    Link: https://lore.kernel.org/r/20211207183226.834557-2-mark.rutland@arm.comSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    6f6cfa58
fault.c 26.4 KB