RDMA/core: Make sure "ib_port" is valid when access sysfs node
[ Upstream commit5e15ff29b1
] The "ib_port" structure must be set before adding the sysfs kobject, and reset after removing it, otherwise it may crash when accessing the sysfs node: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050 Mem abort info: ESR = 0x96000006 Exception class = DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000006 CM = 0, WnR = 0 user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000e85f5ba5 [0000000000000050] pgd=0000000848fd9003, pud=000000085b387003, pmd=0000000000000000 Internal error: Oops: 96000006 [#2] PREEMPT SMP Modules linked in: ib_umad(O) mlx5_ib(O) nfnetlink_cttimeout(E) nfnetlink(E) act_gact(E) cls_flower(E) sch_ingress(E) openvswitch(E) nsh(E) nf_nat_ipv6(E) nf_nat_ipv4(E) nf_conncount(E) nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) mst_pciconf(O) ipmi_devintf(E) ipmi_msghandler(E) ipmb_dev_int(OE) mlx5_core(O) mlxfw(O) mlxdevm(O) auxiliary(O) ib_uverbs(O) ib_core(O) mlx_compat(O) psample(E) sbsa_gwdt(E) uio_pdrv_genirq(E) uio(E) mlxbf_pmc(OE) mlxbf_gige(OE) mlxbf_tmfifo(OE) gpio_mlxbf2(OE) pwr_mlxbf(OE) mlx_trio(OE) i2c_mlxbf(OE) mlx_bootctl(OE) bluefield_edac(OE) knem(O) ip_tables(E) ipv6(E) crc_ccitt(E) [last unloaded: mst_pci] Process grep (pid: 3372, stack limit = 0x0000000022055c92) CPU: 5 PID: 3372 Comm: grep Tainted: G D OE 4.19.161-mlnx.47.gadcd9e3 #1 Hardware name: https://www.mellanox.com BlueField SoC/BlueField SoC, BIOS BlueField:3.9.2-15-ga2403ab Sep 8 2022 pstate: 40000005 (nZcv daif -PAN -UAO) pc : hw_stat_port_show+0x4c/0x80 [ib_core] lr : port_attr_show+0x40/0x58 [ib_core] sp : ffff000029f43b50 x29: ffff000029f43b50 x28: 0000000019375000 x27: ffff8007b821a540 x26: ffff000029f43e30 x25: 0000000000008000 x24: ffff000000eaa958 x23: 0000000000001000 x22: ffff8007a4ce3000 x21: ffff8007baff8000 x20: ffff8007b9066ac0 x19: ffff8007bae97578 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 x8 : ffff8007a4ce4000 x7 : 0000000000000000 x6 : 000000000000003f x5 : ffff000000e6a280 x4 : ffff8007a4ce3000 x3 : 0000000000000000 x2 : aaaaaaaaaaaaaaab x1 : ffff8007b9066a10 x0 : ffff8007baff8000 Call trace: hw_stat_port_show+0x4c/0x80 [ib_core] port_attr_show+0x40/0x58 [ib_core] sysfs_kf_seq_show+0x8c/0x150 kernfs_seq_show+0x44/0x50 seq_read+0x1b4/0x45c kernfs_fop_read+0x148/0x1d8 __vfs_read+0x58/0x180 vfs_read+0x94/0x154 ksys_read+0x68/0xd8 __arm64_sys_read+0x28/0x34 el0_svc_common+0x88/0x18c el0_svc_handler+0x78/0x94 el0_svc+0x8/0xe8 Code: f2955562 aa1603e4 aa1503e0 f9405683 (f9402861) Fixes:d8a5883814
("RDMA/core: Replace the ib_port_data hw_stats pointers with a ib_port pointer") Signed-off-by: Mark Zhang <markzhang@nvidia.com> Reviewed-by: Michael Guralnik <michaelgur@nvidia.com> Link: https://lore.kernel.org/r/88867e705c42c1cd2011e45201c25eecdb9fef94.1667810736.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
13586753ae
Коммит
f981c697b2
|
@ -1198,6 +1198,9 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
|
|||
p->port_num = port_num;
|
||||
kobject_init(&p->kobj, &port_type);
|
||||
|
||||
if (device->port_data && is_full_dev)
|
||||
device->port_data[port_num].sysfs = p;
|
||||
|
||||
cur_group = p->groups_list;
|
||||
ret = alloc_port_table_group("gids", &p->groups[0], p->attrs_list,
|
||||
attr->gid_tbl_len, show_port_gid);
|
||||
|
@ -1243,9 +1246,6 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
|
|||
}
|
||||
|
||||
list_add_tail(&p->kobj.entry, &coredev->port_list);
|
||||
if (device->port_data && is_full_dev)
|
||||
device->port_data[port_num].sysfs = p;
|
||||
|
||||
return p;
|
||||
|
||||
err_groups:
|
||||
|
@ -1253,6 +1253,8 @@ err_groups:
|
|||
err_del:
|
||||
kobject_del(&p->kobj);
|
||||
err_put:
|
||||
if (device->port_data && is_full_dev)
|
||||
device->port_data[port_num].sysfs = NULL;
|
||||
kobject_put(&p->kobj);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
@ -1261,14 +1263,17 @@ static void destroy_port(struct ib_core_device *coredev, struct ib_port *port)
|
|||
{
|
||||
bool is_full_dev = &port->ibdev->coredev == coredev;
|
||||
|
||||
if (port->ibdev->port_data &&
|
||||
port->ibdev->port_data[port->port_num].sysfs == port)
|
||||
port->ibdev->port_data[port->port_num].sysfs = NULL;
|
||||
list_del(&port->kobj.entry);
|
||||
if (is_full_dev)
|
||||
sysfs_remove_groups(&port->kobj, port->ibdev->ops.port_groups);
|
||||
|
||||
sysfs_remove_groups(&port->kobj, port->groups_list);
|
||||
kobject_del(&port->kobj);
|
||||
|
||||
if (port->ibdev->port_data &&
|
||||
port->ibdev->port_data[port->port_num].sysfs == port)
|
||||
port->ibdev->port_data[port->port_num].sysfs = NULL;
|
||||
|
||||
kobject_put(&port->kobj);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче