> Date: Tue, 14 Mar 2017 11:03:32 +1100
> From: Jonathan Gray <[email protected]>
> 
> Maybe this was the sync diff I had, going to drop it.
> Hit this right at the end of an non-interrupted make build when it was
> doing make install.
> 
> panic: kernel diagnostic assertion "(alignment & (alignment - 1)) == 0" 
> failed: file "/usr/src/sys/uvm/uvm_page.c", line 725
> Stopped at      panic+0x158:        TID    PID    UID     PRFLAGS     PFLAGS  
> CPU  COMMAND
> Debugger() at panic+0x154
> panic() at uvm_pglistalloc+0x23c
> uvm_pglistalloc() at _dmamem_alloc_range+0x78
> _dmamem_alloc_range() at _dmamem_alloc+0x14
> _dmamem_alloc() at usb_block_allocmem+0xd4
> usb_block_allocmem() at usb_allocmem+0xb4
> usb_allocmem() at dwc2_hc_setup_align_buf+0x74
> https://www.openbsd.org/ddb.html describes the minimum info required in bug
> reports.  Insufficient info makes it difficult to find and fix bugs.
> ddb> tr
> Debugger() at panic+0x154
> panic() at uvm_pglistalloc+0x23c
> uvm_pglistalloc() at _dmamem_alloc_range+0x78
> _dmamem_alloc_range() at _dmamem_alloc+0x14
> _dmamem_alloc() at usb_block_allocmem+0xd4
> usb_block_allocmem() at usb_allocmem+0xb4
> usb_allocmem() at dwc2_hc_setup_align_buf+0x74
> dwc2_hc_setup_align_buf() at dwc2_assign_and_init_hc+0x23c
> dwc2_assign_and_init_hc() at dwc2_hcd_select_transactions+0x184
> dwc2_hcd_select_transactions() at dwc2_release_channel+0x1c0
> dwc2_release_channel() at dwc2_hc_n_intr+0x158
> dwc2_hc_n_intr() at dwc2_handle_hcd_intr+0x168
> dwc2_handle_hcd_intr() at dwc2_intr+0xa8
> dwc2_intr() at bcm_intc_irq_handler+0x74
> bcm_intc_irq_handler() at handle_el1h_irq+0x6c
> handle_el1h_irq() at sched_idle+0x198
> sched_idle() at proc_trampoline+0xc

Looks like a genuine bug in the dwc2 code to me.

        if (chan->ep_type != USB_ENDPOINT_XFER_ISOC)
                buf_size = hsotg->core_params->max_transfer_size;
        else
                buf_size = 4096;

        ...

                err = usb_allocmem(&hsotg->hsotg_sc->sc_bus, buf_size, buf_size,
                                   &qh->dw_align_buf_usbdma);

In bcm2835_dwctwo.c the max_transfer_size parameter is initialized to
635535, which isn't a power of two.  But this value may be passed as
an alignment to bus_dmamem_alloc() which requires it to be a power of
two.

Perhaps the 2nd buf_size here should be rounded up to the next power
of two?

The NetBSD code where this came from has the same issue, but perhaps
they don't have the strict check.  But using 635535 as the alignment
value makes no sense whatsoever.

Reply via email to