code: plan9front

Download patch

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;