shithub: riscv

Download patch

ref: e0c221eea6b68c87f89eb073d7204851398fc5d8
parent: b486d8871b3ae20745f32b9d509d75d5a911ec65
author: cinap_lenrek <[email protected]>
date: Mon Dec 22 11:10:18 EST 2014

pc, pc64: fix intrdisable() to remove the Vctl entry even tho we can't disable the interrupt on apic

--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -82,29 +82,40 @@
 	Vctl **pv, *v;
 	int vno;
 
-	/*
-	 * For now, none of this will work with the APIC code,
-	 * there is no mapping between irq and vector as the IRQ
-	 * is pretty meaningless.
-	 */
-	if(arch->intrvecno == nil)
-		return -1;
-	vno = arch->intrvecno(irq);
+	if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){
+		/*
+		 * on APIC machine, irq is pretty meaningless
+		 * and disabling a the vector is not implemented.
+		 * however, we still want to remove the matching
+		 * Vctl entry to prevent calling Vctl.f() with a
+		 * stale Vctl.a pointer.
+		 */
+		irq = -1;
+		vno = VectorPIC;
+	} else {
+		vno = arch->intrvecno(irq);
+	}
 	ilock(&vctllock);
-	pv = &vctl[vno];
-	while (*pv &&
-		  ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a ||
-		   strcmp((*pv)->name, name)))
-		pv = &((*pv)->next);
-	assert(*pv);
+	for(; vno <= MaxIrqLAPIC; vno++){
+		for(pv = &vctl[vno]; (v = *pv) != nil; pv = &v->next){
+			if(v->isintr && (v->irq == irq || irq == -1)
+			&& v->tbdf == tbdf && v->f == f && v->a == a
+			&& strcmp(v->name, name) == 0)
+				break;
+		}
+		if(v != nil){
+			*pv = v->next;
+			xfree(v);
 
-	v = *pv;
-	*pv = (*pv)->next;	/* Link out the entry */
-
-	if(vctl[vno] == nil && arch->intrdisable != nil)
-		arch->intrdisable(irq);
+			if(irq == -1)
+				break;
+			if(vctl[vno] == nil && arch->intrdisable != nil)
+				arch->intrdisable(irq);
+		}
+		if(irq != -1)
+			break;
+	}
 	iunlock(&vctllock);
-	xfree(v);
 	return 0;
 }
 
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -82,29 +82,40 @@
 	Vctl **pv, *v;
 	int vno;
 
-	/*
-	 * For now, none of this will work with the APIC code,
-	 * there is no mapping between irq and vector as the IRQ
-	 * is pretty meaningless.
-	 */
-	if(arch->intrvecno == nil)
-		return -1;
-	vno = arch->intrvecno(irq);
+	if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){
+		/*
+		 * on APIC machine, irq is pretty meaningless
+		 * and disabling a the vector is not implemented.
+		 * however, we still want to remove the matching
+		 * Vctl entry to prevent calling Vctl.f() with a
+		 * stale Vctl.a pointer.
+		 */
+		irq = -1;
+		vno = VectorPIC;
+	} else {
+		vno = arch->intrvecno(irq);
+	}
 	ilock(&vctllock);
-	pv = &vctl[vno];
-	while (*pv &&
-		  ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a ||
-		   strcmp((*pv)->name, name)))
-		pv = &((*pv)->next);
-	assert(*pv);
+	for(; vno <= MaxIrqLAPIC; vno++){
+		for(pv = &vctl[vno]; (v = *pv) != nil; pv = &v->next){
+			if(v->isintr && (v->irq == irq || irq == -1)
+			&& v->tbdf == tbdf && v->f == f && v->a == a
+			&& strcmp(v->name, name) == 0)
+				break;
+		}
+		if(v != nil){
+			*pv = v->next;
+			xfree(v);
 
-	v = *pv;
-	*pv = (*pv)->next;	/* Link out the entry */
-
-	if(vctl[vno] == nil && arch->intrdisable != nil)
-		arch->intrdisable(irq);
+			if(irq == -1)
+				break;
+			if(vctl[vno] == nil && arch->intrdisable != nil)
+				arch->intrdisable(irq);
+		}
+		if(irq != -1)
+			break;
+	}
 	iunlock(&vctllock);
-	xfree(v);
 	return 0;
 }