diff options
author | Jan Kiszka <jan.kiszka@web.de> | 2009-11-11 19:04:25 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-12-03 02:32:25 -0500 |
commit | 3cfc3092f40bc37c57ba556cfd8de4218f2135ab (patch) | |
tree | 562d61febfe7d3c99ea08e376b3f3c016cff613c /arch/x86/kvm/vmx.c | |
parent | 65ac7264043740572ba804edca03c374d70427c9 (diff) |
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@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 22fcd27a0b58..778f059ae423 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) | |||
2639 | GUEST_INTR_STATE_NMI)); | 2639 | GUEST_INTR_STATE_NMI)); |
2640 | } | 2640 | } |
2641 | 2641 | ||
2642 | static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu) | ||
2643 | { | ||
2644 | if (!cpu_has_virtual_nmis()) | ||
2645 | return to_vmx(vcpu)->soft_vnmi_blocked; | ||
2646 | else | ||
2647 | return !!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & | ||
2648 | GUEST_INTR_STATE_NMI); | ||
2649 | } | ||
2650 | |||
2651 | static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked) | ||
2652 | { | ||
2653 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
2654 | |||
2655 | if (!cpu_has_virtual_nmis()) { | ||
2656 | if (vmx->soft_vnmi_blocked != masked) { | ||
2657 | vmx->soft_vnmi_blocked = masked; | ||
2658 | vmx->vnmi_blocked_time = 0; | ||
2659 | } | ||
2660 | } else { | ||
2661 | if (masked) | ||
2662 | vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO, | ||
2663 | GUEST_INTR_STATE_NMI); | ||
2664 | else | ||
2665 | vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO, | ||
2666 | GUEST_INTR_STATE_NMI); | ||
2667 | } | ||
2668 | } | ||
2669 | |||
2642 | static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu) | 2670 | static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu) |
2643 | { | 2671 | { |
2644 | return (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) && | 2672 | return (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) && |
@@ -3985,6 +4013,8 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
3985 | .queue_exception = vmx_queue_exception, | 4013 | .queue_exception = vmx_queue_exception, |
3986 | .interrupt_allowed = vmx_interrupt_allowed, | 4014 | .interrupt_allowed = vmx_interrupt_allowed, |
3987 | .nmi_allowed = vmx_nmi_allowed, | 4015 | .nmi_allowed = vmx_nmi_allowed, |
4016 | .get_nmi_mask = vmx_get_nmi_mask, | ||
4017 | .set_nmi_mask = vmx_set_nmi_mask, | ||
3988 | .enable_nmi_window = enable_nmi_window, | 4018 | .enable_nmi_window = enable_nmi_window, |
3989 | .enable_irq_window = enable_irq_window, | 4019 | .enable_irq_window = enable_irq_window, |
3990 | .update_cr8_intercept = update_cr8_intercept, | 4020 | .update_cr8_intercept = update_cr8_intercept, |