All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org
Subject: [PATCH 24/45] KVM: Replace ->drop_interrupt_shadow() by ->set_interrupt_shadow()
Date: Sun, 24 May 2009 18:50:09 +0300	[thread overview]
Message-ID: <1243180230-2480-25-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1243180230-2480-1-git-send-email-avi@redhat.com>

From: Glauber Costa <glommer@redhat.com>

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>
---
 arch/x86/include/asm/kvm_host.h        |    3 +-
 arch/x86/include/asm/kvm_x86_emulate.h |    3 ++
 arch/x86/kvm/svm.c                     |   32 +++++++++++++++-----
 arch/x86/kvm/vmx.c                     |   49 +++++++++++++++++++++----------
 arch/x86/kvm/x86.c                     |    2 +-
 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 ab7de4a..16d1481 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 {
 	void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run);
 	int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
 	void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
+	void (*set_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
+	u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
 	void (*patch_hypercall)(struct kvm_vcpu *vcpu,
 				unsigned char *hypercall_addr);
 	void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
@@ -519,7 +521,6 @@ struct kvm_x86_ops {
 	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);
-	void (*drop_interrupt_shadow)(struct kvm_vcpu *vcpu);
 	int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
 	int (*get_tdp_level)(void);
 	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 6a15973..be40d6e 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 {
 	struct fetch_cache fetch;
 };
 
+#define X86_SHADOW_INT_MOV_SS  1
+#define X86_SHADOW_INT_STI     2
+
 struct x86_emulate_ctxt {
 	/* Register state before/after emulation. */
 	struct kvm_vcpu *vcpu;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index f994c6d..8b5ffbd 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -202,6 +202,27 @@ static int is_external_interrupt(u32 info)
 	return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
 }
 
+static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	u32 ret = 0;
+
+	if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK)
+		ret |= X86_SHADOW_INT_STI | X86_SHADOW_INT_MOV_SS;
+	return ret & mask;
+}
+
+static void svm_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	if (mask == 0)
+		svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
+	else
+		svm->vmcb->control.int_state |= SVM_INTERRUPT_SHADOW_MASK;
+
+}
+
 static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -215,7 +236,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
 		       __func__, kvm_rip_read(vcpu), svm->next_rip);
 
 	kvm_rip_write(vcpu, svm->next_rip);
-	svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
+	svm_set_interrupt_shadow(vcpu, 0);
 }
 
 static int has_svm(void)
@@ -2259,12 +2280,6 @@ static void pre_svm_run(struct vcpu_svm *svm)
 		new_asid(svm, svm_data);
 }
 
-static void svm_drop_interrupt_shadow(struct kvm_vcpu *vcpu)
-{
-	struct vcpu_svm *svm = to_svm(vcpu);
-	svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
-}
-
 static void svm_inject_nmi(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -2667,6 +2682,8 @@ static struct kvm_x86_ops svm_x86_ops = {
 	.run = svm_vcpu_run,
 	.handle_exit = handle_exit,
 	.skip_emulated_instruction = skip_emulated_instruction,
+	.set_interrupt_shadow = svm_set_interrupt_shadow,
+	.get_interrupt_shadow = svm_get_interrupt_shadow,
 	.patch_hypercall = svm_patch_hypercall,
 	.set_irq = svm_set_irq,
 	.set_nmi = svm_inject_nmi,
@@ -2676,7 +2693,6 @@ static struct kvm_x86_ops svm_x86_ops = {
 	.enable_nmi_window = enable_nmi_window,
 	.enable_irq_window = enable_irq_window,
 	.update_cr8_intercept = update_cr8_intercept,
-	.drop_interrupt_shadow = svm_drop_interrupt_shadow,
 
 	.set_tss_addr = svm_set_tss_addr,
 	.get_tdp_level = get_npt_level,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e8a5649..f3ab27b 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)
 	vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
+static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
+	int ret = 0;
+
+	if (interruptibility & GUEST_INTR_STATE_STI)
+		ret |= X86_SHADOW_INT_STI;
+	if (interruptibility & GUEST_INTR_STATE_MOV_SS)
+		ret |= X86_SHADOW_INT_MOV_SS;
+
+	return ret & mask;
+}
+
+static void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	u32 interruptibility_old = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
+	u32 interruptibility = interruptibility_old;
+
+	interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS);
+
+	if (mask & X86_SHADOW_INT_MOV_SS)
+		interruptibility |= GUEST_INTR_STATE_MOV_SS;
+	if (mask & X86_SHADOW_INT_STI)
+		interruptibility |= GUEST_INTR_STATE_STI;
+
+	if ((interruptibility != interruptibility_old))
+		vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, interruptibility);
+}
+
 static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
 {
 	unsigned long rip;
-	u32 interruptibility;
 
 	rip = kvm_rip_read(vcpu);
 	rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
 	kvm_rip_write(vcpu, rip);
 
-	/*
-	 * We emulated an instruction, so temporary interrupt blocking
-	 * should be removed, if set.
-	 */
-	interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
-	if (interruptibility & 3)
-		vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
-			     interruptibility & ~3);
+	/* skipping an emulated instruction also counts */
+	vmx_set_interrupt_shadow(vcpu, 0);
 }
 
 static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
@@ -2400,12 +2422,6 @@ out:
 	return ret;
 }
 
-void vmx_drop_interrupt_shadow(struct kvm_vcpu *vcpu)
-{
-	vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
-			GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS);
-}
-
 static void enable_irq_window(struct kvm_vcpu *vcpu)
 {
 	u32 cpu_based_vm_exec_control;
@@ -3649,6 +3665,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
 	.run = vmx_vcpu_run,
 	.handle_exit = vmx_handle_exit,
 	.skip_emulated_instruction = skip_emulated_instruction,
+	.set_interrupt_shadow = vmx_set_interrupt_shadow,
+	.get_interrupt_shadow = vmx_get_interrupt_shadow,
 	.patch_hypercall = vmx_patch_hypercall,
 	.set_irq = vmx_inject_irq,
 	.set_nmi = vmx_inject_nmi,
@@ -3658,7 +3676,6 @@ static struct kvm_x86_ops vmx_x86_ops = {
 	.enable_nmi_window = enable_nmi_window,
 	.enable_irq_window = enable_irq_window,
 	.update_cr8_intercept = update_cr8_intercept,
-	.drop_interrupt_shadow = vmx_drop_interrupt_shadow,
 
 	.set_tss_addr = vmx_set_tss_addr,
 	.get_tdp_level = get_ept_level,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fd0a571..c9b81ef 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3174,7 +3174,7 @@ static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		kvm_run->request_interrupt_window;
 
 	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-		kvm_x86_ops->drop_interrupt_shadow(vcpu);
+		kvm_x86_ops->set_interrupt_shadow(vcpu, 0);
 
 	inject_irq(vcpu);
 
-- 
1.6.0.6


  parent reply	other threads:[~2009-05-24 15:56 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-24 15:49 [PATCH 00/45] KVM updates for the 2.6.31 merge window (batch 3/3) Avi Kivity
2009-05-24 15:49 ` [PATCH 01/45] KVM: Remove inject_pending_vectors() callback Avi Kivity
2009-05-24 15:49 ` [PATCH 02/45] KVM: Remove kvm_push_irq() Avi Kivity
2009-05-24 15:49 ` [PATCH 03/45] KVM: sync_lapic_to_cr8() should always sync cr8 to V_TPR Avi Kivity
2009-05-24 15:49 ` [PATCH 04/45] KVM: Do not report TPR write to userspace if new value bigger or equal to a previous one Avi Kivity
2009-05-24 15:49 ` [PATCH 05/45] KVM: Get rid of arch.interrupt_window_open & arch.nmi_window_open Avi Kivity
2009-05-24 15:49 ` [PATCH 06/45] KVM: SVM: Add NMI injection support Avi Kivity
2009-05-24 15:49 ` [PATCH 07/45] KVM: Fix userspace IRQ chip migration Avi Kivity
2009-05-24 15:49 ` [PATCH 08/45] KVM: Get rid of get_irq() callback Avi Kivity
2009-05-24 15:49 ` [PATCH 09/45] KVM: Wake up waitqueue before calling get_cpu() Avi Kivity
2009-05-24 15:49 ` [PATCH 10/45] KVM: Replace get_mt_mask_shift with get_mt_mask Avi Kivity
2009-05-24 15:49 ` [PATCH 11/45] KVM: Enable snooping control for supported hardware Avi Kivity
2009-05-24 15:49 ` [PATCH 12/45] KVM: VMX: Disable VMX when system shutdown Avi Kivity
2009-05-24 15:49 ` [PATCH 13/45] KVM: Trivial format fix in setup_routing_entry() Avi Kivity
2009-05-24 15:49 ` [PATCH 14/45] KVM: fix apic_debug instances Avi Kivity
2009-05-24 15:50 ` [PATCH 15/45] KVM: SVM: Fix cross vendor migration issue in segment segment descriptor Avi Kivity
2009-05-24 15:50 ` [PATCH 16/45] KVM: SVM: Don't reinject event that caused a task switch Avi Kivity
2009-05-24 15:50 ` [PATCH 17/45] KVM: Drop request_nmi from stats Avi Kivity
2009-05-24 15:50 ` [PATCH 18/45] KVM: Fix cpuid feature misreporting Avi Kivity
2009-05-24 15:50 ` [PATCH 19/45] KVM: Add AMD cpuid bit: cr8_legacy, abm, misaligned sse, sse4, 3dnow prefetch Avi Kivity
2009-05-24 15:50 ` [PATCH 20/45] x86: Add cpu features MOVBE and POPCNT Avi Kivity
2009-05-24 15:50 ` [PATCH 21/45] KVM: Update cpuid 1.ecx reporting Avi Kivity
2009-05-24 15:50 ` [PATCH 22/45] KVM: use smp_send_reschedule in kvm_vcpu_kick Avi Kivity
2009-05-24 15:50 ` [PATCH 23/45] KVM: protect assigned dev workqueue, int handler and irq acker Avi Kivity
2009-05-24 15:50 ` Avi Kivity [this message]
2009-05-24 15:50 ` [PATCH 25/45] KVM: Deal with interrupt shadow state for emulated instructions Avi Kivity
2009-05-24 15:50 ` [PATCH 26/45] KVM: MMU: protect kvm_mmu_change_mmu_pages with mmu_lock Avi Kivity
2009-05-24 15:50 ` [PATCH 27/45] KVM: take mmu_lock when updating a deleted slot Avi Kivity
2009-05-24 15:50 ` [PATCH 28/45] KVM: x86: check for cr3 validity in mmu_alloc_roots Avi Kivity
2009-05-24 15:50 ` [PATCH 29/45] KVM: Expand on "help" info to specify kvm intel and amd module names Avi Kivity
2009-05-24 15:50 ` [PATCH 30/45] KVM: s390: Fix memory slot versus run - v3 Avi Kivity
2009-05-24 15:50 ` [PATCH 31/45] KVM: s390: use hrtimer for clock wakeup from idle - v2 Avi Kivity
2009-05-24 15:50 ` [PATCH 32/45] KVM: s390: optimize float int lock: spin_lock_bh --> spin_lock Avi Kivity
2009-05-24 15:50 ` [PATCH 33/45] KVM: s390: Unlink vcpu on destroy - v2 Avi Kivity
2009-05-24 15:50 ` [PATCH 34/45] KVM: s390: Sanity check on validity intercept Avi Kivity
2009-05-24 15:50 ` [PATCH 35/45] KVM: s390: Verify memory in kvm run Avi Kivity
2009-05-24 15:50 ` [PATCH 36/45] KVM: Unprotect a page if #PF happens during NMI injection Avi Kivity
2009-05-24 15:50 ` [PATCH 37/45] KVM: Do not allow interrupt injection from userspace if there is a pending event Avi Kivity
2009-05-24 15:50 ` [PATCH 38/45] KVM: Remove irq_pending bitmap Avi Kivity
2009-05-24 15:50 ` [PATCH 39/45] KVM: skip_emulated_instruction() decode instruction if size is not known Avi Kivity
2009-05-24 15:50 ` [PATCH 40/45] KVM: Do not re-execute INTn instruction Avi Kivity
2009-05-24 15:50 ` [PATCH 41/45] KVM: Always request IRQ/NMI window if an interrupt is pending Avi Kivity
2009-05-24 15:50 ` [PATCH 42/45] KVM: inject NMI after IRET from a previous NMI, not before Avi Kivity
2009-05-24 15:50 ` [PATCH 43/45] KVM: Do not migrate pending software interrupts Avi Kivity
2009-05-24 15:50 ` [PATCH 44/45] KVM: Disable CR8 intercept if tpr patching is active Avi Kivity
2009-05-24 15:50 ` [PATCH 45/45] KVM: Move "exit due to NMI" handling into vmx_complete_interrupts() Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1243180230-2480-25-git-send-email-avi@redhat.com \
    --to=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.