kvm: x86: ignore ioapic polarity
authorGabriel L. Somlo <gsomlo@gmail.com>
Fri, 28 Feb 2014 04:06:17 +0000 (23:06 -0500)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 13 Mar 2014 10:58:21 +0000 (11:58 +0100)
Both QEMU and KVM have already accumulated a significant number of
optimizations based on the hard-coded assumption that ioapic polarity
will always use the ActiveHigh convention, where the logical and
physical states of level-triggered irq lines always match (i.e.,
active(asserted) == high == 1, inactive == low == 0). QEMU guests
are expected to follow directions given via ACPI and configure the
ioapic with polarity 0 (ActiveHigh). However, even when misbehaving
guests (e.g. OS X <= 10.9) set the ioapic polarity to 1 (ActiveLow),
QEMU will still use the ActiveHigh signaling convention when
interfacing with KVM.

This patch modifies KVM to completely ignore ioapic polarity as set by
the guest OS, enabling misbehaving guests to work alongside those which
comply with the ActiveHigh polarity specified by QEMU's ACPI tables.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Gabriel L. Somlo <somlo@cmu.edu>
[Move documentation to KVM_IRQ_LINE, add ia64. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Documentation/virtual/kvm/api.txt
arch/ia64/kvm/kvm-ia64.c
arch/x86/kvm/x86.c
include/uapi/linux/kvm.h
virt/kvm/ioapic.c

index 6cd63a9010fbbfd7f011a9f3085a7b688da29fba..4714f282a43e1425347bfa7914292f522a155521 100644 (file)
@@ -612,6 +612,20 @@ On some architectures it is required that an interrupt controller model has
 been previously created with KVM_CREATE_IRQCHIP.  Note that edge-triggered
 interrupts require the level to be set to 1 and then back to 0.
 
+On real hardware, interrupt pins can be active-low or active-high.  This
+does not matter for the level field of struct kvm_irq_level: 1 always
+means active (asserted), 0 means inactive (deasserted).
+
+x86 allows the operating system to program the interrupt polarity
+(active-low/active-high) for level-triggered interrupts, and KVM used
+to consider the polarity.  However, due to bitrot in the handling of
+active-low interrupts, the above convention is now valid on x86 too.
+This is signaled by KVM_CAP_X86_IOAPIC_POLARITY_IGNORED.  Userspace
+should not present interrupts to the guest as active-low unless this
+capability is present (or unless it is not using the in-kernel irqchip,
+of course).
+
+
 ARM/arm64 can signal an interrupt either at the CPU level, or at the
 in-kernel irqchip (GIC), and for in-kernel irqchip can tell the GIC to
 use PPIs designated for specific cpus.  The irq field is interpreted
@@ -628,7 +642,7 @@ The irq_type field has the following values:
 
 (The irq_id field thus corresponds nicely to the IRQ ID in the ARM GIC specs)
 
-In both cases, level is used to raise/lower the line.
+In both cases, level is used to assert/deassert the line.
 
 struct kvm_irq_level {
        union {
index 53f44bee9ebb2cc1efcb4c46b0549b5cfd9a4a48..6a4309bb821af9882d5169eeacee8638e5376bbb 100644 (file)
@@ -199,6 +199,7 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_IRQCHIP:
        case KVM_CAP_MP_STATE:
        case KVM_CAP_IRQ_INJECT_STATUS:
+       case KVM_CAP_IOAPIC_POLARITY_IGNORED:
                r = 1;
                break;
        case KVM_CAP_COALESCED_MMIO:
index d906391a0a3f32e12ddc83db34424b1e7c43c4cf..a37da6b0165a28a0882137a496427fd733205de7 100644 (file)
@@ -2657,6 +2657,7 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_KVMCLOCK_CTRL:
        case KVM_CAP_READONLY_MEM:
        case KVM_CAP_HYPERV_TIME:
+       case KVM_CAP_IOAPIC_POLARITY_IGNORED:
 #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
        case KVM_CAP_ASSIGN_DEV_IRQ:
        case KVM_CAP_PCI_2_3:
index 7d76401d2bb57a629dd09eb073fce707db4dfb37..a7518be31d53472e42db924e102898fcde145fd3 100644 (file)
@@ -740,6 +740,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_SPAPR_MULTITCE 94
 #define KVM_CAP_EXT_EMUL_CPUID 95
 #define KVM_CAP_HYPERV_TIME 96
+#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index ce9ed99ad7dcde1bd513161bebf741c6c417f83c..1539d3757a047b17eb976fb1a10dcad2bbda86d1 100644 (file)
@@ -328,7 +328,6 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id,
        irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq],
                                         irq_source_id, level);
        entry = ioapic->redirtbl[irq];
-       irq_level ^= entry.fields.polarity;
        if (!irq_level) {
                ioapic->irr &= ~mask;
                ret = 1;