lkml.org 
[lkml]   [2019]   [Sep]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 39/50] powerpc/imc: Dont create debugfs files for cpu-less nodes
    Date
    From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>

    [ Upstream commit 41ba17f20ea835c489e77bd54e2da73184e22060 ]

    Commit <684d984038aa> ('powerpc/powernv: Add debugfs interface for
    imc-mode and imc') added debugfs interface for the nest imc pmu
    devices to support changing of different ucode modes. Primarily adding
    this capability for debug. But when doing so, the code did not
    consider the case of cpu-less nodes. So when reading the _cmd_ or
    _mode_ file of a cpu-less node will create this crash.

    Faulting instruction address: 0xc0000000000d0d58
    Oops: Kernel access of bad area, sig: 11 [#1]
    ...
    CPU: 67 PID: 5301 Comm: cat Not tainted 5.2.0-rc6-next-20190627+ #19
    NIP: c0000000000d0d58 LR: c00000000049aa18 CTR:c0000000000d0d50
    REGS: c00020194548f9e0 TRAP: 0300 Not tainted (5.2.0-rc6-next-20190627+)
    MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR:28022822 XER: 00000000
    CFAR: c00000000049aa14 DAR: 000000000003fc08 DSISR:40000000 IRQMASK: 0
    ...
    NIP imc_mem_get+0x8/0x20
    LR simple_attr_read+0x118/0x170
    Call Trace:
    simple_attr_read+0x70/0x170 (unreliable)
    debugfs_attr_read+0x6c/0xb0
    __vfs_read+0x3c/0x70
    vfs_read+0xbc/0x1a0
    ksys_read+0x7c/0x140
    system_call+0x5c/0x70

    Patch fixes the issue with a more robust check for vbase to NULL.

    Before patch, ls output for the debugfs imc directory

    # ls /sys/kernel/debug/powerpc/imc/
    imc_cmd_0 imc_cmd_251 imc_cmd_253 imc_cmd_255 imc_mode_0 imc_mode_251 imc_mode_253 imc_mode_255
    imc_cmd_250 imc_cmd_252 imc_cmd_254 imc_cmd_8 imc_mode_250 imc_mode_252 imc_mode_254 imc_mode_8

    After patch, ls output for the debugfs imc directory

    # ls /sys/kernel/debug/powerpc/imc/
    imc_cmd_0 imc_cmd_8 imc_mode_0 imc_mode_8

    Actual bug here is that, we have two loops with potentially different
    loop counts. That is, in imc_get_mem_addr_nest(), loop count is
    obtained from the dt entries. But in case of export_imc_mode_and_cmd(),
    loop was based on for_each_nid() count. Patch fixes the loop count in
    latter based on the struct mem_info. Ideally it would be better to
    have array size in struct imc_pmu.

    Fixes: 684d984038aa ('powerpc/powernv: Add debugfs interface for imc-mode and imc')
    Reported-by: Qian Cai <cai@lca.pw>
    Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20190827101635.6942-1-maddy@linux.vnet.ibm.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/powerpc/platforms/powernv/opal-imc.c | 12 ++++++------
    1 file changed, 6 insertions(+), 6 deletions(-)

    diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c
    index 828f6656f8f74..649fb268f4461 100644
    --- a/arch/powerpc/platforms/powernv/opal-imc.c
    +++ b/arch/powerpc/platforms/powernv/opal-imc.c
    @@ -57,9 +57,9 @@ static void export_imc_mode_and_cmd(struct device_node *node,
    struct imc_pmu *pmu_ptr)
    {
    static u64 loc, *imc_mode_addr, *imc_cmd_addr;
    - int chip = 0, nid;
    char mode[16], cmd[16];
    u32 cb_offset;
    + struct imc_mem_info *ptr = pmu_ptr->mem_info;

    imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root);

    @@ -73,20 +73,20 @@ static void export_imc_mode_and_cmd(struct device_node *node,
    if (of_property_read_u32(node, "cb_offset", &cb_offset))
    cb_offset = IMC_CNTL_BLK_OFFSET;

    - for_each_node(nid) {
    - loc = (u64)(pmu_ptr->mem_info[chip].vbase) + cb_offset;
    + while (ptr->vbase != NULL) {
    + loc = (u64)(ptr->vbase) + cb_offset;
    imc_mode_addr = (u64 *)(loc + IMC_CNTL_BLK_MODE_OFFSET);
    - sprintf(mode, "imc_mode_%d", nid);
    + sprintf(mode, "imc_mode_%d", (u32)(ptr->id));
    if (!imc_debugfs_create_x64(mode, 0600, imc_debugfs_parent,
    imc_mode_addr))
    goto err;

    imc_cmd_addr = (u64 *)(loc + IMC_CNTL_BLK_CMD_OFFSET);
    - sprintf(cmd, "imc_cmd_%d", nid);
    + sprintf(cmd, "imc_cmd_%d", (u32)(ptr->id));
    if (!imc_debugfs_create_x64(cmd, 0600, imc_debugfs_parent,
    imc_cmd_addr))
    goto err;
    - chip++;
    + ptr++;
    }
    return;

    --
    2.20.1
    \
     
     \ /
      Last update: 2019-09-24 18:51    [W:4.165 / U:0.388 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site