Skip to contentSkip to conversation

Call x86_decode_insn() only when needed

PATCH RESEND Applied Laurent Vivier 1 participant 1 message Sep 18, 2007 KVM

lore
Share & tools
lore
#0 lore raw

PATCH RESEND 5/5 Call x86_decode_insn() only when needed

move emulate_ctxt to kvm_vcpu to keep emulate context when we exit from kvm module. Call x86_decode_insn() only when needed. Modify x86_emulate_insn() to not modify the context if it must be re-entered.

drivers/kvm/kvm.h +7 -1
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -206,6 +206,8 @@ enum {
 	VCPU_SREG_LDTR,
 };
 
+#include "x86_emulate.h"
+
 struct kvm_pio_request {
 	unsigned long count;
 	int cur_count;
@@ -382,6 +384,10 @@ struct kvm_vcpu {
 
 	int cpuid_nent;
 	struct kvm_cpuid_entry cpuid_entries[KVM_MAX_CPUID_ENTRIES];
+
+	/* emulate context */
+
+	struct x86_emulate_ctxt emulate_ctxt;
 };
 
 struct kvm_mem_alias {
@@ -557,7 +563,7 @@ enum emulation_result {
 };
 
 int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run,
-			unsigned long cr2, u16 error_code);
+			unsigned long cr2, u16 error_code, int no_decode);
 void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context);
 void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
 void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
drivers/kvm/kvm_main.c +43 -32

102 lines not on this page · raw message

drivers/kvm/svm.c +4 -3
Index: kvm/drivers/kvm/svm.c
===================================================================
@@ -950,7 +950,7 @@ static int pf_interception(struct vcpu_s
 		return 1;
 	}
 	er = emulate_instruction(&svm->vcpu, kvm_run, fault_address,
-				 error_code);
+				 error_code, 0);
 	mutex_unlock(&kvm->lock);
 
 	switch (er) {
@@ -1006,7 +1006,8 @@ static int io_interception(struct vcpu_s
 	string = (io_info & SVM_IOIO_STR_MASK) != 0;
 
 	if (string) {
-		if (emulate_instruction(&svm->vcpu, kvm_run, 0, 0) == EMULATE_DO_MMIO)
+		if (emulate_instruction(&svm->vcpu,
+					kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
 			return 0;
 		return 1;
 	}
@@ -1064,7 +1065,7 @@ static int cpuid_interception(struct vcp
 static int emulate_on_interception(struct vcpu_svm *svm,
 				   struct kvm_run *kvm_run)
 {
-	if (emulate_instruction(&svm->vcpu, NULL, 0, 0) != EMULATE_DONE)
+	if (emulate_instruction(&svm->vcpu, NULL, 0, 0, 0) != EMULATE_DONE)
 		pr_unimpl(&svm->vcpu, "%s: failed\n", __FUNCTION__);
 	return 1;
 }
drivers/kvm/vmx.c +4 -3
Index: kvm/drivers/kvm/vmx.c
===================================================================
@@ -1732,7 +1732,7 @@ static int handle_rmode_exception(struct
 	 * Cause the #SS fault with 0 error code in VM86 mode.
 	 */
 	if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0)
-		if (emulate_instruction(vcpu, NULL, 0, 0) == EMULATE_DONE)
+		if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE)
 			return 1;
 	return 0;
 }
@@ -1788,7 +1788,7 @@ static int handle_exception(struct kvm_v
 			return 1;
 		}
 
-		er = emulate_instruction(vcpu, kvm_run, cr2, error_code);
+		er = emulate_instruction(vcpu, kvm_run, cr2, error_code, 0);
 		mutex_unlock(&vcpu->kvm->lock);
 
 		switch (er) {
@@ -1849,7 +1849,8 @@ static int handle_io(struct kvm_vcpu *vc
 	string = (exit_qualification & 16) != 0;
 
 	if (string) {
-		if (emulate_instruction(vcpu, kvm_run, 0, 0) == EMULATE_DO_MMIO)
+		if (emulate_instruction(vcpu,
+					kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
 			return 0;
 		return 1;
 	}
drivers/kvm/x86_emulate.c +24 -3
Index: kvm/drivers/kvm/x86_emulate.c
===================================================================
@@ -916,10 +916,14 @@ x86_emulate_insn(struct x86_emulate_ctxt
 	unsigned long cr2 = ctxt->cr2;
 	int no_wb = 0;
 	u64 msr_data;
+	unsigned long saved_rcx = 0, saved_eip = 0;
 	unsigned long _eflags = ctxt->eflags;
 	struct decode_cache *decode = &ctxt->decode;
 	int rc = 0;
 
+	if ((decode->d & ModRM) && (decode->modrm_mod != 3))
+		ctxt->cr2 = decode->modrm_ea;
+
 	if (decode->src.type == OP_MEM) {
 		decode->src.ptr = (unsigned long *)ctxt->cr2;
 		decode->src.val = 0;
@@ -1323,8 +1327,13 @@ special_insn:
 	pop_instruction:
 		if ((rc = ops->read_std(register_address(ctxt->ss_base,
 			decode->regs[VCPU_REGS_RSP]), decode->dst.ptr,
-			decode->op_bytes, ctxt->vcpu)) != 0)
+			decode->op_bytes, ctxt->vcpu)) != 0) {
+			if (ctxt->decode.rep_prefix) {
+				ctxt->decode.regs[VCPU_REGS_RCX] = saved_rcx;
+				ctxt->decode.eip = saved_eip;
+			}
 			goto done;
+		}
 
 		register_address_increment(decode->regs[VCPU_REGS_RSP],
 					   decode->op_bytes);
@@ -1385,6 +1394,8 @@ special_insn:
 			ctxt->vcpu->rip = decode->eip;
 			goto done;
 		}
+		saved_rcx = ctxt->decode.regs[VCPU_REGS_RCX];
+		saved_eip = ctxt->decode.eip;
 		decode->regs[VCPU_REGS_RCX]--;
 		decode->eip = ctxt->vcpu->rip;
 	}
@@ -1400,8 +1411,13 @@ special_insn:
 					ctxt->ds_base,
 					decode->regs[VCPU_REGS_RSI]),
 					&decode->dst.val,
-					decode->dst.bytes, ctxt->vcpu)) != 0)
+					decode->dst.bytes, ctxt->vcpu)) != 0) {
+			if (ctxt->decode.rep_prefix) {
+				ctxt->decode.regs[VCPU_REGS_RCX] = saved_rcx;
+				ctxt->decode.eip = saved_eip;
+			}
 			goto done;
+		}
 		register_address_increment(decode->regs[VCPU_REGS_RSI],
 				       (_eflags & EFLG_DF) ? -decode->dst.bytes
 							   : decode->dst.bytes);
@@ -1427,8 +1443,13 @@ special_insn:
 		decode->dst.ptr = (unsigned long *)&decode->regs[VCPU_REGS_RAX];
 		if ((rc = ops->read_emulated(cr2, &decode->dst.val,
 					     decode->dst.bytes,
-					     ctxt->vcpu)) != 0)
+					     ctxt->vcpu)) != 0) {
+			if (ctxt->decode.rep_prefix) {
+				ctxt->decode.regs[VCPU_REGS_RCX] = saved_rcx;
+				ctxt->decode.eip = saved_eip;
+			}
 			goto done;
+		}
 		register_address_increment(decode->regs[VCPU_REGS_RSI],
 				       (_eflags & EFLG_DF) ? -decode->dst.bytes
 							   : decode->dst.bytes);

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel