diff options
author | Glauber Costa <glommer@redhat.com> | 2009-05-12 16:21:05 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:54 -0400 |
commit | 2809f5d2c4cfad171167b131bb2a21ab65eba40f (patch) | |
tree | eee772c1476fb05ababf306d6458f4ccd8b8412a /arch/x86/kvm/vmx.c | |
parent | 547de29e5b1662deb05b5f90917902dc0e9ac182 (diff) |
KVM: Replace ->drop_interrupt_shadow() by ->set_interrupt_shadow()
This patch replaces drop_interrupt_shadow with the more
general set_interrupt_shadow, that can either drop or raise
it, depending on its parameter. It also adds ->get_interrupt_shadow()
for future use.
Signed-off-by: Glauber Costa <glommer@redhat.com>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Gleb Natapov <gleb@redhat.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 | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e8a5649f9c15..f3ab27b5a6b2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -736,23 +736,45 @@ static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | |||
736 | vmcs_writel(GUEST_RFLAGS, rflags); | 736 | vmcs_writel(GUEST_RFLAGS, rflags); |
737 | } | 737 | } |
738 | 738 | ||
739 | static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | ||
740 | { | ||
741 | u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); | ||
742 | int ret = 0; | ||
743 | |||
744 | if (interruptibility & GUEST_INTR_STATE_STI) | ||
745 | ret |= X86_SHADOW_INT_STI; | ||
746 | if (interruptibility & GUEST_INTR_STATE_MOV_SS) | ||
747 | ret |= X86_SHADOW_INT_MOV_SS; | ||
748 | |||
749 | return ret & mask; | ||
750 | } | ||
751 | |||
752 | static void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | ||
753 | { | ||
754 | u32 interruptibility_old = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); | ||
755 | u32 interruptibility = interruptibility_old; | ||
756 | |||
757 | interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); | ||
758 | |||
759 | if (mask & X86_SHADOW_INT_MOV_SS) | ||
760 | interruptibility |= GUEST_INTR_STATE_MOV_SS; | ||
761 | if (mask & X86_SHADOW_INT_STI) | ||
762 | interruptibility |= GUEST_INTR_STATE_STI; | ||
763 | |||
764 | if ((interruptibility != interruptibility_old)) | ||
765 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, interruptibility); | ||
766 | } | ||
767 | |||
739 | static void skip_emulated_instruction(struct kvm_vcpu *vcpu) | 768 | static void skip_emulated_instruction(struct kvm_vcpu *vcpu) |
740 | { | 769 | { |
741 | unsigned long rip; | 770 | unsigned long rip; |
742 | u32 interruptibility; | ||
743 | 771 | ||
744 | rip = kvm_rip_read(vcpu); | 772 | rip = kvm_rip_read(vcpu); |
745 | rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN); | 773 | rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN); |
746 | kvm_rip_write(vcpu, rip); | 774 | kvm_rip_write(vcpu, rip); |
747 | 775 | ||
748 | /* | 776 | /* skipping an emulated instruction also counts */ |
749 | * We emulated an instruction, so temporary interrupt blocking | 777 | vmx_set_interrupt_shadow(vcpu, 0); |
750 | * should be removed, if set. | ||
751 | */ | ||
752 | interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); | ||
753 | if (interruptibility & 3) | ||
754 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, | ||
755 | interruptibility & ~3); | ||
756 | } | 778 | } |
757 | 779 | ||
758 | static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | 780 | static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, |
@@ -2400,12 +2422,6 @@ out: | |||
2400 | return ret; | 2422 | return ret; |
2401 | } | 2423 | } |
2402 | 2424 | ||
2403 | void vmx_drop_interrupt_shadow(struct kvm_vcpu *vcpu) | ||
2404 | { | ||
2405 | vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO, | ||
2406 | GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); | ||
2407 | } | ||
2408 | |||
2409 | static void enable_irq_window(struct kvm_vcpu *vcpu) | 2425 | static void enable_irq_window(struct kvm_vcpu *vcpu) |
2410 | { | 2426 | { |
2411 | u32 cpu_based_vm_exec_control; | 2427 | u32 cpu_based_vm_exec_control; |
@@ -3649,6 +3665,8 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
3649 | .run = vmx_vcpu_run, | 3665 | .run = vmx_vcpu_run, |
3650 | .handle_exit = vmx_handle_exit, | 3666 | .handle_exit = vmx_handle_exit, |
3651 | .skip_emulated_instruction = skip_emulated_instruction, | 3667 | .skip_emulated_instruction = skip_emulated_instruction, |
3668 | .set_interrupt_shadow = vmx_set_interrupt_shadow, | ||
3669 | .get_interrupt_shadow = vmx_get_interrupt_shadow, | ||
3652 | .patch_hypercall = vmx_patch_hypercall, | 3670 | .patch_hypercall = vmx_patch_hypercall, |
3653 | .set_irq = vmx_inject_irq, | 3671 | .set_irq = vmx_inject_irq, |
3654 | .set_nmi = vmx_inject_nmi, | 3672 | .set_nmi = vmx_inject_nmi, |
@@ -3658,7 +3676,6 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
3658 | .enable_nmi_window = enable_nmi_window, | 3676 | .enable_nmi_window = enable_nmi_window, |
3659 | .enable_irq_window = enable_irq_window, | 3677 | .enable_irq_window = enable_irq_window, |
3660 | .update_cr8_intercept = update_cr8_intercept, | 3678 | .update_cr8_intercept = update_cr8_intercept, |
3661 | .drop_interrupt_shadow = vmx_drop_interrupt_shadow, | ||
3662 | 3679 | ||
3663 | .set_tss_addr = vmx_set_tss_addr, | 3680 | .set_tss_addr = vmx_set_tss_addr, |
3664 | .get_tdp_level = get_ept_level, | 3681 | .get_tdp_level = get_ept_level, |