diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2015-07-21 11:58:01 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2015-07-21 11:58:01 +0000 |
commit | f3759e7dcd7928cd30f27fbaf234cbd59d996aef (patch) | |
tree | c12249addbd915f8044aace58fe5221b21c479a7 | |
parent | c8e7811bddeb1096b890998f058e01410a02335b (diff) | |
parent | 3f745f41d6d087602fbb2f748e1baabc3768f5fb (diff) | |
download | illumos-joyent-f3759e7dcd7928cd30f27fbaf234cbd59d996aef.tar.gz |
[illumos-gate merge]
commit 3f745f41d6d087602fbb2f748e1baabc3768f5fb
6062 Workaround broken KVM handling of directed EOIs
-rw-r--r-- | usr/src/uts/i86pc/io/pcplusmp/apic_regops.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/usr/src/uts/i86pc/io/pcplusmp/apic_regops.c b/usr/src/uts/i86pc/io/pcplusmp/apic_regops.c index eba22ca090..60ce7a3771 100644 --- a/usr/src/uts/i86pc/io/pcplusmp/apic_regops.c +++ b/usr/src/uts/i86pc/io/pcplusmp/apic_regops.c @@ -24,6 +24,7 @@ */ /* * Copyright 2014 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright (c) 2014 by Delphix. All rights reserved. */ #include <sys/cpuvar.h> @@ -66,6 +67,9 @@ static void local_x2apic_write_int_cmd(uint32_t cpu_id, uint32_t cmd1); int x2apic_enable = 1; apic_mode_t apic_mode = LOCAL_APIC; /* Default mode is Local APIC */ +/* See apic_directed_EOI_supported(). Currently 3-state variable. */ +volatile int apic_directed_eoi_state = 2; + /* Uses MMIO (Memory Mapped IO) */ static apic_reg_ops_t local_apic_regs_ops = { local_apic_read, @@ -294,6 +298,41 @@ apic_directed_EOI_supported() { uint32_t ver; + /* + * There are some known issues with some versions of Linux KVM and QEMU + * where by directed EOIs do not properly function and instead get + * coalesced at the hypervisor, causing the host not to see interrupts. + * Thus, when the platform is KVM, we would like to disable it by + * default, but keep it available otherwise. + * + * We use a three-state variable (apic_directed_eoi_state) to determine + * how we handle directed EOI. + * + * 0 --> Don't do directed EOI at all. + * 1 --> Do directed EOI if available, no matter the HW environment. + * 2 --> Don't do directed EOI on KVM, but do it otherwise if available. + * + * If some grinning weirdo put something else in there, treat it as '2' + * (i.e. the current default). + * + * Note, at this time illumos KVM does not identify as KVM. If it does, + * we'll need to do some work to determine if it should be caught by + * this or if it should show up as its own value of platform_type. + */ + switch (apic_directed_eoi_state) { + case 0: + /* Don't do it at all. */ + return (0); + case 1: + break; + case 2: + default: + /* Only do it if we aren't on KVM. */ + if (get_hwenv() == HW_KVM) + return (0); + /* FALLTHRU */ + } + ver = apic_reg_ops->apic_read(APIC_VERS_REG); if (ver & APIC_DIRECTED_EOI_BIT) return (1); |