@@ -3619,6 +3619,55 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
update_cr0_intercept(svm);
}
+static void svm_check_group7(struct vmcb *vmcb, struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+
+ switch (c->modrm_rm) {
+ case 0:
+ switch (c->modrm_reg) {
+ case 1:
+ vmcb->control.exit_code = SVM_EXIT_MONITOR;
+ break;
+ case 3:
+ vmcb->control.exit_code = SVM_EXIT_VMRUN;
+ break;
+ }
+ break;
+ case 1:
+ switch (c->modrm_reg) {
+ case 1:
+ vmcb->control.exit_code = SVM_EXIT_MWAIT;
+ break;
+ case 3:
+ vmcb->control.exit_code = SVM_EXIT_VMMCALL;
+ break;
+ case 7:
+ vmcb->control.exit_code = SVM_EXIT_RDTSCP;
+ break;
+ }
+ break;
+ case 2:
+ vmcb->control.exit_code = SVM_EXIT_VMLOAD;
+ break;
+ case 3:
+ vmcb->control.exit_code = SVM_EXIT_VMSAVE;
+ break;
+ case 4:
+ vmcb->control.exit_code = SVM_EXIT_STGI;
+ break;
+ case 5:
+ vmcb->control.exit_code = SVM_EXIT_CLGI;
+ break;
+ case 6:
+ vmcb->control.exit_code = SVM_EXIT_SKINIT;
+ break;
+ case 7:
+ vmcb->control.exit_code = SVM_EXIT_INVLPGA;
+ break;
+ }
+}
+
static int svm_insn_intercepted(struct kvm_vcpu *vcpu,
struct x86_emulate_ctxt *ctxt)
{
@@ -3654,8 +3703,10 @@ static int svm_insn_intercepted(struct kvm_vcpu *vcpu,
break;
case 0x01:
/* 0x0f 0x01 and modrm_mod == 3 encodes special instructions */
- if (c->modrm_mod == 3)
+ if (c->modrm_mod == 3) {
+ svm_check_group7(vmcb, ctxt);
break;
+ }
switch (c->modrm_reg) {
case 0x00: /* SGDT */