* [PATCH 5/5][RESEND] Call x86_decode_insn() only when needed
@ 2007-09-18 9:27 Laurent Vivier
0 siblings, 0 replies; only message in thread
From: Laurent Vivier @ 2007-09-18 9:27 UTC (permalink / raw)
To: kvm-devel
[-- Attachment #1: Type: text/plain, Size: 281 bytes --]
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.
Signed-off-by: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
[-- Attachment #2: x86_emulate-optimize --]
[-- Type: text/plain, Size: 9418 bytes --]
Index: kvm/drivers/kvm/kvm.h
===================================================================
--- kvm.orig/drivers/kvm/kvm.h 2007-09-18 10:41:04.000000000 +0200
+++ kvm/drivers/kvm/kvm.h 2007-09-18 10:42:41.000000000 +0200
@@ -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);
Index: kvm/drivers/kvm/kvm_main.c
===================================================================
--- kvm.orig/drivers/kvm/kvm_main.c 2007-09-18 10:42:05.000000000 +0200
+++ kvm/drivers/kvm/kvm_main.c 2007-09-18 11:08:45.000000000 +0200
@@ -1251,45 +1251,56 @@ struct x86_emulate_ops emulate_ops = {
int emulate_instruction(struct kvm_vcpu *vcpu,
struct kvm_run *run,
unsigned long cr2,
- u16 error_code)
+ u16 error_code,
+ int no_decode)
{
- struct x86_emulate_ctxt emulate_ctxt;
- int r;
- int cs_db, cs_l;
+ int r = 0;
vcpu->mmio_fault_cr2 = cr2;
kvm_x86_ops->cache_regs(vcpu);
- kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+ vcpu->mmio_is_write = 0;
+ vcpu->pio.string = 0;
- emulate_ctxt.vcpu = vcpu;
- emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
- emulate_ctxt.cr2 = cr2;
- emulate_ctxt.mode = (emulate_ctxt.eflags & X86_EFLAGS_VM)
- ? X86EMUL_MODE_REAL : cs_l
- ? X86EMUL_MODE_PROT64 : cs_db
- ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
-
- if (emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
- emulate_ctxt.cs_base = 0;
- emulate_ctxt.ds_base = 0;
- emulate_ctxt.es_base = 0;
- emulate_ctxt.ss_base = 0;
- } else {
- emulate_ctxt.cs_base = get_segment_base(vcpu, VCPU_SREG_CS);
- emulate_ctxt.ds_base = get_segment_base(vcpu, VCPU_SREG_DS);
- emulate_ctxt.es_base = get_segment_base(vcpu, VCPU_SREG_ES);
- emulate_ctxt.ss_base = get_segment_base(vcpu, VCPU_SREG_SS);
- }
+ if (!no_decode) {
+ int cs_db, cs_l;
+ kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+
+ vcpu->emulate_ctxt.vcpu = vcpu;
+ vcpu->emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
+ vcpu->emulate_ctxt.cr2 = cr2;
+ vcpu->emulate_ctxt.mode =
+ (vcpu->emulate_ctxt.eflags & X86_EFLAGS_VM)
+ ? X86EMUL_MODE_REAL : cs_l
+ ? X86EMUL_MODE_PROT64 : cs_db
+ ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+
+ if (vcpu->emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
+ vcpu->emulate_ctxt.cs_base = 0;
+ vcpu->emulate_ctxt.ds_base = 0;
+ vcpu->emulate_ctxt.es_base = 0;
+ vcpu->emulate_ctxt.ss_base = 0;
+ } else {
+ vcpu->emulate_ctxt.cs_base =
+ get_segment_base(vcpu, VCPU_SREG_CS);
+ vcpu->emulate_ctxt.ds_base =
+ get_segment_base(vcpu, VCPU_SREG_DS);
+ vcpu->emulate_ctxt.es_base =
+ get_segment_base(vcpu, VCPU_SREG_ES);
+ vcpu->emulate_ctxt.ss_base =
+ get_segment_base(vcpu, VCPU_SREG_SS);
+ }
- emulate_ctxt.gs_base = get_segment_base(vcpu, VCPU_SREG_GS);
- emulate_ctxt.fs_base = get_segment_base(vcpu, VCPU_SREG_FS);
+ vcpu->emulate_ctxt.gs_base =
+ get_segment_base(vcpu, VCPU_SREG_GS);
+ vcpu->emulate_ctxt.fs_base =
+ get_segment_base(vcpu, VCPU_SREG_FS);
+
+ r = x86_decode_insn(&vcpu->emulate_ctxt, &emulate_ops);
+ }
- vcpu->mmio_is_write = 0;
- vcpu->pio.string = 0;
- r = x86_decode_insn(&emulate_ctxt, &emulate_ops);
if (r == 0)
- r = x86_emulate_insn(&emulate_ctxt, &emulate_ops);
+ r = x86_emulate_insn(&vcpu->emulate_ctxt, &emulate_ops);
if (vcpu->pio.string)
return EMULATE_DO_MMIO;
@@ -1313,7 +1324,7 @@ int emulate_instruction(struct kvm_vcpu
}
kvm_x86_ops->decache_regs(vcpu);
- kvm_x86_ops->set_rflags(vcpu, emulate_ctxt.eflags);
+ kvm_x86_ops->set_rflags(vcpu, vcpu->emulate_ctxt.eflags);
if (vcpu->mmio_is_write) {
vcpu->mmio_needed = 0;
@@ -2111,7 +2122,7 @@ static int kvm_vcpu_ioctl_run(struct kvm
vcpu->mmio_read_completed = 1;
vcpu->mmio_needed = 0;
r = emulate_instruction(vcpu, kvm_run,
- vcpu->mmio_fault_cr2, 0);
+ vcpu->mmio_fault_cr2, 0, 1);
if (r == EMULATE_DO_MMIO) {
/*
* Read-modify-write. Back to userspace.
Index: kvm/drivers/kvm/svm.c
===================================================================
--- kvm.orig/drivers/kvm/svm.c 2007-09-18 10:41:04.000000000 +0200
+++ kvm/drivers/kvm/svm.c 2007-09-18 10:42:41.000000000 +0200
@@ -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;
}
Index: kvm/drivers/kvm/vmx.c
===================================================================
--- kvm.orig/drivers/kvm/vmx.c 2007-09-18 10:41:04.000000000 +0200
+++ kvm/drivers/kvm/vmx.c 2007-09-18 10:42:41.000000000 +0200
@@ -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;
}
Index: kvm/drivers/kvm/x86_emulate.c
===================================================================
--- kvm.orig/drivers/kvm/x86_emulate.c 2007-09-18 10:42:05.000000000 +0200
+++ kvm/drivers/kvm/x86_emulate.c 2007-09-18 10:42:41.000000000 +0200
@@ -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);
[-- Attachment #3: Type: text/plain, Size: 228 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/
[-- Attachment #4: Type: text/plain, Size: 186 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-09-18 9:27 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-18 9:27 [PATCH 5/5][RESEND] Call x86_decode_insn() only when needed Laurent Vivier
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.