]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.18.85/media-don-t-do-dma-on-stack-for-firmware-upload-in-the-as102-driver.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.18.85 / media-don-t-do-dma-on-stack-for-firmware-upload-in-the-as102-driver.patch
1 From b3120d2cc447ee77b9d69bf4ad7b452c9adb4d39 Mon Sep 17 00:00:00 2001
2 From: Michele Baldessari <michele@acksyn.org>
3 Date: Mon, 6 Nov 2017 08:50:22 -0500
4 Subject: media: Don't do DMA on stack for firmware upload in the AS102 driver
5
6 From: Michele Baldessari <michele@acksyn.org>
7
8 commit b3120d2cc447ee77b9d69bf4ad7b452c9adb4d39 upstream.
9
10 Firmware load on AS102 is using the stack which is not allowed any
11 longer. We currently fail with:
12
13 kernel: transfer buffer not dma capable
14 kernel: ------------[ cut here ]------------
15 kernel: WARNING: CPU: 0 PID: 598 at drivers/usb/core/hcd.c:1595 usb_hcd_map_urb_for_dma+0x41d/0x620
16 kernel: Modules linked in: amd64_edac_mod(-) edac_mce_amd as102_fe dvb_as102(+) kvm_amd kvm snd_hda_codec_realtek dvb_core snd_hda_codec_generic snd_hda_codec_hdmi snd_hda_intel snd_hda_codec irqbypass crct10dif_pclmul crc32_pclmul snd_hda_core snd_hwdep snd_seq ghash_clmulni_intel sp5100_tco fam15h_power wmi k10temp i2c_piix4 snd_seq_device snd_pcm snd_timer parport_pc parport tpm_infineon snd tpm_tis soundcore tpm_tis_core tpm shpchp acpi_cpufreq xfs libcrc32c amdgpu amdkfd amd_iommu_v2 radeon hid_logitech_hidpp i2c_algo_bit drm_kms_helper crc32c_intel ttm drm r8169 mii hid_logitech_dj
17 kernel: CPU: 0 PID: 598 Comm: systemd-udevd Not tainted 4.13.10-200.fc26.x86_64 #1
18 kernel: Hardware name: ASUS All Series/AM1I-A, BIOS 0505 03/13/2014
19 kernel: task: ffff979933b24c80 task.stack: ffffaf83413a4000
20 kernel: RIP: 0010:usb_hcd_map_urb_for_dma+0x41d/0x620
21 systemd-fsck[659]: /dev/sda2: clean, 49/128016 files, 268609/512000 blocks
22 kernel: RSP: 0018:ffffaf83413a7728 EFLAGS: 00010282
23 systemd-udevd[604]: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.
24 kernel: RAX: 000000000000001f RBX: ffff979930bce780 RCX: 0000000000000000
25 kernel: RDX: 0000000000000000 RSI: ffff97993ec0e118 RDI: ffff97993ec0e118
26 kernel: RBP: ffffaf83413a7768 R08: 000000000000039a R09: 0000000000000000
27 kernel: R10: 0000000000000001 R11: 00000000ffffffff R12: 00000000fffffff5
28 kernel: R13: 0000000001400000 R14: 0000000000000001 R15: ffff979930806800
29 kernel: FS: 00007effaca5c8c0(0000) GS:ffff97993ec00000(0000) knlGS:0000000000000000
30 kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
31 kernel: CR2: 00007effa9fca962 CR3: 0000000233089000 CR4: 00000000000406f0
32 kernel: Call Trace:
33 kernel: usb_hcd_submit_urb+0x493/0xb40
34 kernel: ? page_cache_tree_insert+0x100/0x100
35 kernel: ? xfs_iunlock+0xd5/0x100 [xfs]
36 kernel: ? xfs_file_buffered_aio_read+0x57/0xc0 [xfs]
37 kernel: usb_submit_urb+0x22d/0x560
38 kernel: usb_start_wait_urb+0x6e/0x180
39 kernel: usb_bulk_msg+0xb8/0x160
40 kernel: as102_send_ep1+0x49/0xe0 [dvb_as102]
41 kernel: ? devres_add+0x3f/0x50
42 kernel: as102_firmware_upload.isra.0+0x1dc/0x210 [dvb_as102]
43 kernel: as102_fw_upload+0xb6/0x1f0 [dvb_as102]
44 kernel: as102_dvb_register+0x2af/0x2d0 [dvb_as102]
45 kernel: as102_usb_probe+0x1f3/0x260 [dvb_as102]
46 kernel: usb_probe_interface+0x124/0x300
47 kernel: driver_probe_device+0x2ff/0x450
48 kernel: __driver_attach+0xa4/0xe0
49 kernel: ? driver_probe_device+0x450/0x450
50 kernel: bus_for_each_dev+0x6e/0xb0
51 kernel: driver_attach+0x1e/0x20
52 kernel: bus_add_driver+0x1c7/0x270
53 kernel: driver_register+0x60/0xe0
54 kernel: usb_register_driver+0x81/0x150
55 kernel: ? 0xffffffffc0807000
56 kernel: as102_usb_driver_init+0x1e/0x1000 [dvb_as102]
57 kernel: do_one_initcall+0x50/0x190
58 kernel: ? __vunmap+0x81/0xb0
59 kernel: ? kfree+0x154/0x170
60 kernel: ? kmem_cache_alloc_trace+0x15f/0x1c0
61 kernel: ? do_init_module+0x27/0x1e9
62 kernel: do_init_module+0x5f/0x1e9
63 kernel: load_module+0x2602/0x2c30
64 kernel: SYSC_init_module+0x170/0x1a0
65 kernel: ? SYSC_init_module+0x170/0x1a0
66 kernel: SyS_init_module+0xe/0x10
67 kernel: do_syscall_64+0x67/0x140
68 kernel: entry_SYSCALL64_slow_path+0x25/0x25
69 kernel: RIP: 0033:0x7effab6cf3ea
70 kernel: RSP: 002b:00007fff5cfcbbc8 EFLAGS: 00000246 ORIG_RAX: 00000000000000af
71 kernel: RAX: ffffffffffffffda RBX: 00005569e0b83760 RCX: 00007effab6cf3ea
72 kernel: RDX: 00007effac2099c5 RSI: 0000000000009a13 RDI: 00005569e0b98c50
73 kernel: RBP: 00007effac2099c5 R08: 00005569e0b83ed0 R09: 0000000000001d80
74 kernel: R10: 00007effab98db00 R11: 0000000000000246 R12: 00005569e0b98c50
75 kernel: R13: 00005569e0b81c60 R14: 0000000000020000 R15: 00005569dfadfdf7
76 kernel: Code: 48 39 c8 73 30 80 3d 59 60 9d 00 00 41 bc f5 ff ff ff 0f 85 26 ff ff ff 48 c7 c7 b8 6b d0 92 c6 05 3f 60 9d 00 01 e8 24 3d ad ff <0f> ff 8b 53 64 e9 09 ff ff ff 65 48 8b 0c 25 00 d3 00 00 48 8b
77 kernel: ---[ end trace c4cae366180e70ec ]---
78 kernel: as10x_usb: error during firmware upload part1
79
80 Let's allocate the the structure dynamically so we can get the firmware
81 loaded correctly:
82 [ 14.243057] as10x_usb: firmware: as102_data1_st.hex loaded with success
83 [ 14.500777] as10x_usb: firmware: as102_data2_st.hex loaded with success
84
85 Signed-off-by: Michele Baldessari <michele@acksyn.org>
86 Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
87 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
88
89 ---
90 drivers/media/usb/as102/as102_fw.c | 28 +++++++++++++++++-----------
91 1 file changed, 17 insertions(+), 11 deletions(-)
92
93 --- a/drivers/media/usb/as102/as102_fw.c
94 +++ b/drivers/media/usb/as102/as102_fw.c
95 @@ -101,18 +101,23 @@ static int as102_firmware_upload(struct
96 unsigned char *cmd,
97 const struct firmware *firmware) {
98
99 - struct as10x_fw_pkt_t fw_pkt;
100 + struct as10x_fw_pkt_t *fw_pkt;
101 int total_read_bytes = 0, errno = 0;
102 unsigned char addr_has_changed = 0;
103
104 + fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL);
105 + if (!fw_pkt)
106 + return -ENOMEM;
107 +
108 +
109 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
110 int read_bytes = 0, data_len = 0;
111
112 /* parse intel hex line */
113 read_bytes = parse_hex_line(
114 (u8 *) (firmware->data + total_read_bytes),
115 - fw_pkt.raw.address,
116 - fw_pkt.raw.data,
117 + fw_pkt->raw.address,
118 + fw_pkt->raw.data,
119 &data_len,
120 &addr_has_changed);
121
122 @@ -122,28 +127,28 @@ static int as102_firmware_upload(struct
123 /* detect the end of file */
124 total_read_bytes += read_bytes;
125 if (total_read_bytes == firmware->size) {
126 - fw_pkt.u.request[0] = 0x00;
127 - fw_pkt.u.request[1] = 0x03;
128 + fw_pkt->u.request[0] = 0x00;
129 + fw_pkt->u.request[1] = 0x03;
130
131 /* send EOF command */
132 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
133 (uint8_t *)
134 - &fw_pkt, 2, 0);
135 + fw_pkt, 2, 0);
136 if (errno < 0)
137 goto error;
138 } else {
139 if (!addr_has_changed) {
140 /* prepare command to send */
141 - fw_pkt.u.request[0] = 0x00;
142 - fw_pkt.u.request[1] = 0x01;
143 + fw_pkt->u.request[0] = 0x00;
144 + fw_pkt->u.request[1] = 0x01;
145
146 - data_len += sizeof(fw_pkt.u.request);
147 - data_len += sizeof(fw_pkt.raw.address);
148 + data_len += sizeof(fw_pkt->u.request);
149 + data_len += sizeof(fw_pkt->raw.address);
150
151 /* send cmd to device */
152 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
153 (uint8_t *)
154 - &fw_pkt,
155 + fw_pkt,
156 data_len,
157 0);
158 if (errno < 0)
159 @@ -152,6 +157,7 @@ static int as102_firmware_upload(struct
160 }
161 }
162 error:
163 + kfree(fw_pkt);
164 return (errno == 0) ? total_read_bytes : errno;
165 }
166