@@ -144,6 +144,15 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
}
}
+static int ioapic_dest_multiple_cpus(struct kvm_lapic_irq *irqe)
+{
+ /* physical mode is always directed to 1 cpu */
+ if (irqe->dest_mode == 0 || irqe->dest_id == 0)
+ return 0;
+
+ return hweight_long(irqe->dest_id) != 1;
+}
+
static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
{
union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];
@@ -164,8 +173,10 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
irqe.shorthand = 0;
#ifdef CONFIG_X86
- /* Always deliver PIT interrupt to vcpu 0 */
- if (irq == 0) {
+ /* if this is the PIT interrupt and the dest_id is multiple
+ * vcpus, re-write to go to vcpu 0
+ */
+ if (irq == 0 && ioapic_dest_multiple_cpus(&irqe)) {
irqe.dest_mode = 0; /* Physical mode. */
/* need to read apic_id from apic register since
* it can be rewritten */