[PATCH] CB/CBI storage devices not working with CONFIG_VMAP_STACK=y

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
   I've built 4.9.0-rc4 with CONFIG_VMAP_STACK=y, and while I can use bulk
storage drives, I cannot use CB-based USB floppy drive: kernel complains
(once) that DMA address is invalid, and after that log is full of device resets:

Nov  7 12:18:42 petr-dev3 kernel: [   25.929808] scsi 12:0:0:1: Direct-Access     Generic  USB SM/MS/SD     1.00 PQ: 0 ANSI: 0
Nov  7 12:18:42 petr-dev3 kernel: [   25.969520] scsi 13:0:0:0: Direct-Access     CITIZEN  X1DE-USB         1002 PQ: 0 ANSI: 0 CCS
Nov  7 12:18:42 petr-dev3 kernel: [   25.978504] sd 13:0:0:0: Attached scsi generic sg9 type 0
Nov  7 12:18:42 petr-dev3 kernel: [   25.981037] ------------[ cut here ]------------
Nov  7 12:18:42 petr-dev3 kernel: [   25.981042] WARNING: CPU: 0 PID: 3829 at /bhavesh/usr/src/git/libata-pv3/drivers/usb/core/hcd.c:1584 usb_hcd_map_urb_for_dma+0x425/0x540
Nov  7 12:18:42 petr-dev3 kernel: [   25.981042] transfer buffer not dma capable
Nov  7 12:18:42 petr-dev3 kernel: [   25.981059] Modules linked in: snd_hda_codec_hdmi(+) snd_hda_codec_realtek snd_hda_codec_generic coretemp hwmon x86_pkg_temp_thermal crct10dif_pclmul crc32_pclmul
crc32c_intel snd_hda_intel ghash_clmulni_intel snd_hda_codec aesni_intel uas aes_x86_64 snd_hwdep lrw dcdbas glue_helper ablk_helper usb_storage cryptd serio_raw snd_hda_core sr_mod i2c_i801 cdrom i2c_smbus snd_pcm_oss sg snd_mixer_oss snd_pcm snd_timer mei_me snd mei tpm_tis tpm_tis_core tpm e1000e ptp pps_core iTCO_wdt iTCO_vendor_support lpc_ich mfd_core nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables x_tables ipv6 crc_ccitt autofs4
Nov  7 12:18:42 petr-dev3 kernel: [   25.981060] CPU: 0 PID: 3829 Comm: usb-storage Not tainted 4.9.0-rc4-64-00017-ga6c2c43-dirty #110
Nov  7 12:18:42 petr-dev3 kernel: [   25.981061] Hardware name: Dell Inc. Precision T3610/09M8Y8, BIOS A11 04/22/2016
Nov  7 12:18:42 petr-dev3 kernel: [   25.981063]  ffffc90000573ac8 ffffffff813a1d60 ffffc90000573b18 0000000000000000
Nov  7 12:18:42 petr-dev3 kernel: [   25.981064]  ffffc90000573b08 ffffffff8105e171 00000630000fff59 ffff88101dbc83c0
Nov  7 12:18:42 petr-dev3 kernel: [   25.981064]  0000000000000000 ffff881024a7d800 0000000000000001 ffff881024e97000
Nov  7 12:18:42 petr-dev3 kernel: [   25.981065] Call Trace:
Nov  7 12:18:42 petr-dev3 kernel: [   25.981069]  [<ffffffff813a1d60>] dump_stack+0x63/0x83
Nov  7 12:18:42 petr-dev3 kernel: [   25.981070]  [<ffffffff8105e171>] __warn+0xc1/0xe0
Nov  7 12:18:42 petr-dev3 kernel: [   25.981071]  [<ffffffff8105e1da>] warn_slowpath_fmt+0x4a/0x50
Nov  7 12:18:42 petr-dev3 kernel: [   25.981072]  [<ffffffff816831b5>] usb_hcd_map_urb_for_dma+0x425/0x540
Nov  7 12:18:42 petr-dev3 kernel: [   25.981074]  [<ffffffff816840f0>] usb_hcd_submit_urb+0x330/0xb20
Nov  7 12:18:42 petr-dev3 kernel: [   25.981075]  [<ffffffff817faa18>] ? schedule+0x38/0x90
Nov  7 12:18:42 petr-dev3 kernel: [   25.981076]  [<ffffffff817fd26c>] ? schedule_timeout+0x12c/0x180
Nov  7 12:18:42 petr-dev3 kernel: [   25.981078]  [<ffffffff8109c2c1>] ? cpuacct_charge+0x81/0x90
Nov  7 12:18:42 petr-dev3 kernel: [   25.981079]  [<ffffffff81089535>] ? set_next_entity+0x45/0x9a0
Nov  7 12:18:42 petr-dev3 kernel: [   25.981081]  [<ffffffff8168595f>] usb_submit_urb+0x2ef/0x560
Nov  7 12:18:42 petr-dev3 kernel: [   25.981083]  [<ffffffff810818f0>] ? wake_up_q+0x80/0x80
Nov  7 12:18:42 petr-dev3 kernel: [   25.981085]  [<ffffffffa0359fc7>] usb_stor_msg_common+0x97/0x120 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981087]  [<ffffffffa035a34a>] usb_stor_ctrl_transfer+0x9a/0xc0 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981088]  [<ffffffffa035aafe>] usb_stor_CB_transport+0x4e/0x230 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981089]  [<ffffffffa035b05a>] usb_stor_invoke_transport+0x23a/0x500 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981091]  [<ffffffff810025c9>] ? do_syscall_64+0x69/0x180
Nov  7 12:18:42 petr-dev3 kernel: [   25.981093]  [<ffffffffa0359edd>] usb_stor_ufi_command+0x5d/0x90 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981095]  [<ffffffffa035c3e0>] usb_stor_control_thread+0x150/0x250 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981096]  [<ffffffff810025c9>] ? do_syscall_64+0x69/0x180
Nov  7 12:18:42 petr-dev3 kernel: [   25.981097]  [<ffffffffa035c290>] ? fill_inquiry_response+0x20/0x20 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981098]  [<ffffffff810025c9>] ? do_syscall_64+0x69/0x180
Nov  7 12:18:42 petr-dev3 kernel: [   25.981100]  [<ffffffffa035c290>] ? fill_inquiry_response+0x20/0x20 [usb_storage]
Nov  7 12:18:42 petr-dev3 kernel: [   25.981103]  [<ffffffff81079b35>] kthread+0xc5/0xe0
Nov  7 12:18:42 petr-dev3 kernel: [   25.981104]  [<ffffffff81079a70>] ? kthread_park+0x60/0x60
Nov  7 12:18:42 petr-dev3 kernel: [   25.981106]  [<ffffffff817fe9f5>] ret_from_fork+0x25/0x30
Nov  7 12:18:42 petr-dev3 kernel: [   25.981107] ---[ end trace ec2cf5d1c79e1535 ]---
Nov  7 12:18:42 petr-dev3 kernel: [   26.100014] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
...
Nov  7 12:18:48 petr-dev3 kernel: [   37.950059] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
Nov  7 12:18:49 petr-dev3 kernel: [   38.280055] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
Nov  7 12:18:49 petr-dev3 kernel: [   38.610061] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
Nov  7 12:18:49 petr-dev3 kernel: [   38.950056] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
Nov  7 12:18:50 petr-dev3 kernel: [   39.280067] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
Nov  7 12:18:50 petr-dev3 kernel: [   39.610061] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
...
Nov  7 17:07:51 petr-dev3 kernel: [17380.710055] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
Nov  7 17:07:52 petr-dev3 kernel: [17381.040057] usb 2-1.3.2: reset full-speed USB device number 5 using ehci-pci
...

Problem is that CB/CBI code passes CDB directly to the HCD for transmission -
and unfortunately SCSI error handling code creates CDB on stack (scsi_eh_prep_cmnd
uses scsi_eh_save structure for CDB, and as far as I can tell, everybody creates
scsi_eh_save structure on stack, rather than in kmalloc memory).

As no other drivers does DMA directly from CDB field, I think if I try to modify
USB storage code to not create scsi_eh_save on stack it will get broken again
anyway when someone else stores CDB on stack, so I went ahead with memcpy
solution instead: now CB/CBI code copies CDB into its private iobuf, and sends
command from there.

With this fix in place USB floppy works again...

Thanks,
Petr Vandrovec





commit 07da00a2bb122bc7ffb287aa80f58714a17b1d9c
Author: Petr Vandrovec <petr@xxxxxxxxxxxxxx>
Date:   Wed Nov 9 14:46:35 2016 -0800

    Fix UFI USB storage devices with vmalloced stacks
    
    Some code (all error handling) submits CDBs that are allocated
    on stack.  This breaks with UFI code that tries to create URB
    directly from SCSI command buffer - which happens to be in
    vmalloced memory with vmalloced kernel stacks.
    
    Let's make copy of cmd in usb_stor_CB_transport - it is pretty
    cheap, and I cannot find any easy way to modify SCSI error
    handling to not use on-stack structure for error handling
    command.
    
    Signed-off-by: Petr Vandrovec <petr@xxxxxxxxxxxxxx>

diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index ffd0867..e46833b 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -954,10 +954,16 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 	/* COMMAND STAGE */
 	/* let's send the command via the control pipe */
+	/*
+	 * Command is sometime (f.e. after scsi_eh_prep_cmnd) on the stack.
+	 * Stack may be vmallocated.  So no DMA for us.  Make a copy.
+	 */
+	BUG_ON(srb->cmd_len > US_IOBUF_SIZE);
+	memcpy(us->iobuf, srb->cmnd, srb->cmd_len);
 	result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
 				      US_CBI_ADSC, 
 				      USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 
-				      us->ifnum, srb->cmnd, srb->cmd_len);
+				      us->ifnum, us->iobuf, srb->cmd_len);
 
 	/* check the return code for the command */
 	usb_stor_dbg(us, "Call to usb_stor_ctrl_transfer() returned %d\n",
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux