diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-05-01 17:05:45 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-05-01 17:05:45 +0000 |
commit | 64ae775d6f91c929f4938be111fcc101b845a811 (patch) | |
tree | 057b216d980bc382510356d0c7faae358bc0ceb8 /sys/src | |
parent | c512cf16e5e0d40d559688e6706696f82182a693 (diff) |
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().
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/port/usbxhci.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/src/9/port/usbxhci.c b/sys/src/9/port/usbxhci.c index b4842e638..312a205c1 100644 --- a/sys/src/9/port/usbxhci.c +++ b/sys/src/9/port/usbxhci.c @@ -815,6 +815,10 @@ ctlrcmd(Ctlr *ctlr, u32int c, u32int s, u64int p, u32int *er) 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 @@ completering(Ctlr *ctlr, Ring *r, u32int *er) 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 @@ interrupt(Ureg*, void *arg) 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 @@ interrupt(Ureg*, void *arg) 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 @@ freeslot(void *arg) 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 @@ isowrite(Ep *ep, uchar *p, long n) static char* unstall(Ep *ep, Ring *r) { - Ctlr *ctlr = r->slot->ctlr; char *err; switch(r->ctx[0]&7){ @@ -1474,16 +1480,15 @@ unstall(Ep *ep, Ring *r) } 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; |