@@ -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;
}
@@ -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,