Skip to content

Commit

Permalink
6062 Workaround broken KVM handling of directed EOIs
Browse files Browse the repository at this point in the history
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Approved by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
  • Loading branch information
Dan McDonald committed Jul 20, 2015
1 parent a2cdcdd commit 3f745f4
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions usr/src/uts/i86pc/io/pcplusmp/apic_regops.c
Expand Up @@ -24,6 +24,7 @@
*/
/*
* Copyright 2014 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
* Copyright (c) 2014 by Delphix. All rights reserved.
*/

#include <sys/cpuvar.h>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 3f745f4

Please sign in to comment.