• Mark Rutland's avatar
    arm64: insn: consistently handle exit text · ca2ef4ff
    Mark Rutland authored
    A kernel built with KASAN && FTRACE_WITH_REGS && !MODULES, produces a
    boot-time splat in the bowels of ftrace:
    
    | [    0.000000] ftrace: allocating 32281 entries in 127 pages
    | [    0.000000] ------------[ cut here ]------------
    | [    0.000000] WARNING: CPU: 0 PID: 0 at kernel/trace/ftrace.c:2019 ftrace_bug+0x27c/0x328
    | [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.4.0-rc3-00008-g7f08ae53 #13
    | [    0.000000] Hardware name: linux,dummy-virt (DT)
    | [    0.000000] pstate: 60000085 (nZCv daIf -PAN -UAO)
    | [    0.000000] pc : ftrace_bug+0x27c/0x328
    | [    0.000000] lr : ftrace_init+0x640/0x6cc
    | [    0.000000] sp : ffffa000120e7e00
    | [    0.000000] x29: ffffa000120e7e00 x28: ffff00006ac01b10
    | [    0.000000] x27: ffff00006ac898c0 x26: dfffa00000000000
    | [    0.000000] x25: ffffa000120ef290 x24: ffffa0001216df40
    | [    0.000000] x23: 000000000000018d x22: ffffa0001244c700
    | [    0.000000] x21: ffffa00011bf393c x20: ffff00006ac898c0
    | [    0.000000] x19: 00000000ffffffff x18: 0000000000001584
    | [    0.000000] x17: 0000000000001540 x16: 0000000000000007
    | [    0.000000] x15: 0000000000000000 x14: ffffa00010432770
    | [    0.000000] x13: ffff940002483519 x12: 1ffff40002483518
    | [    0.000000] x11: 1ffff40002483518 x10: ffff940002483518
    | [    0.000000] x9 : dfffa00000000000 x8 : 0000000000000001
    | [    0.000000] x7 : ffff940002483519 x6 : ffffa0001241a8c0
    | [    0.000000] x5 : ffff940002483519 x4 : ffff940002483519
    | [    0.000000] x3 : ffffa00011780870 x2 : 0000000000000001
    | [    0.000000] x1 : 1fffe0000d591318 x0 : 0000000000000000
    | [    0.000000] Call trace:
    | [    0.000000]  ftrace_bug+0x27c/0x328
    | [    0.000000]  ftrace_init+0x640/0x6cc
    | [    0.000000]  start_kernel+0x27c/0x654
    | [    0.000000] random: get_random_bytes called from print_oops_end_marker+0x30/0x60 with crng_init=0
    | [    0.000000] ---[ end trace 0000000000000000 ]---
    | [    0.000000] ftrace faulted on writing
    | [    0.000000] [<ffffa00011bf393c>] _GLOBAL__sub_D_65535_0___tracepoint_initcall_level+0x4/0x28
    | [    0.000000] Initializing ftrace call sites
    | [    0.000000] ftrace record flags: 0
    | [    0.000000]  (0)
    | [    0.000000]  expected tramp: ffffa000100b3344
    
    This is due to an unfortunate combination of several factors.
    
    Building with KASAN results in the compiler generating anonymous
    functions to register/unregister global variables against the shadow
    memory. These functions are placed in .text.startup/.text.exit, and
    given mangled names like _GLOBAL__sub_{I,D}_65535_0_$OTHER_SYMBOL. The
    kernel linker script places these in .init.text and .exit.text
    respectively, which are both discarded at runtime as part of initmem.
    
    Building with FTRACE_WITH_REGS uses -fpatchable-function-entry=2, which
    also instruments KASAN's anonymous functions. When these are discarded
    with the rest of initmem, ftrace removes dangling references to these
    call sites.
    
    Building without MODULES implicitly disables STRICT_MODULE_RWX, and
    causes arm64's patch_map() function to treat any !core_kernel_text()
    symbol as something that can be modified in-place. As core_kernel_text()
    is only true for .text and .init.text, with the latter depending on
    system_state < SYSTEM_RUNNING, we'll treat .exit.text as something that
    can be patched in-place. However, .exit.text is mapped read-only.
    
    Hence in this configuration the ftrace init code blows up while trying
    to patch one of the functions generated by KASAN.
    
    We could try to filter out the call sites in .exit.text rather than
    initializing them, but this would be inconsistent with how we handle
    .init.text, and requires hooking into core bits of ftrace. The behaviour
    of patch_map() is also inconsistent today, so instead let's clean that
    up and have it consistently handle .exit.text.
    
    This patch teaches patch_map() to handle .exit.text at init time,
    preventing the boot-time splat above. The flow of patch_map() is
    reworked to make the logic clearer and minimize redundant
    conditionality.
    
    Fixes: 3b23e499 ("arm64: implement ftrace with regs")
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Cc: Amit Daniel Kachhap <amit.kachhap@arm.com>
    Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
    Cc: Torsten Duwe <duwe@suse.de>
    Cc: Will Deacon <will@kernel.org>
    Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    ca2ef4ff
sections.h 894 Bytes