On Wed, Apr 19, 2023 at 04:21:50PM -0700, Nam Nguyen wrote:
> >Synopsis:    xbox 360 controller crash
> >Category:    kernel amd64
> >Environment:
>       System      : OpenBSD 7.3
>       Details     : OpenBSD 7.3-current (GENERIC.MP) #1149: Mon Apr 17 
> 12:04:55 MDT 2023
>                        
> dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> 
>       Architecture: OpenBSD.amd64
>       Machine     : amd64
> >Description:
>       Plugging in xbox 360 controller has a chance of causing a system
>       freeze and sending it to ddb. it prints, "panic: b_to_q: tty has
>       no clist."
> 
>         picture of trace: https://namtsui.com/public/ujoy1.jpg
> 
>         This issue seems related to that reported by thfr@ here:
>         https://marc.info/?l=openbsd-bugs&m=165136879315845&w=2
> 
>         The crash seems to occur frequently on my radeon 6850 desktop
>         but does not seem to happen on my intel x230i laptop.
> 
>         If I plug in my xbox 360 controller to xhci on top of my
>         computer case and have a dac connected to the ehci nearby, it
>         can cause it more easily without requiring plugging and
>         unplugging. Plugging xbox 360 into the back of the case into
>         ehci seems to require plugging and unplugging the
>         controller. The crash can occur upon unplugging and plugging in
>         the controller, during setting up controls in the sameboy port,
>         or upon launching flycast emulator.
> 
> >How-To-Repeat:
>         It is a bit hard to reproduce, but running sdl-jstest repeatedly
>         in conjunction with unplugging and plugging in controllers can
>         cause it to crash within a minute or two.
> 
>         `while true; do sdl-jstest --list; vmstat;
>          sysctl kern.malloc.kmemstat.DRM; sleep 2; done'
>         
> >Fix:
>       There is a patch that I tested by brynet@ that seems to have
>       resolved the issue.

I think we need to allocate the ring buffer to before calling
uhidev_open. That way it's not NULL in uhid_intr as seen in Nam's
backtrace.

Alternatively, uhid_intr could return early, e.g:

    if (!sc->sc_q)
        return;

ok on the diff below, or thoughts?

Index: dev/usb/uhid.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhid.c,v
retrieving revision 1.89
diff -u -p -u -r1.89 uhid.c
--- dev/usb/uhid.c      2 Jul 2022 08:50:42 -0000       1.89
+++ dev/usb/uhid.c      19 Apr 2023 06:18:40 -0000
@@ -225,11 +225,16 @@ uhid_do_open(dev_t dev, int flag, int mo
        if (usbd_is_dying(sc->sc_hdev.sc_udev))
                return (ENXIO);
 
-       error = uhidev_open(&sc->sc_hdev);
-       if (error)
-               return (error);
+       if (sc->sc_hdev.sc_state & UHIDEV_OPEN)
+               return (EBUSY);
 
        clalloc(&sc->sc_q, UHID_BSIZE, 0);
+
+       error = uhidev_open(&sc->sc_hdev);
+       if (error) {
+               clfree(&sc->sc_q);
+               return (error);
+       }
 
        sc->sc_obuf = malloc(sc->sc_hdev.sc_osize, M_USBDEV, M_WAITOK);
 

Reply via email to