Index: F-11/TODO =================================================================== --- F-11.orig/TODO +++ F-11/TODO @@ -102,3 +102,10 @@ * linux-2.6.29-pat-fixes.patch: http://bugs.freedesktop.org/show_bug.cgi?id=20803 ajax to follow up with jbarnes + +* linux-2.6-kvm-kconfig-irqchip.patch +* linux-2.6-kvm-mask-notifiers.patch +* linux-2.6-kvm-reset-pit-irq-on-unmask.patch: + https://bugzilla.redhat.com/show_bug.cgi?id=491625 + Queued by Avi, needs to get into linux-2.6-stable. + Index: F-11/kernel.spec =================================================================== --- F-11.orig/kernel.spec +++ F-11/kernel.spec @@ -720,6 +720,11 @@ Patch9101: linux-2.6-net-fix-another-gro # http://bugs.freedesktop.org/show_bug.cgi?id=20803 Patch9210: linux-2.6.29-pat-fixes.patch +# kvm fixes +Patch9300: linux-2.6-kvm-kconfig-irqchip.patch +Patch9301: linux-2.6-kvm-mask-notifiers.patch +Patch9302: linux-2.6-kvm-reset-pit-irq-on-unmask.patch + %endif BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -1320,6 +1325,10 @@ ApplyPatch linux-2.6-net-fix-another-gro ApplyPatch linux-2.6.29-pat-fixes.patch +ApplyPatch linux-2.6-kvm-kconfig-irqchip.patch +ApplyPatch linux-2.6-kvm-mask-notifiers.patch +ApplyPatch linux-2.6-kvm-reset-pit-irq-on-unmask.patch + # END OF PATCH APPLICATIONS %endif @@ -1905,6 +1914,12 @@ fi # and build. %changelog +* Wed Apr 08 2009 Marcelo Tosatti +- linux-2.6-kvm-kconfig-irqchip.patch + linux-2.6-kvm-mask-notifiers.patch + linux-2.6-kvm-reset-pit-irq-on-unmask.patch: + Fixes PIT bug with Xen on KVM (rh#491625). + * Wed Apr 08 2009 Dave Jones 2.6.29.1-58 - disable MMIOTRACE in non-debug builds (#494584) Index: F-11/linux-2.6-kvm-mask-notifiers.patch =================================================================== --- /dev/null +++ F-11/linux-2.6-kvm-mask-notifiers.patch @@ -0,0 +1,117 @@ +b018d32632d3c59d3618e23128e4312fe8e48d64 +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index 3cf0ede..99963f3 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -127,6 +127,10 @@ struct kvm { + struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; + #endif + ++#ifdef CONFIG_HAVE_KVM_IRQCHIP ++ struct hlist_head mask_notifier_list; ++#endif ++ + #ifdef KVM_ARCH_WANT_MMU_NOTIFIER + struct mmu_notifier mmu_notifier; + unsigned long mmu_notifier_seq; +@@ -320,6 +324,19 @@ struct kvm_assigned_dev_kernel { + struct pci_dev *dev; + struct kvm *kvm; + }; ++ ++struct kvm_irq_mask_notifier { ++ void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked); ++ int irq; ++ struct hlist_node link; ++}; ++ ++void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, ++ struct kvm_irq_mask_notifier *kimn); ++void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, ++ struct kvm_irq_mask_notifier *kimn); ++void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask); ++ + void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level); + void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi); + void kvm_register_irq_ack_notifier(struct kvm *kvm, +diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c +index 23b81cf..e85a2bc 100644 +--- a/virt/kvm/ioapic.c ++++ b/virt/kvm/ioapic.c +@@ -101,6 +101,7 @@ static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) + static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) + { + unsigned index; ++ bool mask_before, mask_after; + + switch (ioapic->ioregsel) { + case IOAPIC_REG_VERSION: +@@ -120,6 +121,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) + ioapic_debug("change redir index %x val %x\n", index, val); + if (index >= IOAPIC_NUM_PINS) + return; ++ mask_before = ioapic->redirtbl[index].fields.mask; + if (ioapic->ioregsel & 1) { + ioapic->redirtbl[index].bits &= 0xffffffff; + ioapic->redirtbl[index].bits |= (u64) val << 32; +@@ -128,6 +130,9 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) + ioapic->redirtbl[index].bits |= (u32) val; + ioapic->redirtbl[index].fields.remote_irr = 0; + } ++ mask_after = ioapic->redirtbl[index].fields.mask; ++ if (mask_before != mask_after) ++ kvm_fire_mask_notifiers(ioapic->kvm, index, mask_after); + if (ioapic->irr & (1 << index)) + ioapic_service(ioapic, index); + break; +@@ -426,3 +431,4 @@ int kvm_ioapic_init(struct kvm *kvm) + kvm_io_bus_register_dev(&kvm->mmio_bus, &ioapic->dev); + return 0; + } ++ +diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c +index aa5d1e5..5162a41 100644 +--- a/virt/kvm/irq_comm.c ++++ b/virt/kvm/irq_comm.c +@@ -99,3 +99,27 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) + clear_bit(irq_source_id, &kvm->arch.irq_states[i]); + clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap); + } ++ ++void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, ++ struct kvm_irq_mask_notifier *kimn) ++{ ++ kimn->irq = irq; ++ hlist_add_head(&kimn->link, &kvm->mask_notifier_list); ++} ++ ++void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, ++ struct kvm_irq_mask_notifier *kimn) ++{ ++ hlist_del(&kimn->link); ++} ++ ++void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask) ++{ ++ struct kvm_irq_mask_notifier *kimn; ++ struct hlist_node *n; ++ ++ hlist_for_each_entry(kimn, n, &kvm->mask_notifier_list, link) ++ if (kimn->irq == irq) ++ kimn->func(kimn, mask); ++} ++ +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index dcbfc68..785c1e3 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -831,6 +831,9 @@ static struct kvm *kvm_create_vm(void) + + if (IS_ERR(kvm)) + goto out; ++#ifdef CONFIG_HAVE_KVM_IRQCHIP ++ INIT_HLIST_HEAD(&kvm->mask_notifier_list); ++#endif + + #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET + page = alloc_page(GFP_KERNEL | __GFP_ZERO); Index: F-11/linux-2.6-kvm-reset-pit-irq-on-unmask.patch =================================================================== --- /dev/null +++ F-11/linux-2.6-kvm-reset-pit-irq-on-unmask.patch @@ -0,0 +1,67 @@ +commit 4780c65904f0fc4e312ee2da9383eacbe04e61ea +Author: Avi Kivity +Date: Sun Jan 4 18:06:06 2009 +0200 + + KVM: Reset PIT irq injection logic when the PIT IRQ is unmasked + + While the PIT is masked the guest cannot ack the irq, so the reinject logic + will never allow the interrupt to be injected. + + Fix by resetting the reinjection counters on unmask. + + Unbreaks Xen. + + Signed-off-by: Avi Kivity + +diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c +index 69d1bbf..c13bb92 100644 +--- a/arch/x86/kvm/i8254.c ++++ b/arch/x86/kvm/i8254.c +@@ -539,6 +539,16 @@ void kvm_pit_reset(struct kvm_pit *pit) + pit->pit_state.irq_ack = 1; + } + ++static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask) ++{ ++ struct kvm_pit *pit = container_of(kimn, struct kvm_pit, mask_notifier); ++ ++ if (!mask) { ++ atomic_set(&pit->pit_state.pit_timer.pending, 0); ++ pit->pit_state.irq_ack = 1; ++ } ++} ++ + struct kvm_pit *kvm_create_pit(struct kvm *kvm) + { + struct kvm_pit *pit; +@@ -586,6 +596,9 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm) + + kvm_pit_reset(pit); + ++ pit->mask_notifier.func = pit_mask_notifer; ++ kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier); ++ + return pit; + } + +@@ -594,6 +607,8 @@ void kvm_free_pit(struct kvm *kvm) + struct hrtimer *timer; + + if (kvm->arch.vpit) { ++ kvm_unregister_irq_mask_notifier(kvm, 0, ++ &kvm->arch.vpit->mask_notifier); + mutex_lock(&kvm->arch.vpit->pit_state.lock); + timer = &kvm->arch.vpit->pit_state.pit_timer.timer; + hrtimer_cancel(timer); +diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h +index 76959c4..6acbe4b 100644 +--- a/arch/x86/kvm/i8254.h ++++ b/arch/x86/kvm/i8254.h +@@ -46,6 +46,7 @@ struct kvm_pit { + struct kvm *kvm; + struct kvm_kpit_state pit_state; + int irq_source_id; ++ struct kvm_irq_mask_notifier mask_notifier; + }; + + #define KVM_PIT_BASE_ADDRESS 0x40 Index: F-11/linux-2.6-kvm-kconfig-irqchip.patch =================================================================== --- /dev/null +++ F-11/linux-2.6-kvm-kconfig-irqchip.patch @@ -0,0 +1,69 @@ +commit 1dae8e15bb85de0116ed43cd3d798a035044954c +Author: Avi Kivity +Date: Sun Jan 4 18:04:18 2009 +0200 + + KVM: Add CONFIG_HAVE_KVM_IRQCHIP + + Two KVM archs support irqchips and two don't. Add a Kconfig item to + make selecting between the two models easier. + + Signed-off-by: Avi Kivity + +diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig +index f833a0b..0a2d6b8 100644 +--- a/arch/ia64/kvm/Kconfig ++++ b/arch/ia64/kvm/Kconfig +@@ -4,6 +4,10 @@ + config HAVE_KVM + bool + ++config HAVE_KVM_IRQCHIP ++ bool ++ default y ++ + menuconfig VIRTUALIZATION + bool "Virtualization" + depends on HAVE_KVM || IA64 +diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig +index 1465705..5a152a5 100644 +--- a/arch/powerpc/kvm/Kconfig ++++ b/arch/powerpc/kvm/Kconfig +@@ -2,6 +2,9 @@ + # KVM configuration + # + ++config HAVE_KVM_IRQCHIP ++ bool ++ + menuconfig VIRTUALIZATION + bool "Virtualization" + ---help--- +diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig +index e051cad..3e260b7 100644 +--- a/arch/s390/kvm/Kconfig ++++ b/arch/s390/kvm/Kconfig +@@ -4,6 +4,9 @@ + config HAVE_KVM + bool + ++config HAVE_KVM_IRQCHIP ++ bool ++ + menuconfig VIRTUALIZATION + bool "Virtualization" + default y +diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig +index b81125f..0a303c3 100644 +--- a/arch/x86/kvm/Kconfig ++++ b/arch/x86/kvm/Kconfig +@@ -4,6 +4,10 @@ + config HAVE_KVM + bool + ++config HAVE_KVM_IRQCHIP ++ bool ++ default y ++ + menuconfig VIRTUALIZATION + bool "Virtualization" + depends on HAVE_KVM || X86