aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGlauber Costa <glommer@redhat.com>2009-05-12 16:21:05 -0400
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:54 -0400
commit2809f5d2c4cfad171167b131bb2a21ab65eba40f (patch)
treeeee772c1476fb05ababf306d6458f4ccd8b8412a /arch
parent547de29e5b1662deb05b5f90917902dc0e9ac182 (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')
-rw-r--r--arch/x86/include/asm/kvm_host.h3
-rw-r--r--arch/x86/include/asm/kvm_x86_emulate.h3
-rw-r--r--arch/x86/kvm/svm.c32
-rw-r--r--arch/x86/kvm/vmx.c49
-rw-r--r--arch/x86/kvm/x86.c2
5 files changed, 63 insertions, 26 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index ab7de4a11955..16d1481aa231 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -508,6 +508,8 @@ struct kvm_x86_ops {
508 void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run); 508 void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run);
509 int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu); 509 int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
510 void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); 510 void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
511 void (*set_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
512 u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
511 void (*patch_hypercall)(struct kvm_vcpu *vcpu, 513 void (*patch_hypercall)(struct kvm_vcpu *vcpu,
512 unsigned char *hypercall_addr); 514 unsigned char *hypercall_addr);
513 void (*set_irq)(struct kvm_vcpu *vcpu, int vec); 515 void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
@@ -519,7 +521,6 @@ struct kvm_x86_ops {
519 void (*enable_nmi_window)(struct kvm_vcpu *vcpu); 521 void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
520 void (*enable_irq_window)(struct kvm_vcpu *vcpu); 522 void (*enable_irq_window)(struct kvm_vcpu *vcpu);
521 void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr); 523 void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
522 void (*drop_interrupt_shadow)(struct kvm_vcpu *vcpu);
523 int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); 524 int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
524 int (*get_tdp_level)(void); 525 int (*get_tdp_level)(void);
525 u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); 526 u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
diff --git a/arch/x86/include/asm/kvm_x86_emulate.h b/arch/x86/include/asm/kvm_x86_emulate.h
index 6a159732881a..be40d6e2b6bb 100644
--- a/arch/x86/include/asm/kvm_x86_emulate.h
+++ b/arch/x86/include/asm/kvm_x86_emulate.h
@@ -143,6 +143,9 @@ struct decode_cache {
143 struct fetch_cache fetch; 143 struct fetch_cache fetch;
144}; 144};
145 145
146#define X86_SHADOW_INT_MOV_SS 1
147#define X86_SHADOW_INT_STI 2
148
146struct x86_emulate_ctxt { 149struct x86_emulate_ctxt {
147 /* Register state before/after emulation. */ 150 /* Register state before/after emulation. */
148 struct kvm_vcpu *vcpu; 151 struct kvm_vcpu *vcpu;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index f994c6df78be..8b5ffbd55c11 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -202,6 +202,27 @@ static int is_external_interrupt(u32 info)
202 return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR); 202 return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
203} 203}
204 204
205static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
206{
207 struct vcpu_svm *svm = to_svm(vcpu);
208 u32 ret = 0;
209
210 if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK)
211 ret |= X86_SHADOW_INT_STI | X86_SHADOW_INT_MOV_SS;
212 return ret & mask;
213}
214
215static void svm_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
216{
217 struct vcpu_svm *svm = to_svm(vcpu);
218
219 if (mask == 0)
220 svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
221 else
222 svm->vmcb->control.int_state |= SVM_INTERRUPT_SHADOW_MASK;
223
224}
225
205static void skip_emulated_instruction(struct kvm_vcpu *vcpu) 226static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
206{ 227{
207 struct vcpu_svm *svm = to_svm(vcpu); 228 struct vcpu_svm *svm = to_svm(vcpu);
@@ -215,7 +236,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
215 __func__, kvm_rip_read(vcpu), svm->next_rip); 236 __func__, kvm_rip_read(vcpu), svm->next_rip);
216 237
217 kvm_rip_write(vcpu, svm->next_rip); 238 kvm_rip_write(vcpu, svm->next_rip);
218 svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK; 239 svm_set_interrupt_shadow(vcpu, 0);
219} 240}
220 241
221static int has_svm(void) 242static int has_svm(void)
@@ -2259,12 +2280,6 @@ static void pre_svm_run(struct vcpu_svm *svm)
2259 new_asid(svm, svm_data); 2280 new_asid(svm, svm_data);
2260} 2281}
2261 2282
2262static void svm_drop_interrupt_shadow(struct kvm_vcpu *vcpu)
2263{
2264 struct vcpu_svm *svm = to_svm(vcpu);
2265 svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
2266}
2267
2268static void svm_inject_nmi(struct kvm_vcpu *vcpu) 2283static void svm_inject_nmi(struct kvm_vcpu *vcpu)
2269{ 2284{
2270 struct vcpu_svm *svm = to_svm(vcpu); 2285 struct vcpu_svm *svm = to_svm(vcpu);
@@ -2667,6 +2682,8 @@ static struct kvm_x86_ops svm_x86_ops = {
2667 .run = svm_vcpu_run, 2682 .run = svm_vcpu_run,
2668 .handle_exit = handle_exit, 2683 .handle_exit = handle_exit,
2669 .skip_emulated_instruction = skip_emulated_instruction, 2684 .skip_emulated_instruction = skip_emulated_instruction,
2685 .set_interrupt_shadow = svm_set_interrupt_shadow,
2686 .get_interrupt_shadow = svm_get_interrupt_shadow,
2670 .patch_hypercall = svm_patch_hypercall, 2687 .patch_hypercall = svm_patch_hypercall,
2671 .set_irq = svm_set_irq, 2688 .set_irq = svm_set_irq,
2672 .set_nmi = svm_inject_nmi, 2689 .set_nmi = svm_inject_nmi,
@@ -2676,7 +2693,6 @@ static struct kvm_x86_ops svm_x86_ops = {
2676 .enable_nmi_window = enable_nmi_window, 2693 .enable_nmi_window = enable_nmi_window,
2677 .enable_irq_window = enable_irq_window, 2694 .enable_irq_window = enable_irq_window,
2678 .update_cr8_intercept = update_cr8_intercept, 2695 .update_cr8_intercept = update_cr8_intercept,
2679 .drop_interrupt_shadow = svm_drop_interrupt_shadow,
2680 2696
2681 .set_tss_addr = svm_set_tss_addr, 2697 .set_tss_addr = svm_set_tss_addr,
2682 .get_tdp_level = get_npt_level, 2698 .get_tdp_level = get_npt_level,
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
739static 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
752static 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
739static void skip_emulated_instruction(struct kvm_vcpu *vcpu) 768static 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
758static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, 780static 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
2403void 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
2409static void enable_irq_window(struct kvm_vcpu *vcpu) 2425static 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,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3c4c327490af..7475b029b2ad 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3178,7 +3178,7 @@ static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3178 kvm_run->request_interrupt_window; 3178 kvm_run->request_interrupt_window;
3179 3179
3180 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) 3180 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
3181 kvm_x86_ops->drop_interrupt_shadow(vcpu); 3181 kvm_x86_ops->set_interrupt_shadow(vcpu, 0);
3182 3182
3183 inject_irq(vcpu); 3183 inject_irq(vcpu);
3184 3184