Hi Mathias, On Mon, Jan 16, 2023 at 04:22:11PM +0200, Mathias Nyman wrote: > From: Jimmy Hu <hhhuuu@xxxxxxxxxx> > > When the host controller is not responding, all URBs queued to all > endpoints need to be killed. This can cause a kernel panic if we > dereference an invalid endpoint. > > Fix this by using xhci_get_virt_ep() helper to find the endpoint and > checking if the endpoint is valid before dereferencing it. I'm a bit confused this goes in and even to stable. Let me quote your own analysis from Message-ID: <0fe978ed-8269-9774-1c40-f8a98c17e838@xxxxxxxxxxxxxxx> On Thu, Dec 22, 2022 at 03:18:53PM +0200, Mathias Nyman wrote: > I think root cause is that freeing xhci->devs[i] and including rings isn't > protected by the lock, this happens in xhci_free_virt_device() called by > xhci_free_dev(), which in turn may be called by usbcore at any time > > So xhci->devs[i] might just suddenly disappear > > Patch just checks more often if xhci->devs[i] is valid, between every endpoint. > So the race between xhci_free_virt_device() and xhci_kill_endpoint_urbs() > doesn't trigger null pointer deref as easily. I believe the above is correct and even Jimmy was unable to verify your later patch (3rd in this serie), which brings a question how could be this patch tested. It just burns a bug a bit deeper and I do not think it is the right approach. ladis > [233311.853271] xhci-hcd xhci-hcd.1.auto: xHCI host controller not responding, assume dead > [233311.853393] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000e8 > > [233311.853964] pc : xhci_hc_died+0x10c/0x270 > [233311.853971] lr : xhci_hc_died+0x1ac/0x270 > > [233311.854077] Call trace: > [233311.854085] xhci_hc_died+0x10c/0x270 > [233311.854093] xhci_stop_endpoint_command_watchdog+0x100/0x1a4 > [233311.854105] call_timer_fn+0x50/0x2d4 > [233311.854112] expire_timers+0xac/0x2e4 > [233311.854118] run_timer_softirq+0x300/0xabc > [233311.854127] __do_softirq+0x148/0x528 > [233311.854135] irq_exit+0x194/0x1a8 > [233311.854143] __handle_domain_irq+0x164/0x1d0 > [233311.854149] gic_handle_irq.22273+0x10c/0x188 > [233311.854156] el1_irq+0xfc/0x1a8 > [233311.854175] lpm_cpuidle_enter+0x25c/0x418 [msm_pm] > [233311.854185] cpuidle_enter_state+0x1f0/0x764 > [233311.854194] do_idle+0x594/0x6ac > [233311.854201] cpu_startup_entry+0x7c/0x80 > [233311.854209] secondary_start_kernel+0x170/0x198 > > Fixes: 50e8725e7c42 ("xhci: Refactor command watchdog and fix split string.") > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Jimmy Hu <hhhuuu@xxxxxxxxxx> > Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> > --- > drivers/usb/host/xhci-ring.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c > index ddc30037f9ce..f5b0e1ce22af 100644 > --- a/drivers/usb/host/xhci-ring.c > +++ b/drivers/usb/host/xhci-ring.c > @@ -1169,7 +1169,10 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci, > struct xhci_virt_ep *ep; > struct xhci_ring *ring; > > - ep = &xhci->devs[slot_id]->eps[ep_index]; > + ep = xhci_get_virt_ep(xhci, slot_id, ep_index); > + if (!ep) > + return; > + > if ((ep->ep_state & EP_HAS_STREAMS) || > (ep->ep_state & EP_GETTING_NO_STREAMS)) { > int stream_id; > -- > 2.25.1