[PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd

From: Joerg Roedel
Date: Fri Feb 19 2010 - 10:25:29 EST


There is an intercept for WBINVD and INVD in SVM so we don't
need the instruction emulator. The primary reason is that
the current instruction emulator fails to emulate these
instructions and the rip is not advanced.

Signed-off-by: Joerg Roedel <joerg.roedel@xxxxxxx>
---
arch/x86/kvm/emulate.c | 4 ++++
arch/x86/kvm/svm.c | 14 ++++++++++++--
2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 9beda8e..0180cb1 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1029,6 +1029,10 @@ done_prefixes:

/* Unrecognised? */
if (c->d == 0) {
+ /* Don't fail for invd and wbinvd*/
+ if (c->twobyte && (c->b == 0x08 || c->b == 0x09))
+ return 0;
+
DPRINTF("Cannot emulate %02x\n", c->b);
return -1;
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 8119355..5fd00e8 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2117,6 +2117,16 @@ static int cpuid_interception(struct vcpu_svm *svm)
return 1;
}

+static int invd_interception(struct vcpu_svm *svm)
+{
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
+ skip_emulated_instruction(&svm->vcpu);
+
+ /* Nop */
+
+ return 1;
+}
+
static int iret_interception(struct vcpu_svm *svm)
{
++svm->vcpu.stat.nmi_window_exits;
@@ -2418,7 +2428,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
/* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */
[SVM_EXIT_CPUID] = cpuid_interception,
[SVM_EXIT_IRET] = iret_interception,
- [SVM_EXIT_INVD] = emulate_on_interception,
+ [SVM_EXIT_INVD] = invd_interception,
[SVM_EXIT_PAUSE] = pause_interception,
[SVM_EXIT_HLT] = halt_interception,
[SVM_EXIT_INVLPG] = invlpg_interception,
@@ -2434,7 +2444,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_STGI] = stgi_interception,
[SVM_EXIT_CLGI] = clgi_interception,
[SVM_EXIT_SKINIT] = skinit_interception,
- [SVM_EXIT_WBINVD] = emulate_on_interception,
+ [SVM_EXIT_WBINVD] = invd_interception,
[SVM_EXIT_MONITOR] = invalid_op_interception,
[SVM_EXIT_MWAIT] = invalid_op_interception,
[SVM_EXIT_NPF] = pf_interception,
--
1.6.6


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/