summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2015-07-21 11:58:01 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2015-07-21 11:58:01 +0000
commitf3759e7dcd7928cd30f27fbaf234cbd59d996aef (patch)
treec12249addbd915f8044aace58fe5221b21c479a7
parentc8e7811bddeb1096b890998f058e01410a02335b (diff)
parent3f745f41d6d087602fbb2f748e1baabc3768f5fb (diff)
downloadillumos-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.c39
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);