ref: 64ae775d6f91c929f4938be111fcc101b845a811
parent: c512cf16e5e0d40d559688e6706696f82182a693
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon May 1 13:05:45 EDT 2023
usbxhci: add some robustness checks Add some checks in the interrupt handler to ensure that the slot and ring referred to by the event have been initialized. Also add a check in ctlrcmd() just in case we mess up the recovery and someone issues a ctlrcmd() after a failed xhciinit().
--- a/sys/src/9/port/usbxhci.c
+++ b/sys/src/9/port/usbxhci.c
@@ -815,6 +815,10 @@
qunlock(&ctlr->cmdlock);
return Erecover;
}
+ if(ctlr->cr->base == nil || ctlr->cr->ctlr != ctlr){
+ qunlock(&ctlr->cmdlock);
+ return Egreg;
+ }
ctlr->cr->stopped = 0;
queuetd(ctlr->cr, c, s, p, w);
err = waittd(w, 5000);
@@ -833,6 +837,9 @@
u32int *td, x;
u64int pa;
+ if(r->base == nil || r->ctlr != ctlr)
+ return;
+
pa = (*(u64int*)er) & ~15ULL;
ilock(r);
for(x = r->rp; (int)(r->wp - x) > 0; x++){
@@ -876,7 +883,7 @@
Slot *slot;
u32int *irs, *td, x;
- if(ring->base == nil)
+ if(ring->base == nil || ring->ctlr != ctlr)
return;
irs = &ctlr->rts[IR0];
@@ -899,7 +906,7 @@
if(x == 0 || x > ctlr->nslots)
break;
slot = ctlr->slot[x];
- if(slot == nil)
+ if(slot == nil || slot->ctlr != ctlr)
break;
completering(ctlr, &slot->epr[(td[3]>>16)-1&31], td);
break;
@@ -935,7 +942,7 @@
if(arg == nil)
return;
slot = arg;
- if(slot->id != 0){
+ if(slot->id > 0){
Ctlr *ctlr = slot->ctlr;
qlock(&ctlr->slotlock);
if(ctlr->slot != nil
@@ -1464,7 +1471,6 @@
static char*
unstall(Ep *ep, Ring *r)
{
- Ctlr *ctlr = r->slot->ctlr;
char *err;
switch(r->ctx[0]&7){
@@ -1474,16 +1480,15 @@
}
if(ep->clrhalt){
ep->clrhalt = 0;
- err = ctlrcmd(ctlr, CR_RESETEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
- dmaflush(0, r->ctx, 8*4 << ctlr->csz);
+ err = ctlrcmd(r->ctlr, CR_RESETEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
+ dmaflush(0, r->ctx, 8*4 << r->ctlr->csz);
if(err != nil)
return err;
r->stopped = 1;
}
if(r->stopped){
- err = ctlrcmd(ctlr, CR_SETTRDQP | (r->id<<16) | (r->slot->id<<24), 0,
- resetring(r), nil);
- dmaflush(0, r->ctx, 8*4 << ctlr->csz);
+ err = ctlrcmd(r->ctlr, CR_SETTRDQP | (r->id<<16) | (r->slot->id<<24), 0, resetring(r), nil);
+ dmaflush(0, r->ctx, 8*4 << r->ctlr->csz);
if(err != nil)
return err;
r->stopped = 0;