[PATCH] FC11: fix rh#491625 (Unable to run RHEL-5 Xen within KVM guest)
Marcelo Tosatti
mtosatti at redhat.com
Wed Apr 8 22:00:15 UTC 2009
Following adds a fix for $subject. Please review.
Don't have commit access yet so unable to commit myself.
TODO | 7 +
kernel.spec | 15 +++
linux-2.6-kvm-kconfig-irqchip.patch | 69 ++++++++++++++++
linux-2.6-kvm-mask-notifiers.patch | 117 ++++++++++++++++++++++++++++
linux-2.6-kvm-reset-pit-irq-on-unmask.patch | 67 ++++++++++++++++
5 files changed, 275 insertions(+)
-------------- next part --------------
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 <mtosatti at redhat.com>
+- 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 <davej at redhat.com> 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 <avi at redhat.com>
+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 <avi at redhat.com>
+
+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 <avi at redhat.com>
+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 <avi at redhat.com>
+
+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
More information about the Fedora-kernel-list
mailing list