greybus: esx: fix null-deref on hotplug events
We must be prepared to receive hotplug events as soon as we submit the
SVC URB. Since commit 2eb8a6a947d7 ("core: don't set up endo until host
device is initialized") this is no longer the case as the endo would not
have been setup, something which may lead to a null-pointer dereference
in endo_get_module_id() when the interface is created (see oops below
with an added dev_dbg for hd->endo).
Fix this by setting up the endo before submitting the SVC URB.
[ 28.810610] gb_interface_create - hd->endo = (null)
[ 28.816020] Unable to handle kernel NULL pointer dereference at virtual address 0000022b
[ 28.824952] pgd = c0004000
[ 28.827880] [0000022b] *pgd=00000000
[ 28.831913] Internal error: Oops: 17 [#1] PREEMPT ARM
[ 28.837183] Modules linked in: gb_es1(O+) greybus(O) netconsole
[ 28.843419] CPU: 0 PID: 21 Comm: kworker/u2:1 Tainted: G O 4.1.0-rc7 #12
[ 28.851576] Hardware name: Generic AM33XX (Flattened Device Tree)
[ 28.857978] Workqueue: greybus_ap ap_process_event [greybus]
[ 28.863890] task: cf2961c0 ti: cf29c000 task.ti: cf29c000
[ 28.869529] PC is at endo_get_module_id+0x18/0x88 [greybus]
[ 28.875355] LR is at gb_interface_add+0x88/0x204 [greybus]
[ 28.881070] pc : [<bf0052d4>] lr : [<bf005dac>] psr: 20070013
[ 28.881070] sp : cf29de08 ip : cf29de18 fp : cf29de14
[ 28.893021] r10: 00000001 r9 : 0000005a r8 : cd813ec6
[ 28.898461] r7 : 00000058 r6 : cf7fa200 r5 : 00000001 r4 : cf7fa20c
[ 28.905261] r3 : 00000000 r2 : cf2961c0 r1 : 00000001 r0 : 00000000
[ 28.912067] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
[ 28.919677] Control: 10c5387d Table: 8f508019 DAC: 00000015
[ 28.925663] Process kworker/u2:1 (pid: 21, stack limit = 0xcf29c210)
[ 28.932279] Stack: (0xcf29de08 to 0xcf29e000)
[ 28.936823] de00: cf29de44 cf29de18 bf005dac bf0052c8 00000058 cd813ec0
[ 28.945349] de20: cf58b60c bf00afe0 cf7fa200 cf58b600 0000005a 00000001 cf29de84 cf29de48
[ 28.953865] de40: bf004844 bf005d30 00000000 cf02d800 cf29de6c cf29de60 c00759a0 cf58b60c
[ 28.962389] de60: cf2742c0 cf02d800 cf0c6000 cf29dea8 c07b745c 00000000 cf29dee4 cf29de88
[ 28.970908] de80: c005943c bf004560 00000001 00000000 c0059354 cf02d800 c0059c0c 00000001
[ 28.979426] dea0: 00000000 00000000 bf00b314 00000000 00000000 bf009144 c04e3710 cf02d800
[ 28.987945] dec0: cf2742d8 cf02d830 00000088 c0059bd0 00000000 cf2742c0 cf29df24 cf29dee8
[ 28.996464] dee0: c0059b78 c0059248 cf29c000 cf245d40 c0776890 c07b6bf3 00000000 00000000
[ 29.004983] df00: cf245d40 cf2742c0 c0059b20 00000000 00000000 00000000 cf29dfac cf29df28
[ 29.013502] df20: c005fe90 c0059b2c c07812d0 00000000 cf29df4c cf2742c0 00000000 00000001
[ 29.022025] df40: dead4ead ffffffff ffffffff c07c86b0 00000000 00000000 c05fd8e8 cf29df5c
[ 29.030542] df60: cf29df5c 00000000 00000001 dead4ead ffffffff ffffffff c07c86b0 00000000
[ 29.039062] df80: 00000000 c05fd8e8 cf29df88 cf29df88 cf245d40 c005fd98 00000000 00000000
[ 29.047581] dfa0: 00000000 cf29dfb0 c00108f8 c005fda4 00000000 00000000 00000000 00000000
[ 29.056105] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 29.064623] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffff0000 ffff0000
[ 29.073178] [<bf0052d4>] (endo_get_module_id [greybus]) from [<bf005dac>] (gb_interface_add+0x88/0x204 [greybus])
[ 29.083887] [<bf005dac>] (gb_interface_add [greybus]) from [<bf004844>] (ap_process_event+0x2f0/0x4d8 [greybus])
[ 29.094527] [<bf004844>] (ap_process_event [greybus]) from [<c005943c>] (process_one_work+0x200/0x8e4)
[ 29.104228] [<c005943c>] (process_one_work) from [<c0059b78>] (worker_thread+0x58/0x500)
[ 29.112668] [<c0059b78>] (worker_thread) from [<c005fe90>] (kthread+0xf8/0x110)
[ 29.120295] [<c005fe90>] (kthread) from [<c00108f8>] (ret_from_fork+0x14/0x3c)
[ 29.127825] Code: e24cb004 e52de004 e8bd4000 e3510000 (e5d0c22b)
[ 29.137481] ---[ end trace ad95c3c26bdc98ce ]---
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
diff --git a/drivers/staging/greybus/es1.c b/drivers/staging/greybus/es1.c
index f9a6c54c..067b4c1 100644
--- a/drivers/staging/greybus/es1.c
+++ b/drivers/staging/greybus/es1.c
@@ -679,16 +679,6 @@
es1->cport_out_urb_busy[i] = false; /* just to be anal */
}
- /* Start up our svc urb, which allows events to start flowing */
- retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL);
- if (retval)
- goto error;
-
- apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable",
- (S_IWUSR | S_IRUGO),
- gb_debugfs_get(), es1,
- &apb1_log_enable_fops);
-
/*
* XXX Soon this will be initiated later, with a combination
* XXX of a Control protocol probe operation and a
@@ -700,6 +690,15 @@
if (retval)
goto error;
+ /* Start up our svc urb, which allows events to start flowing */
+ retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL);
+ if (retval)
+ goto error;
+
+ apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable",
+ (S_IWUSR | S_IRUGO),
+ gb_debugfs_get(), es1,
+ &apb1_log_enable_fops);
return 0;
error:
ap_disconnect(interface);
diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c
index 274d1d4..97fa2e0 100644
--- a/drivers/staging/greybus/es2.c
+++ b/drivers/staging/greybus/es2.c
@@ -783,16 +783,6 @@
es1->cport_out_urb_busy[i] = false; /* just to be anal */
}
- /* Start up our svc urb, which allows events to start flowing */
- retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL);
- if (retval)
- goto error;
-
- apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable",
- (S_IWUSR | S_IRUGO),
- gb_debugfs_get(), es1,
- &apb1_log_enable_fops);
-
/*
* XXX Soon this will be initiated later, with a combination
* XXX of a Control protocol probe operation and a
@@ -804,6 +794,15 @@
if (retval)
goto error;
+ /* Start up our svc urb, which allows events to start flowing */
+ retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL);
+ if (retval)
+ goto error;
+
+ apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable",
+ (S_IWUSR | S_IRUGO),
+ gb_debugfs_get(), es1,
+ &apb1_log_enable_fops);
return 0;
error:
ap_disconnect(interface);