summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-12-22 15:52:37 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-12-22 15:52:37 +0000
commita6c89b1492d8f2d99d4746f02aebfcf13d570a61 (patch)
tree53b926302b7efe99f090b045e6fac3a96ef34973
parent20cbe50184aefa4063f3f43eb89ea166d8bc6d22 (diff)
If we use the cookie-based interrupt API on sun4v, whe shouldn't put the
interrupts in the lookup table. On machines like the Oracle T7-2 this would make the code believe that there is interrupt sharing, but since we bypass intr_list_handler() when using the cookie-based interrupt API, we wouldn't properly acknowledge the interrupt. This fixes the last remaining problem with interrupts on the Oracle T7-2.
-rw-r--r--sys/arch/sparc64/dev/vbus.c6
-rw-r--r--sys/arch/sparc64/dev/vpci.c8
-rw-r--r--sys/arch/sparc64/sparc64/intr.c30
3 files changed, 22 insertions, 22 deletions
diff --git a/sys/arch/sparc64/dev/vbus.c b/sys/arch/sparc64/dev/vbus.c
index 85260dd4ddd..11894593e8e 100644
--- a/sys/arch/sparc64/dev/vbus.c
+++ b/sys/arch/sparc64/dev/vbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vbus.c,v 1.9 2017/12/06 16:20:53 kettenis Exp $ */
+/* $OpenBSD: vbus.c,v 1.10 2017/12/22 15:52:36 kettenis Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
*
@@ -181,7 +181,6 @@ vbus_intr_map(int node, int ino, uint64_t *sysino)
if (err != H_EOK)
return (-1);
- KASSERT(*sysino == INTVEC(*sysino));
return (0);
}
imap += address_cells + interrupt_cells + 2;
@@ -238,8 +237,9 @@ vbus_intr_ack(struct intrhand *ih)
bus_space_tag_t t = ih->ih_bus;
struct vbus_softc *sc = t->cookie;
uint64_t devhandle = sc->sc_devhandle;
+ uint64_t sysino = INTVEC(ih->ih_number);
- sun4v_intr_setstate(devhandle, ih->ih_number, INTR_IDLE);
+ sun4v_intr_setstate(devhandle, sysino, INTR_IDLE);
}
bus_space_tag_t
diff --git a/sys/arch/sparc64/dev/vpci.c b/sys/arch/sparc64/dev/vpci.c
index 3a1a7a00c42..70af99abc44 100644
--- a/sys/arch/sparc64/dev/vpci.c
+++ b/sys/arch/sparc64/dev/vpci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vpci.c,v 1.23 2017/12/06 16:20:53 kettenis Exp $ */
+/* $OpenBSD: vpci.c,v 1.24 2017/12/22 15:52:36 kettenis Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org>
*
@@ -328,7 +328,7 @@ vpci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
struct vpci_pbm *pbm = pa->pa_pc->cookie;
uint64_t devhandle = pbm->vp_devhandle;
- uint64_t devino = INTINO(*ihp);
+ uint64_t devino = INTVEC(*ihp);
uint64_t sysino;
int err;
@@ -337,7 +337,6 @@ vpci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
if (err != H_EOK)
return (-1);
- KASSERT(sysino == INTVEC(sysino));
*ihp = sysino;
return (0);
}
@@ -590,8 +589,9 @@ vpci_intr_ack(struct intrhand *ih)
bus_space_tag_t t = ih->ih_bus;
struct vpci_pbm *pbm = t->cookie;
uint64_t devhandle = pbm->vp_devhandle;
+ uint64_t sysino = INTVEC(ih->ih_number);
- sun4v_intr_setstate(devhandle, ih->ih_number, INTR_IDLE);
+ sun4v_intr_setstate(devhandle, sysino, INTR_IDLE);
}
void
diff --git a/sys/arch/sparc64/sparc64/intr.c b/sys/arch/sparc64/sparc64/intr.c
index 193e734e345..6321d3c4dc5 100644
--- a/sys/arch/sparc64/sparc64/intr.c
+++ b/sys/arch/sparc64/sparc64/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.57 2017/12/06 16:20:53 kettenis Exp $ */
+/* $OpenBSD: intr.c,v 1.58 2017/12/22 15:52:36 kettenis Exp $ */
/* $NetBSD: intr.c,v 1.39 2001/07/19 23:38:11 eeh Exp $ */
/*
@@ -65,6 +65,8 @@
*/
struct intrhand *intrlev[MAXINTNUM];
+#define INTR_DEVINO 0x8000
+
void strayintr(const struct trapframe64 *, int);
int softintr(void *);
int intr_handler(struct trapframe64 *, struct intrhand *);
@@ -206,25 +208,22 @@ intr_establish(int level, struct intrhand *ih)
else
ih->ih_ack = NULL;
+ if (strlen(ih->ih_name) == 0)
+ evcount_attach(&ih->ih_count, "unknown", NULL);
+ else
+ evcount_attach(&ih->ih_count, ih->ih_name, NULL);
+
+ if (ih->ih_number & INTR_DEVINO) {
+ splx(s);
+ return;
+ }
+
/*
* Store in fast lookup table
*/
-#ifdef NOT_DEBUG
- if (!ih->ih_number) {
- printf("\nintr_establish: NULL vector fun %p arg %p pil %p",
- ih->ih_fun, ih->ih_arg, ih->ih_number, ih->ih_pil);
- db_enter();
- }
-#endif
-
if (ih->ih_number <= 0 || ih->ih_number >= MAXINTNUM)
panic("intr_establish: bad intr number %x", ih->ih_number);
- if (strlen(ih->ih_name) == 0)
- evcount_attach(&ih->ih_count, "unknown", NULL);
- else
- evcount_attach(&ih->ih_count, ih->ih_name, NULL);
-
q = intrlev[ih->ih_number];
if (q == NULL) {
/* No interrupt already there, just put handler in place. */
@@ -396,7 +395,8 @@ sun4v_intr_devino_to_sysino(uint64_t devhandle, uint64_t devino, uint64_t *ino)
if (sun4v_group_interrupt_major < 3)
return hv_intr_devino_to_sysino(devhandle, devino, ino);
- *ino = devino;
+ KASSERT(INTVEC(devino) == devino);
+ *ino = devino | INTR_DEVINO;
return H_EOK;
}