linux/drivers/infiniband/hw/cxgb3
Neil Horman e48f129c2f [SCSI] cxgb3i: convert cdev->l2opt to use rcu to prevent NULL dereference
This oops was reported recently:
d:mon> e
cpu 0xd: Vector: 300 (Data Access) at [c0000000fd4c7120]
    pc: d00000000076f194: .t3_l2t_get+0x44/0x524 [cxgb3]
    lr: d000000000b02108: .init_act_open+0x150/0x3d4 [cxgb3i]
    sp: c0000000fd4c73a0
   msr: 8000000000009032
   dar: 0
 dsisr: 40000000
  current = 0xc0000000fd640d40
  paca    = 0xc00000000054ff80
    pid   = 5085, comm = iscsid
d:mon> t
[c0000000fd4c7450] d000000000b02108 .init_act_open+0x150/0x3d4 [cxgb3i]
[c0000000fd4c7500] d000000000e45378 .cxgbi_ep_connect+0x784/0x8e8 [libcxgbi]
[c0000000fd4c7650] d000000000db33f0 .iscsi_if_rx+0x71c/0xb18
[scsi_transport_iscsi2]
[c0000000fd4c7740] c000000000370c9c .netlink_data_ready+0x40/0xa4
[c0000000fd4c77c0] c00000000036f010 .netlink_sendskb+0x4c/0x9c
[c0000000fd4c7850] c000000000370c18 .netlink_sendmsg+0x358/0x39c
[c0000000fd4c7950] c00000000033be24 .sock_sendmsg+0x114/0x1b8
[c0000000fd4c7b50] c00000000033d208 .sys_sendmsg+0x218/0x2ac
[c0000000fd4c7d70] c00000000033f55c .sys_socketcall+0x228/0x27c
[c0000000fd4c7e30] c0000000000086a4 syscall_exit+0x0/0x40
--- Exception: c01 (System Call) at 00000080da560cfc

The root cause was an EEH error, which sent us down the offload_close path in
the cxgb3 driver, which in turn sets cdev->l2opt to NULL, without regard for
upper layer driver (like the cxgbi drivers) which might have execution contexts
in the middle of its use. The result is the oops above, when t3_l2t_get attempts
to dereference L2DATA(cdev)->nentries in arp_hash right after the EEH error handler sets it to NULL.

The fix is to prevent the setting of the NULL pointer until after there are no
further users of it.  The t3cdev->l2opt pointer is now converted to be an rcu
pointer and the L2DATA macro is now called under the protection of the
rcu_read_lock().  When the EEH error path:
t3_adapter_error->offload_close->cxgb3_offload_deactivate
Is exectured, setting of that l2opt pointer to NULL, is now gated on an rcu
quiescence point, preventing, allowing L2DATA callers to safely check for a NULL
pointer without concern that the underlying data will be freeded before the
pointer is dereferenced.

This has been tested by the reporter and shown to fix the reproted oops

[nhorman: fix up unitinialised variable reported by Dan Carpenter]
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Reviewed-by: Karen Xie <kxie@chelsio.com>
Cc: stable@kernel.org
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
2011-09-26 09:28:01 -05:00
..
Kconfig Update broken web addresses in the kernel. 2010-10-18 11:03:14 +02:00
Makefile IB: Replace EXTRA_CFLAGS with ccflags-y 2010-10-23 13:45:03 -07:00
cxio_dbg.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
cxio_hal.c RDMA/cxgb3,cxgb4: Remove dead code 2011-01-10 17:41:43 -08:00
cxio_hal.h RDMA/cxgb3: Don't exceed the max HW CQ depth 2010-09-02 14:52:21 -07:00
cxio_resource.c kfifo: fix warn_unused_result 2009-12-22 14:17:56 -08:00
cxio_resource.h RDMA/cxgb3: Remove Open Grid Computing copyrights in iw_cxgb3 driver 2007-02-16 13:57:35 -08:00
cxio_wr.h tree-wide: fix comment/printk typos 2010-11-01 15:38:34 -04:00
iwch.c RDMA/cxgb3: Shrink .text with compile-time init of handlers arrays 2010-04-28 14:57:40 -07:00
iwch.h RDMA/cxgb3: Doorbell overflow avoidance and recovery 2010-02-24 10:40:28 -08:00
iwch_cm.c [SCSI] cxgb3i: convert cdev->l2opt to use rcu to prevent NULL dereference 2011-09-26 09:28:01 -05:00
iwch_cm.h RDMA/cxgb3: Don't free endpoints early 2009-09-05 20:22:38 -07:00
iwch_cq.c RDMA/cxgb3: MEM_MGT_EXTENSIONS support 2008-07-14 23:48:45 -07:00
iwch_ev.c RDMA/cxgb3: When a user QP is marked in error, also mark the CQs in error 2010-10-22 22:00:53 -07:00
iwch_mem.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
iwch_provider.c RDMA: Allow for NULL .modify_device() and .modify_port() methods 2011-07-18 16:44:30 -07:00
iwch_provider.h RDMA/cxgb3: Don't post zero-byte read if endpoint is going away 2011-05-24 10:01:04 -07:00
iwch_qp.c RDMA/cxgb3: Don't post zero-byte read if endpoint is going away 2011-05-24 10:01:04 -07:00
iwch_user.h RDMA/cxgb3: When a user QP is marked in error, also mark the CQs in error 2010-10-22 22:00:53 -07:00
tcb.h