[kernel] r15572 - in dists/sid/linux-2.6/debian: . patches/features/all patches/series
Maximilian Attems
maks at alioth.debian.org
Tue Apr 27 16:36:44 UTC 2010
Author: maks
Date: Tue Apr 27 16:36:34 2010
New Revision: 15572
Log:
backport KVM: x86: Add KVM_GET/SET_VCPU_EVENTS
is said to help with troubles on vmsave/restore.
Added:
dists/sid/linux-2.6/debian/patches/features/all/KVM-x86-Add-KVM_GET-SET_VCPU_EVENTS.patch
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/12
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog Tue Apr 27 16:36:15 2010 (r15571)
+++ dists/sid/linux-2.6/debian/changelog Tue Apr 27 16:36:34 2010 (r15572)
@@ -51,6 +51,7 @@
* net: export device speed and duplex via sysfs.
* postrm: rm modules.softdep. (closes: #579175)
* Backport KVM: Xen PV-on-HVM guest support.
+ * Backport KVM: x86: Add KVM_GET/SET_VCPU_EVENTS. (closes: #578005)
[ dann frazier ]
* Add DRBD backport
Added: dists/sid/linux-2.6/debian/patches/features/all/KVM-x86-Add-KVM_GET-SET_VCPU_EVENTS.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/KVM-x86-Add-KVM_GET-SET_VCPU_EVENTS.patch Tue Apr 27 16:36:34 2010 (r15572)
@@ -0,0 +1,359 @@
+From 3cfc3092f40bc37c57ba556cfd8de4218f2135ab Mon Sep 17 00:00:00 2001
+From: Jan Kiszka <jan.kiszka at web.de>
+Date: Thu, 12 Nov 2009 01:04:25 +0100
+Subject: [PATCH] KVM: x86: Add KVM_GET/SET_VCPU_EVENTS
+
+This new IOCTL exports all yet user-invisible states related to
+exceptions, interrupts, and NMIs. Together with appropriate user space
+changes, this fixes sporadic problems of vmsave/restore, live migration
+and system reset.
+
+[avi: future-proof abi by adding a flags field]
+
+Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
+Signed-off-by: Avi Kivity <avi at redhat.com>
+---
+ Documentation/kvm/api.txt | 49 +++++++++++++++++++++++++
+ arch/x86/include/asm/kvm.h | 28 ++++++++++++++
+ arch/x86/include/asm/kvm_host.h | 2 +
+ arch/x86/kvm/svm.c | 22 +++++++++++
+ arch/x86/kvm/vmx.c | 30 +++++++++++++++
+ arch/x86/kvm/x86.c | 77 +++++++++++++++++++++++++++++++++++++++
+ include/linux/kvm.h | 6 +++
+ 7 files changed, 214 insertions(+), 0 deletions(-)
+
+diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
+index 36594ba..e1a1141 100644
+--- a/Documentation/kvm/api.txt
++++ b/Documentation/kvm/api.txt
+@@ -653,6 +653,55 @@ struct kvm_clock_data {
+ __u32 pad[9];
+ };
+
++4.29 KVM_GET_VCPU_EVENTS
++
++Capability: KVM_CAP_VCPU_EVENTS
++Architectures: x86
++Type: vm ioctl
++Parameters: struct kvm_vcpu_event (out)
++Returns: 0 on success, -1 on error
++
++Gets currently pending exceptions, interrupts, and NMIs as well as related
++states of the vcpu.
++
++struct kvm_vcpu_events {
++ struct {
++ __u8 injected;
++ __u8 nr;
++ __u8 has_error_code;
++ __u8 pad;
++ __u32 error_code;
++ } exception;
++ struct {
++ __u8 injected;
++ __u8 nr;
++ __u8 soft;
++ __u8 pad;
++ } interrupt;
++ struct {
++ __u8 injected;
++ __u8 pending;
++ __u8 masked;
++ __u8 pad;
++ } nmi;
++ __u32 sipi_vector;
++ __u32 flags; /* must be zero */
++};
++
++4.30 KVM_SET_VCPU_EVENTS
++
++Capability: KVM_CAP_VCPU_EVENTS
++Architectures: x86
++Type: vm ioctl
++Parameters: struct kvm_vcpu_event (in)
++Returns: 0 on success, -1 on error
++
++Set pending exceptions, interrupts, and NMIs as well as related states of the
++vcpu.
++
++See KVM_GET_VCPU_EVENTS for the data structure.
++
++
+ 5. The kvm_run structure
+
+ Application code obtains a pointer to the kvm_run structure by
+diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
+index ef9b4b7..950df43 100644
+--- a/arch/x86/include/asm/kvm.h
++++ b/arch/x86/include/asm/kvm.h
+@@ -20,6 +20,7 @@
+ #define __KVM_HAVE_MCE
+ #define __KVM_HAVE_PIT_STATE2
+ #define __KVM_HAVE_XEN_HVM
++#define __KVM_HAVE_VCPU_EVENTS
+
+ /* Architectural interrupt line count. */
+ #define KVM_NR_INTERRUPTS 256
+@@ -252,4 +253,31 @@ struct kvm_reinject_control {
+ __u8 pit_reinject;
+ __u8 reserved[31];
+ };
++
++/* for KVM_GET/SET_VCPU_EVENTS */
++struct kvm_vcpu_events {
++ struct {
++ __u8 injected;
++ __u8 nr;
++ __u8 has_error_code;
++ __u8 pad;
++ __u32 error_code;
++ } exception;
++ struct {
++ __u8 injected;
++ __u8 nr;
++ __u8 soft;
++ __u8 pad;
++ } interrupt;
++ struct {
++ __u8 injected;
++ __u8 pending;
++ __u8 masked;
++ __u8 pad;
++ } nmi;
++ __u32 sipi_vector;
++ __u32 flags;
++ __u32 reserved[10];
++};
++
+ #endif /* _ASM_X86_KVM_H */
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index 26a74b7..06e0856 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -523,6 +523,8 @@ struct kvm_x86_ops {
+ bool has_error_code, u32 error_code);
+ int (*interrupt_allowed)(struct kvm_vcpu *vcpu);
+ int (*nmi_allowed)(struct kvm_vcpu *vcpu);
++ bool (*get_nmi_mask)(struct kvm_vcpu *vcpu);
++ void (*set_nmi_mask)(struct kvm_vcpu *vcpu, bool masked);
+ void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
+ void (*enable_irq_window)(struct kvm_vcpu *vcpu);
+ void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index 34b700f..3de0b37 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -2499,6 +2499,26 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
+ !(svm->vcpu.arch.hflags & HF_NMI_MASK);
+ }
+
++static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
++{
++ struct vcpu_svm *svm = to_svm(vcpu);
++
++ return !!(svm->vcpu.arch.hflags & HF_NMI_MASK);
++}
++
++static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
++{
++ struct vcpu_svm *svm = to_svm(vcpu);
++
++ if (masked) {
++ svm->vcpu.arch.hflags |= HF_NMI_MASK;
++ svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
++ } else {
++ svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
++ svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
++ }
++}
++
+ static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+@@ -2946,6 +2966,8 @@ static struct kvm_x86_ops svm_x86_ops = {
+ .queue_exception = svm_queue_exception,
+ .interrupt_allowed = svm_interrupt_allowed,
+ .nmi_allowed = svm_nmi_allowed,
++ .get_nmi_mask = svm_get_nmi_mask,
++ .set_nmi_mask = svm_set_nmi_mask,
+ .enable_nmi_window = enable_nmi_window,
+ .enable_irq_window = enable_irq_window,
+ .update_cr8_intercept = update_cr8_intercept,
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 22fcd27..778f059 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -2639,6 +2639,34 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
+ GUEST_INTR_STATE_NMI));
+ }
+
++static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
++{
++ if (!cpu_has_virtual_nmis())
++ return to_vmx(vcpu)->soft_vnmi_blocked;
++ else
++ return !!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
++ GUEST_INTR_STATE_NMI);
++}
++
++static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
++{
++ struct vcpu_vmx *vmx = to_vmx(vcpu);
++
++ if (!cpu_has_virtual_nmis()) {
++ if (vmx->soft_vnmi_blocked != masked) {
++ vmx->soft_vnmi_blocked = masked;
++ vmx->vnmi_blocked_time = 0;
++ }
++ } else {
++ if (masked)
++ vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
++ GUEST_INTR_STATE_NMI);
++ else
++ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
++ GUEST_INTR_STATE_NMI);
++ }
++}
++
+ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
+ {
+ return (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
+@@ -3985,6 +4013,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
+ .queue_exception = vmx_queue_exception,
+ .interrupt_allowed = vmx_interrupt_allowed,
+ .nmi_allowed = vmx_nmi_allowed,
++ .get_nmi_mask = vmx_get_nmi_mask,
++ .set_nmi_mask = vmx_set_nmi_mask,
+ .enable_nmi_window = enable_nmi_window,
+ .enable_irq_window = enable_irq_window,
+ .update_cr8_intercept = update_cr8_intercept,
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index ba8958d..35eea30 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1342,6 +1342,7 @@ int kvm_dev_ioctl_check_extension(long ext)
+ case KVM_CAP_SET_IDENTITY_MAP_ADDR:
+ case KVM_CAP_ADJUST_CLOCK:
+ case KVM_CAP_XEN_HVM:
++ case KVM_CAP_VCPU_EVENTS:
+ r = 1;
+ break;
+ case KVM_CAP_COALESCED_MMIO:
+@@ -1883,6 +1884,61 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
+ return 0;
+ }
+
++static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
++ struct kvm_vcpu_events *events)
++{
++ vcpu_load(vcpu);
++
++ events->exception.injected = vcpu->arch.exception.pending;
++ events->exception.nr = vcpu->arch.exception.nr;
++ events->exception.has_error_code = vcpu->arch.exception.has_error_code;
++ events->exception.error_code = vcpu->arch.exception.error_code;
++
++ events->interrupt.injected = vcpu->arch.interrupt.pending;
++ events->interrupt.nr = vcpu->arch.interrupt.nr;
++ events->interrupt.soft = vcpu->arch.interrupt.soft;
++
++ events->nmi.injected = vcpu->arch.nmi_injected;
++ events->nmi.pending = vcpu->arch.nmi_pending;
++ events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu);
++
++ events->sipi_vector = vcpu->arch.sipi_vector;
++
++ events->flags = 0;
++
++ vcpu_put(vcpu);
++}
++
++static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
++ struct kvm_vcpu_events *events)
++{
++ if (events->flags)
++ return -EINVAL;
++
++ vcpu_load(vcpu);
++
++ vcpu->arch.exception.pending = events->exception.injected;
++ vcpu->arch.exception.nr = events->exception.nr;
++ vcpu->arch.exception.has_error_code = events->exception.has_error_code;
++ vcpu->arch.exception.error_code = events->exception.error_code;
++
++ vcpu->arch.interrupt.pending = events->interrupt.injected;
++ vcpu->arch.interrupt.nr = events->interrupt.nr;
++ vcpu->arch.interrupt.soft = events->interrupt.soft;
++ if (vcpu->arch.interrupt.pending && irqchip_in_kernel(vcpu->kvm))
++ kvm_pic_clear_isr_ack(vcpu->kvm);
++
++ vcpu->arch.nmi_injected = events->nmi.injected;
++ vcpu->arch.nmi_pending = events->nmi.pending;
++ kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
++
++ vcpu->arch.sipi_vector = events->sipi_vector;
++
++ vcpu_put(vcpu);
++
++ return 0;
++}
++
+ long kvm_arch_vcpu_ioctl(struct file *filp,
+ unsigned int ioctl, unsigned long arg)
+ {
+@@ -2040,6 +2096,27 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
+ r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce);
+ break;
+ }
++ case KVM_GET_VCPU_EVENTS: {
++ struct kvm_vcpu_events events;
++
++ kvm_vcpu_ioctl_x86_get_vcpu_events(vcpu, &events);
++
++ r = -EFAULT;
++ if (copy_to_user(argp, &events, sizeof(struct kvm_vcpu_events)))
++ break;
++ r = 0;
++ break;
++ }
++ case KVM_SET_VCPU_EVENTS: {
++ struct kvm_vcpu_events events;
++
++ r = -EFAULT;
++ if (copy_from_user(&events, argp, sizeof(struct kvm_vcpu_events)))
++ break;
++
++ r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events);
++ break;
++ }
+ default:
+ r = -EINVAL;
+ }
+diff --git a/include/linux/kvm.h b/include/linux/kvm.h
+index 976f4d1..92045a9 100644
+--- a/include/linux/kvm.h
++++ b/include/linux/kvm.h
+@@ -489,6 +489,9 @@ struct kvm_ioeventfd {
+ #define KVM_CAP_XEN_HVM 38
+ #endif
+ #define KVM_CAP_ADJUST_CLOCK 39
++#ifdef __KVM_HAVE_VCPU_EVENTS
++#define KVM_CAP_VCPU_EVENTS 41
++#endif
+
+ #ifdef KVM_CAP_IRQ_ROUTING
+
+@@ -672,6 +675,9 @@ struct kvm_clock_data {
+ /* IA64 stack access */
+ #define KVM_IA64_VCPU_GET_STACK _IOR(KVMIO, 0x9a, void *)
+ #define KVM_IA64_VCPU_SET_STACK _IOW(KVMIO, 0x9b, void *)
++/* Available with KVM_CAP_VCPU_EVENTS */
++#define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events)
++#define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events)
+
+ #define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2)
+ #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2)
+
+--
+1.6.5
+
Modified: dists/sid/linux-2.6/debian/patches/series/12
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/12 Tue Apr 27 16:36:15 2010 (r15571)
+++ dists/sid/linux-2.6/debian/patches/series/12 Tue Apr 27 16:36:34 2010 (r15572)
@@ -50,3 +50,4 @@
+ bugfix/all/p54pci-fix-regression.patch
+ features/all/net-export-device-speed-and-duplex-via-sysfs.patch
+ features/all/KVM-Xen-PV-on-HVM-guest-support.patch
++ features/all/KVM-x86-Add-KVM_GET-SET_VCPU_EVENTS.patch
More information about the Kernel-svn-changes
mailing list