Don't write a 1 to the RIRR bit in the IOAPIC redirection register. This bit
authormlarkin <mlarkin@openbsd.org>
Wed, 29 Jun 2016 06:05:15 +0000 (06:05 +0000)
committermlarkin <mlarkin@openbsd.org>
Wed, 29 Jun 2016 06:05:15 +0000 (06:05 +0000)
is R/O, and although it should not matter what value is written there,
Hyper-V's emulated IOAPIC interprets a write of 1 in some unexpected way and
subsequently blocks interrupt delivery. This primarily manifests itself as
de(4) timeouts when using Hyper-V VMs with the "Legacy Network Adapter"
interface.

This diff has been in snaps for almost a month with no reported fallout.

Based on an idea originally from mikeb with further input from kettenis and
deraadt.

sys/arch/amd64/amd64/ioapic.c
sys/arch/amd64/include/i82093reg.h

index 14c3e13..85df17f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ioapic.c,v 1.24 2016/05/07 14:19:50 kettenis Exp $    */
+/*     $OpenBSD: ioapic.c,v 1.25 2016/06/29 06:05:15 mlarkin Exp $     */
 /*     $NetBSD: ioapic.c,v 1.6 2003/05/15 13:30:31 fvdl Exp $  */
 
 /*-
@@ -492,6 +492,7 @@ ioapic_hwmask(struct pic *pic, int pin)
        flags = ioapic_lock(sc);
        redlo = ioapic_read_ul(sc, IOAPIC_REDLO(pin));
        redlo |= IOAPIC_REDLO_MASK;
+       redlo &= ~IOAPIC_REDLO_RIRR;
        ioapic_write_ul(sc, IOAPIC_REDLO(pin), redlo);
        ioapic_unlock(sc, flags);
 }
@@ -508,6 +509,7 @@ ioapic_hwunmask(struct pic *pic, int pin)
        flags = ioapic_lock(sc);
        redlo = ioapic_read_ul(sc, IOAPIC_REDLO(pin));
        redlo &= ~IOAPIC_REDLO_MASK;
+       redlo &= ~IOAPIC_REDLO_RIRR;
        ioapic_write_ul(sc, IOAPIC_REDLO(pin), redlo);
        ioapic_unlock(sc, flags);
 }
index c6a7b11..e1fcfc9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: i82093reg.h,v 1.5 2015/04/19 19:45:21 sf Exp $        */
+/*     $OpenBSD: i82093reg.h,v 1.6 2016/06/29 06:05:15 mlarkin Exp $   */
 /*     $NetBSD: i82093reg.h,v 1.1 2003/02/26 21:26:10 fvdl Exp $ */
 
 /*-
        movq    IOAPIC_SC_DATA(%rdi),%r15                       ;\
        movl    (%r15),%esi                                     ;\
        orl     $IOAPIC_REDLO_MASK,%esi                         ;\
+       andl    $~IOAPIC_REDLO_RIRR,%esi                        ;\
        movl    %esi,(%r15)                                     ;\
        ioapic_asm_unlock(num)
 
        movl    %esi, (%r15)                                    ;\
        movl    (%r13),%r12d                                    ;\
        andl    $~IOAPIC_REDLO_MASK,%r12d                       ;\
+       andl    $~IOAPIC_REDLO_RIRR,%r12d                       ;\
        movl    %esi,(%r15)                                     ;\
        movl    %r12d,(%r13)                                    ;\
        ioapic_asm_unlock(num)                                  ;\