NetBSD-Bugs archive

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

Re: port-evbarm/54696: Kernel panic in bus_dma.c on Raspberry Pi 3B/3B+



At Wed, 13 Nov 2019 21:05:01 +0000 (UTC),
Michael van Elst wrote:
>  >[   153.534940] panic: kernel diagnostic assertion "len > 0 && offset + len <= map->dm_mapsize" failed: file "/usr/src/sys/arch/arm/arm32/bus_dma.c", line 1058 len 0 offset 0 mapsize 8192
>  
>  A zero length transfer. In that case it would be a uaudio (or audio?) bug.
>  
>  No idea why that should be aarch64-specific.

I think it's dwc2's issue.

According to report, calling usb_syncmem() with len == 0 in
dwc2_device_start() caused a panic.

 sys/external/bsd/dwc2/dwc2.c:
  929 dwc2_device_start(struct usbd_xfer *xfer)
  930 {
  :
  966     if (xfertype == UE_CONTROL) {
  :
  990     } else {
  :
  995         len = xfer->ux_length;
  996     }
  :
 1027     if (!(xfertype == UE_CONTROL && len == 0)) {
 1028         dwc2_urb->usbdma = &xfer->ux_dmabuf;
 1029         dwc2_urb->buf = KERNADDR(dwc2_urb->usbdma, 0);
 1030         dwc2_urb->dma = DMAADDR(dwc2_urb->usbdma, 0);
 1031
 1032         usb_syncmem(&xfer->ux_dmabuf, 0, len,
 1033             dir == UE_DIR_IN ?
 1034             BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 

Here len passed to usb_syncmem() is xfer->ux_length.

According to reported backtrace,
- dwc2_device_start(xfer) is called from dwc2_device_isoc_transfer(xfer).
- dwc2_device_isoc_transfer(xfer) is called from usbd_transfer(xfer) as
  up_methods->upm_transfer.
- usbd_transfer(xfer) seems be called from uaudio_chan_rtransfer(ch)
  and uaudio_chan_rtransfer(ch) seems be inline-expanded in
  uaudio_trigger_input().

 sys/dev/usb/uaudio.c:
 2838 uaudio_chan_rtransfer(struct chan *ch)
 2839 {
 :
 2874     usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0,
 2875         uaudio_chan_rintr);
 2876
 2877     (void)usbd_transfer(cb->xfer);
 2878 }

usbd_setup_isoc_xfer() initializes ux_length == 0.

  592 usbd_setup_isoc_xfer(struct usbd_xfer *xfer, void *priv, uint16_t
      *frlengths,
  593     uint32_t nframes, uint16_t flags, usbd_callback callback)
  594 {
  595     xfer->ux_priv = priv;
  596     xfer->ux_buffer = NULL;
  597     xfer->ux_length = 0;
 
And then see also similar (the same?) PR port-arm/54615,
sc.dying%gmail.com@localhost wrote:
>  At line 1032 of sys/external/bsd/dwc2/dwc2.c usb_syncmem is called.
>
> >		usb_syncmem(&xfer->ux_dmabuf, 0, len,
> >		    dir == UE_DIR_IN ?
> >			BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
>
> len = xfer->ux_length, however, ux_length is always 0 for isoc transfers.

I just read source code and I have no environment.  But if my
understanding is correct, I think that dwc2_device_start() needs
to handle length == 0 properly.

Thanks,
---
Tetsuya Isaki <isaki%pastel-flower.jp@localhost / isaki%NetBSD.org@localhost>


Home | Main Index | Thread Index | Old Index