If we use the cookie-based interrupt API on sun4v, whe shouldn't put the
authorkettenis <kettenis@openbsd.org>
Fri, 22 Dec 2017 15:52:36 +0000 (15:52 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 22 Dec 2017 15:52:36 +0000 (15:52 +0000)
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.

sys/arch/sparc64/dev/vbus.c
sys/arch/sparc64/dev/vpci.c
sys/arch/sparc64/sparc64/intr.c

index 85260dd..1189459 100644 (file)
@@ -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
index 3a1a7a0..70af99a 100644 (file)
@@ -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
index 193e734..6321d3c 100644 (file)
@@ -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;
 }