From: kettenis Date: Fri, 22 Dec 2017 15:52:36 +0000 (+0000) Subject: If we use the cookie-based interrupt API on sun4v, whe shouldn't put the X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=45460660750088909e85a488017bcbc72cbbf0b0;p=openbsd 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. --- 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 * @@ -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; }