• Naveen N. Rao's avatar
    powerpc/module_64: Use special stub for _mcount() with -mprofile-kernel · bd55e792
    Naveen N. Rao authored
    Since commit c55d7b5e ("powerpc: Remove STRICT_KERNEL_RWX
    incompatibility with RELOCATABLE"), powerpc kernels with
    -mprofile-kernel can crash in certain scenarios with a trace like below:
    
        BUG: Unable to handle kernel instruction fetch (NULL pointer?)
        Faulting instruction address: 0x00000000
        Oops: Kernel access of bad area, sig: 11 [#1]
        LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=256 DEBUG_PAGEALLOC NUMA PowerNV
        <snip>
        NIP [0000000000000000] 0x0
        LR [c0080000102c0048] ext4_iomap_end+0x8/0x30 [ext4]
        Call Trace:
         iomap_apply+0x20c/0x920 (unreliable)
         iomap_bmap+0xfc/0x160
         ext4_bmap+0xa4/0x180 [ext4]
         bmap+0x4c/0x80
         jbd2_journal_init_inode+0x44/0x1a0 [jbd2]
         ext4_load_journal+0x440/0x860 [ext4]
         ext4_fill_super+0x342c/0x3ab0 [ext4]
         mount_bdev+0x25c/0x290
         ext4_mount+0x28/0x50 [ext4]
         legacy_get_tree+0x4c/0xb0
         vfs_get_tree+0x4c/0x130
         do_mount+0xa18/0xc50
         sys_mount+0x158/0x180
         system_call+0x5c/0x68
    
    The NIP points to NULL, or a random location (data even), while the LR
    always points to the LEP of a function (with an offset of 8), indicating
    that something went wrong with ftrace. However, ftrace is not
    necessarily active when such crashes occur.
    
    The kernel OOPS sometimes follows a warning from ftrace indicating that
    some module functions could not be patched with a nop. Other times, if a
    module is loaded early during boot, instruction patching can fail due to
    a separate bug, but the error is not reported due to missing error
    reporting.
    
    In all the above cases when instruction patching fails, ftrace will be
    disabled but certain kernel module functions will be left with default
    calls to _mcount(). This is not a problem with ELFv1. However, with
    -mprofile-kernel, the default stub is problematic since it depends on a
    valid module TOC in r2. If the kernel (or a different module) calls into
    a function that does not use the TOC, the function won't have a prologue
    to setup the module TOC. When that function calls into _mcount(), we
    will end up in the relocation stub that will use the previous TOC, and
    end up trying to jump into a random location. From the above trace:
    
    	iomap_apply+0x20c/0x920 [kernel TOC]
    			|
    			V
    	ext4_iomap_end+0x8/0x30 [no GEP == kernel TOC]
    			|
    			V
    		_mcount() stub
    	[uses kernel TOC -> random entry]
    
    To address this, let's change over to using the special stub that is
    used for ftrace_[regs_]caller() for _mcount(). This ensures that we are
    not dependent on a valid module TOC in r2 for default _mcount()
    handling.
    Reported-by: default avatarQian Cai <cai@lca.pw>
    Signed-off-by: default avatarNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
    Tested-by: default avatarQian Cai <cai@lca.pw>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/8affd4298d22099bbd82544fab8185700a6222b1.1587488954.git.naveen.n.rao@linux.vnet.ibm.com
    bd55e792
module_64.c 21.6 KB