* Crash while capturing with usbmon
@ 2020-03-05 19:26 Måns Rullgård
2020-03-05 21:09 ` Alan Stern
0 siblings, 1 reply; 7+ messages in thread
From: Måns Rullgård @ 2020-03-05 19:26 UTC (permalink / raw)
To: linux-usb
While trying to capture some USB traffic, this happened:
8<--- cut here ---
Unable to handle kernel paging request at virtual address ffeff000
pgd = e14505c9
[ffeff000] *pgd=6ffce861, *pte=00000000, *ppte=00000000
Internal error: Oops: 37 [#1] SMP ARM
Modules linked in: sd_mod usb_storage scsi_mod ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip6table_filter ip6_tables xt_conntrack nf_conntrack nf_defrag_ipv6 libcrc32c nf_defrag_ipv4 iptable_filter ip_tables x_tables hci_uart btbcm sun4i_can edt_ft5x06 victron_cerbogx_adc can_dev victron_gxdisp_bl brcmfmac bluetooth ecdh_generic ecc cfg80211 rfkill brcmutil pwm_sun4i sun4i_emac mdio_sun4i evdev pwm_beeper
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.0-rc4-next-20200304-venus-1 #1
Hardware name: Allwinner sun7i (A20) Family
PC is at memcpy+0x48/0x330
LR is at 0x21564032
pc : [<c069e0a8>] lr : [<21564032>] psr: 20070193
sp : c0b01ba4 ip : a2cb45df fp : ed64b180
r10: c0b04e88 r9 : 00000043 r8 : f5b57f8b
r7 : 393670c0 r6 : 08e2dffb r5 : abb694bc r4 : 44843523
r3 : 907b4c7f r2 : 00000480 r1 : ffeff000 r0 : ed661b00
Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
Control: 10c5387d Table: 6f09806a DAC: 00000051
Process swapper/0 (pid: 0, stack limit = 0x0bca7ef1)
Stack: (0xc0b01ba4 to 0xc0b02000)
1ba0: 00001000 00001000 ffefee00 ed4fd080 ed661900 00000700 c050c88c
1bc0: ed4fd080 ed6618c0 00001000 ed4fd200 00001040 c050cd2c 00000000 00000900
1be0: 00070193 00000000 00000000 00000080 00001000 00000000 00001000 00000000
1c00: 5e6004b0 00000000 2ab0f539 0b751234 0b7512c8 10961743 c0b04e88 ed4fd0c0
1c20: ee92996c 00000000 ed4fd200 ee929948 a0070193 00000001 ed4fd200 c050ade4
1c40: ed4fd200 00000000 00000000 00000000 ef026040 ef0266c4 00000001 c050ae1c
1c60: ed4fd200 ee932c00 00000000 c04f6788 ef026040 ef027040 ed4fd200 00000000
1c80: ef026040 c05216f0 ed4fd400 00000000 00000080 ef0266c4 ef026040 c0522624
1ca0: f08f8080 00000203 ed4fd200 00000000 c0b04e88 ef026040 ef027040 00000000
1cc0: 00000004 c0b04e88 c0b01cf8 ef026330 0000005d c051fbd8 ee3ebf00 ee3ebf00
1ce0: ed60f210 c0b38d80 c0b04e88 c0619098 00000000 00000000 00000010 10961743
1d00: ee4b1240 ef026040 000002ee a0070193 c0b01d70 00000022 c0b3ecfa c0880f9c
1d20: c0880f74 c05259b0 ee929780 ef14d468 00000000 c0178ed4 ed41a168 10961743
1d40: 00000000 ef14d400 ee4b1240 c0b04e88 ef14d468 ef14d400 00000001 ef00cc00
1d60: c0b00000 c0b01e4c 2eceb000 c0178fd0 00000000 10961743 ef14d400 ef14d468
1d80: c0b01f18 c0179064 ef14d400 c0b052b4 c0b01f18 c017d448 c0ab0c10 00000000
1da0: c0b01f18 c0178140 c0ab0c10 c017872c c0b052b4 f080200c f0802000 c0b01de0
1dc0: f0803000 c03c8fb4 c05a6014 60070113 ffffffff c0b01e14 ef79c940 c0101acc
1de0: 00000002 00000000 10961743 10961743 ef79c9f0 00000002 00000040 c0ab1940
1e00: ef79c940 0000012a c0b01e4c 2eceb000 00000003 c0b01e30 c05a6000 c05a6014
1e20: 60070113 ffffffff 00000051 bf000000 c0b04e88 ef79c940 c0ab1940 c0b3efcc
1e40: c08d9ff8 c08df484 00000008 c0b01e4c c0b01e4c c0b01e54 c0b01e54 10961743
1e60: c0ab03e8 00000000 00000003 c0b0308c ffffe000 00000100 c0b03080 40000003
1e80: c0b03080 c01022c8 c0b04e88 00000001 ef14dd00 c0aaa340 c0ab0c40 0000000a
1ea0: c087c59c c0aaa2cc 000092f6 c0b03d00 c0701aa0 00200002 00000000 ffffe000
1ec0: 00000000 00000000 00000001 ef00cc00 c0b00000 c0ab03e8 00000000 c0131bfc
1ee0: c0ab0c10 c0178730 c0b052b4 f080200c f0802000 c0b01f18 f0803000 c03c8fb4
1f00: c0108a68 60070013 ffffffff c0b01f4c 00000000 c0101acc 00000000 00129634
1f20: ef79c830 c0119aa0 ffffe000 c0b04ea8 c0b04eec 00000001 00000000 c0b04e88
1f40: c0ab03e8 00000000 c0b04f64 c0b01f68 c0108a64 c0108a68 60070013 ffffffff
1f60: 00000051 00000000 ffffe000 c01576ec 000000d1 c0b43a4c c0b43a00 c0b3ecd3
1f80: 00000000 10961743 effffc40 000000d1 c0b43a4c c0b43a00 c0a3aa3c 00000000
1fa0: c0a3aa3c effffc40 00000000 c01579e8 c0b04e88 c0a00d3c ffffffff ffffffff
1fc0: 00000000 c0a0059c 00000000 c0a3aa3c 10931143 00000000 c0a00330 00000051
1fe0: 10c0387d 100010bb 49ff5000 410fc074 10c5387d 00000000 00000000 00000000
[<c069e0a8>] (memcpy) from [<c050c88c>] (mon_copy_to_buff+0x4c/0x6c)
[<c050c88c>] (mon_copy_to_buff) from [<c050cd2c>] (mon_bin_event+0x480/0x7b8)
[<c050cd2c>] (mon_bin_event) from [<c050ade4>] (mon_bus_complete+0x50/0x6c)
[<c050ade4>] (mon_bus_complete) from [<c050ae1c>] (mon_complete+0x1c/0x34)
[<c050ae1c>] (mon_complete) from [<c04f6788>] (__usb_hcd_giveback_urb+0x64/0x10c)
[<c04f6788>] (__usb_hcd_giveback_urb) from [<c05216f0>] (musb_giveback+0x44/0x50)
[<c05216f0>] (musb_giveback) from [<c0522624>] (musb_advance_schedule+0xb4/0x278)
[<c0522624>] (musb_advance_schedule) from [<c051fbd8>] (musb_interrupt+0x128/0xcd4)
[<c051fbd8>] (musb_interrupt) from [<c05259b0>] (sunxi_musb_interrupt+0x98/0x120)
[<c05259b0>] (sunxi_musb_interrupt) from [<c0178ed4>] (__handle_irq_event_percpu+0x50/0x120)
[<c0178ed4>] (__handle_irq_event_percpu) from [<c0178fd0>] (handle_irq_event_percpu+0x2c/0x7c)
[<c0178fd0>] (handle_irq_event_percpu) from [<c0179064>] (handle_irq_event+0x44/0x68)
[<c0179064>] (handle_irq_event) from [<c017d448>] (handle_fasteoi_irq+0xa8/0x18c)
[<c017d448>] (handle_fasteoi_irq) from [<c0178140>] (generic_handle_irq+0x24/0x34)
[<c0178140>] (generic_handle_irq) from [<c017872c>] (__handle_domain_irq+0x5c/0xb4)
[<c017872c>] (__handle_domain_irq) from [<c03c8fb4>] (gic_handle_irq+0x3c/0x78)
[<c03c8fb4>] (gic_handle_irq) from [<c0101acc>] (__irq_svc+0x6c/0x90)
Exception stack(0xc0b01de0 to 0xc0b01e28)
1de0: 00000002 00000000 10961743 10961743 ef79c9f0 00000002 00000040 c0ab1940
1e00: ef79c940 0000012a c0b01e4c 2eceb000 00000003 c0b01e30 c05a6000 c05a6014
1e20: 60070113 ffffffff
[<c0101acc>] (__irq_svc) from [<c05a6014>] (net_rx_action+0x228/0x38c)
[<c05a6014>] (net_rx_action) from [<c01022c8>] (__do_softirq+0x120/0x2b0)
[<c01022c8>] (__do_softirq) from [<c0131bfc>] (irq_exit+0xcc/0xd8)
[<c0131bfc>] (irq_exit) from [<c0178730>] (__handle_domain_irq+0x60/0xb4)
[<c0178730>] (__handle_domain_irq) from [<c03c8fb4>] (gic_handle_irq+0x3c/0x78)
[<c03c8fb4>] (gic_handle_irq) from [<c0101acc>] (__irq_svc+0x6c/0x90)
Exception stack(0xc0b01f18 to 0xc0b01f60)
1f00: 00000000 00129634
1f20: ef79c830 c0119aa0 ffffe000 c0b04ea8 c0b04eec 00000001 00000000 c0b04e88
1f40: c0ab03e8 00000000 c0b04f64 c0b01f68 c0108a64 c0108a68 60070013 ffffffff
[<c0101acc>] (__irq_svc) from [<c0108a68>] (arch_cpu_idle+0x38/0x3c)
[<c0108a68>] (arch_cpu_idle) from [<c01576ec>] (do_idle+0x224/0x260)
[<c01576ec>] (do_idle) from [<c01579e8>] (cpu_startup_entry+0x18/0x1c)
[<c01579e8>] (cpu_startup_entry) from [<c0a00d3c>] (start_kernel+0x3fc/0x420)
Code: ba000002 f5d1f03c f5d1f05c f5d1f07c (e8b151f8)
---[ end trace acd3bf978189eeca ]---
It is easily reproducible. What can I do to narrow down the cause?
--
Måns Rullgård
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Crash while capturing with usbmon
2020-03-05 19:26 Crash while capturing with usbmon Måns Rullgård
@ 2020-03-05 21:09 ` Alan Stern
2020-03-05 21:53 ` Måns Rullgård
2020-03-06 12:38 ` Måns Rullgård
0 siblings, 2 replies; 7+ messages in thread
From: Alan Stern @ 2020-03-05 21:09 UTC (permalink / raw)
To: Måns Rullgård; +Cc: linux-usb
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset=UTF-8, Size: 804 bytes --]
On Thu, 5 Mar 2020, [iso-8859-1] Måns Rullgård wrote:
> While trying to capture some USB traffic, this happened:
>
> 8<--- cut here ---
> Unable to handle kernel paging request at virtual address ffeff000
...
> [<c069e0a8>] (memcpy) from [<c050c88c>] (mon_copy_to_buff+0x4c/0x6c)
> [<c050c88c>] (mon_copy_to_buff) from [<c050cd2c>] (mon_bin_event+0x480/0x7b8)
> [<c050cd2c>] (mon_bin_event) from [<c050ade4>] (mon_bus_complete+0x50/0x6c)
...
> It is easily reproducible. What can I do to narrow down the cause?
What kind of USB traffic were you monitoring? Isochronous?
Scatter-gather?
Can you add printk statements in drivers/usb/mon/mon_bin.c:
mon_bin_get_data() to determine which of the pathways was used for
calling mon_copy_buff() and what the values of the arguments were?
Alan Stern
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Crash while capturing with usbmon
2020-03-05 21:09 ` Alan Stern
@ 2020-03-05 21:53 ` Måns Rullgård
2020-03-06 12:38 ` Måns Rullgård
1 sibling, 0 replies; 7+ messages in thread
From: Måns Rullgård @ 2020-03-05 21:53 UTC (permalink / raw)
To: Alan Stern; +Cc: linux-usb
Alan Stern <stern@rowland.harvard.edu> writes:
> On Thu, 5 Mar 2020, Måns Rullgård wrote:
>
>> While trying to capture some USB traffic, this happened:
>>
>> 8<--- cut here ---
>> Unable to handle kernel paging request at virtual address ffeff000
> ...
>> [<c069e0a8>] (memcpy) from [<c050c88c>] (mon_copy_to_buff+0x4c/0x6c)
>> [<c050c88c>] (mon_copy_to_buff) from [<c050cd2c>] (mon_bin_event+0x480/0x7b8)
>> [<c050cd2c>] (mon_bin_event) from [<c050ade4>] (mon_bus_complete+0x50/0x6c)
> ...
>
>> It is easily reproducible. What can I do to narrow down the cause?
>
> What kind of USB traffic were you monitoring? Isochronous?
> Scatter-gather?
It was bulk transfers reading from a flash stick:
# tcpdump -i usbmon5
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on usbmon5, link-type USB_LINUX_MMAPPED (USB with padded Linux header), capture size 262144 bytes
18:52:44.785060 CONTROL SUBMIT to 5:4:0
18:52:44.785248 CONTROL COMPLETE from 5:4:0
18:52:44.786077 CONTROL SUBMIT to 5:3:0
18:52:44.786171 CONTROL COMPLETE from 5:3:0
18:52:44.786274 CONTROL SUBMIT to 5:2:0
18:52:44.786308 CONTROL COMPLETE from 5:2:0
18:52:44.786379 CONTROL SUBMIT to 5:1:0
18:52:44.786408 CONTROL COMPLETE from 5:1:0
18:52:50.693712 BULK SUBMIT to 5:4:2
18:52:50.693788 BULK COMPLETE from 5:4:2
18:52:50.694470 BULK SUBMIT to 5:4:1
18:52:50.694562 BULK COMPLETE from 5:4:1
18:52:50.694667 BULK SUBMIT to 5:4:1
18:52:50.694687 BULK COMPLETE from 5:4:1
18:52:50.695562 BULK SUBMIT to 5:4:2
18:52:50.695630 BULK COMPLETE from 5:4:2
18:52:50.695799 BULK SUBMIT to 5:4:1
18:52:50.695823 BULK SUBMIT to 5:4:1
18:52:50.695828 BULK SUBMIT to 5:4:1
18:52:50.695832 BULK SUBMIT to 5:4:1
And then it died. Sometimes it lasts a little longer, but it always
happens pretty quickly.
> Can you add printk statements in drivers/usb/mon/mon_bin.c:
> mon_bin_get_data() to determine which of the pathways was used for
> calling mon_copy_buff() and what the values of the arguments were?
I'll do that.
--
Måns Rullgård
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Crash while capturing with usbmon
2020-03-05 21:09 ` Alan Stern
2020-03-05 21:53 ` Måns Rullgård
@ 2020-03-06 12:38 ` Måns Rullgård
2020-03-06 17:27 ` Alan Stern
1 sibling, 1 reply; 7+ messages in thread
From: Måns Rullgård @ 2020-03-06 12:38 UTC (permalink / raw)
To: Alan Stern; +Cc: linux-usb
Alan Stern <stern@rowland.harvard.edu> writes:
> On Thu, 5 Mar 2020, Måns Rullgård wrote:
>
>> While trying to capture some USB traffic, this happened:
>>
>> 8<--- cut here ---
>> Unable to handle kernel paging request at virtual address ffeff000
> ...
>> [<c069e0a8>] (memcpy) from [<c050c88c>] (mon_copy_to_buff+0x4c/0x6c)
>> [<c050c88c>] (mon_copy_to_buff) from [<c050cd2c>] (mon_bin_event+0x480/0x7b8)
>> [<c050cd2c>] (mon_bin_event) from [<c050ade4>] (mon_bus_complete+0x50/0x6c)
> ...
>
>> It is easily reproducible. What can I do to narrow down the cause?
>
> What kind of USB traffic were you monitoring? Isochronous?
> Scatter-gather?
>
> Can you add printk statements in drivers/usb/mon/mon_bin.c:
> mon_bin_get_data() to determine which of the pathways was used for
> calling mon_copy_buff() and what the values of the arguments were?
OK, I added a printk to mon_bin_get_data(), and the bad call has
offset=4736, length=4096 urb->num_sgs=0 urb->transfer_flags=0x281,
urb->transfer_buffer=0xffefee00.
I guess the question now is how transfer_buffer got assigned that value.
--
Måns Rullgård
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Crash while capturing with usbmon
2020-03-06 12:38 ` Måns Rullgård
@ 2020-03-06 17:27 ` Alan Stern
2020-03-06 17:48 ` Måns Rullgård
0 siblings, 1 reply; 7+ messages in thread
From: Alan Stern @ 2020-03-06 17:27 UTC (permalink / raw)
To: Måns Rullgård; +Cc: linux-usb
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset=UTF-8, Size: 1743 bytes --]
On Fri, 6 Mar 2020, [iso-8859-1] Måns Rullgård wrote:
> Alan Stern <stern@rowland.harvard.edu> writes:
>
> > On Thu, 5 Mar 2020, Måns Rullgård wrote:
> >
> >> While trying to capture some USB traffic, this happened:
> >>
> >> 8<--- cut here ---
> >> Unable to handle kernel paging request at virtual address ffeff000
> > ...
> >> [<c069e0a8>] (memcpy) from [<c050c88c>] (mon_copy_to_buff+0x4c/0x6c)
> >> [<c050c88c>] (mon_copy_to_buff) from [<c050cd2c>] (mon_bin_event+0x480/0x7b8)
> >> [<c050cd2c>] (mon_bin_event) from [<c050ade4>] (mon_bus_complete+0x50/0x6c)
> > ...
> >
> >> It is easily reproducible. What can I do to narrow down the cause?
> >
> > What kind of USB traffic were you monitoring? Isochronous?
> > Scatter-gather?
> >
> > Can you add printk statements in drivers/usb/mon/mon_bin.c:
> > mon_bin_get_data() to determine which of the pathways was used for
> > calling mon_copy_buff() and what the values of the arguments were?
>
> OK, I added a printk to mon_bin_get_data(), and the bad call has
> offset=4736, length=4096 urb->num_sgs=0 urb->transfer_flags=0x281,
> urb->transfer_buffer=0xffefee00.
The values seem reasonable enough, except for transfer_buffer.
> I guess the question now is how transfer_buffer got assigned that value.
Depending on how your kernel is configured (in particular, whether
CONFIG_MUSB_PIO_ONLY is enabled), it might be assigned in
musb_alloc_temp_buffer() (in drivers/usb/musb/musb_host.c) or
usb_sg_init() (in drivers/usb/core/message.c).
With a little more detective work you ought to be to determine which
pathway is being used and what its important values are. I wouldn't be
surprised to learn that 0xffefee0 was the value from sg_virt(sg) in
usb_sg_init().
Alan Stern
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Crash while capturing with usbmon
2020-03-06 17:27 ` Alan Stern
@ 2020-03-06 17:48 ` Måns Rullgård
2020-03-06 18:18 ` Alan Stern
0 siblings, 1 reply; 7+ messages in thread
From: Måns Rullgård @ 2020-03-06 17:48 UTC (permalink / raw)
To: Alan Stern; +Cc: linux-usb
Alan Stern <stern@rowland.harvard.edu> writes:
> On Fri, 6 Mar 2020, Måns Rullgård wrote:
>
>> Alan Stern <stern@rowland.harvard.edu> writes:
>>
>> > On Thu, 5 Mar 2020, Måns Rullgård wrote:
>> >
>> >> While trying to capture some USB traffic, this happened:
>> >>
>> >> 8<--- cut here ---
>> >> Unable to handle kernel paging request at virtual address ffeff000
>> > ...
>> >> [<c069e0a8>] (memcpy) from [<c050c88c>] (mon_copy_to_buff+0x4c/0x6c)
>> >> [<c050c88c>] (mon_copy_to_buff) from [<c050cd2c>] (mon_bin_event+0x480/0x7b8)
>> >> [<c050cd2c>] (mon_bin_event) from [<c050ade4>] (mon_bus_complete+0x50/0x6c)
>> > ...
>> >
>> >> It is easily reproducible. What can I do to narrow down the cause?
>> >
>> > What kind of USB traffic were you monitoring? Isochronous?
>> > Scatter-gather?
>> >
>> > Can you add printk statements in drivers/usb/mon/mon_bin.c:
>> > mon_bin_get_data() to determine which of the pathways was used for
>> > calling mon_copy_buff() and what the values of the arguments were?
>>
>> OK, I added a printk to mon_bin_get_data(), and the bad call has
>> offset=4736, length=4096 urb->num_sgs=0 urb->transfer_flags=0x281,
>> urb->transfer_buffer=0xffefee00.
>
> The values seem reasonable enough, except for transfer_buffer.
>
>> I guess the question now is how transfer_buffer got assigned that value.
>
> Depending on how your kernel is configured (in particular, whether
> CONFIG_MUSB_PIO_ONLY is enabled), it might be assigned in
> musb_alloc_temp_buffer() (in drivers/usb/musb/musb_host.c) or
> usb_sg_init() (in drivers/usb/core/message.c).
>
> With a little more detective work you ought to be to determine which
> pathway is being used and what its important values are. I wouldn't be
> surprised to learn that 0xffefee0 was the value from sg_virt(sg) in
> usb_sg_init().
I found the problem. Initially, usb_sg_init() sets transfer_buffer to
NULL like this:
if (!PageHighMem(sg_page(sg)))
urb->transfer_buffer = sg_virt(sg);
else
urb->transfer_buffer = NULL;
Later, musb_host_rx() uses sg_miter_next() to assign a temporary
address:
/*
* We need to map sg if the transfer_buffer is
* NULL.
*/
if (!urb->transfer_buffer) {
qh->use_sg = true;
sg_miter_start(&qh->sg_miter, urb->sg, 1,
sg_flags);
}
if (qh->use_sg) {
if (!sg_miter_next(&qh->sg_miter)) {
dev_err(musb->controller, "error: sg list empty\n");
sg_miter_stop(&qh->sg_miter);
status = -EINVAL;
done = true;
goto finish;
}
urb->transfer_buffer = qh->sg_miter.addr;
received_len = urb->actual_length;
qh->offset = 0x0;
done = musb_host_packet_rx(musb, urb, epnum,
iso_err);
/* Calculate the number of bytes received */
received_len = urb->actual_length -
received_len;
qh->sg_miter.consumed = received_len;
sg_miter_stop(&qh->sg_miter);
} else {
done = musb_host_packet_rx(musb, urb,
epnum, iso_err);
}
When the transfer has completed, a bogus value is left behind in
urb->transfer_buffer, and this trips up usbmon. Apparently nothing else
uses that value before the urb is released.
This patch makes it not crash:
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 1c813c37462a..b67b40de1947 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1459,8 +1459,10 @@ void musb_host_tx(struct musb *musb, u8 epnum)
qh->segsize = length;
if (qh->use_sg) {
- if (offset + length >= urb->transfer_buffer_length)
+ if (offset + length >= urb->transfer_buffer_length) {
qh->use_sg = false;
+ urb->transfer_buffer = NULL;
+ }
}
musb_ep_select(mbase, epnum);
@@ -1977,8 +1979,10 @@ void musb_host_rx(struct musb *musb, u8 epnum)
urb->actual_length += xfer_len;
qh->offset += xfer_len;
if (done) {
- if (qh->use_sg)
+ if (qh->use_sg) {
qh->use_sg = false;
+ urb->transfer_buffer = NULL;
+ }
if (urb->status == -EINPROGRESS)
urb->status = status;
--
Måns Rullgård
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: Crash while capturing with usbmon
2020-03-06 17:48 ` Måns Rullgård
@ 2020-03-06 18:18 ` Alan Stern
0 siblings, 0 replies; 7+ messages in thread
From: Alan Stern @ 2020-03-06 18:18 UTC (permalink / raw)
To: Måns Rullgård; +Cc: linux-usb
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset=UTF-8, Size: 2452 bytes --]
On Fri, 6 Mar 2020, [iso-8859-1] Måns Rullgård wrote:
> I found the problem. Initially, usb_sg_init() sets transfer_buffer to
> NULL like this:
>
> if (!PageHighMem(sg_page(sg)))
> urb->transfer_buffer = sg_virt(sg);
> else
> urb->transfer_buffer = NULL;
>
> Later, musb_host_rx() uses sg_miter_next() to assign a temporary
> address:
>
> /*
> * We need to map sg if the transfer_buffer is
> * NULL.
> */
> if (!urb->transfer_buffer) {
> qh->use_sg = true;
> sg_miter_start(&qh->sg_miter, urb->sg, 1,
> sg_flags);
> }
>
> if (qh->use_sg) {
> if (!sg_miter_next(&qh->sg_miter)) {
> dev_err(musb->controller, "error: sg list empty\n");
> sg_miter_stop(&qh->sg_miter);
> status = -EINVAL;
> done = true;
> goto finish;
> }
> urb->transfer_buffer = qh->sg_miter.addr;
> received_len = urb->actual_length;
> qh->offset = 0x0;
> done = musb_host_packet_rx(musb, urb, epnum,
> iso_err);
> /* Calculate the number of bytes received */
> received_len = urb->actual_length -
> received_len;
> qh->sg_miter.consumed = received_len;
> sg_miter_stop(&qh->sg_miter);
> } else {
> done = musb_host_packet_rx(musb, urb,
> epnum, iso_err);
> }
>
> When the transfer has completed, a bogus value is left behind in
> urb->transfer_buffer, and this trips up usbmon. Apparently nothing else
> uses that value before the urb is released.
>
> This patch makes it not crash:
>
> diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> index 1c813c37462a..b67b40de1947 100644
> --- a/drivers/usb/musb/musb_host.c
> +++ b/drivers/usb/musb/musb_host.c
> @@ -1459,8 +1459,10 @@ void musb_host_tx(struct musb *musb, u8 epnum)
> qh->segsize = length;
>
> if (qh->use_sg) {
> - if (offset + length >= urb->transfer_buffer_length)
> + if (offset + length >= urb->transfer_buffer_length) {
> qh->use_sg = false;
> + urb->transfer_buffer = NULL;
> + }
> }
>
> musb_ep_select(mbase, epnum);
> @@ -1977,8 +1979,10 @@ void musb_host_rx(struct musb *musb, u8 epnum)
> urb->actual_length += xfer_len;
> qh->offset += xfer_len;
> if (done) {
> - if (qh->use_sg)
> + if (qh->use_sg) {
> qh->use_sg = false;
> + urb->transfer_buffer = NULL;
> + }
>
> if (urb->status == -EINPROGRESS)
> urb->status = status;
Good detective work, and I'm glad I was able to help.
Alan Stern
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-03-06 18:18 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-05 19:26 Crash while capturing with usbmon Måns Rullgård
2020-03-05 21:09 ` Alan Stern
2020-03-05 21:53 ` Måns Rullgård
2020-03-06 12:38 ` Måns Rullgård
2020-03-06 17:27 ` Alan Stern
2020-03-06 17:48 ` Måns Rullgård
2020-03-06 18:18 ` Alan Stern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).