* [PATCH 5/5] Call x86_decode_insn() only when needed
@ 2007-08-29 16:45 Laurent Vivier
[not found] ` <46D5A2B0.7050802-6ktuUTfB/bM@public.gmane.org>
0 siblings, 1 reply; 2+ messages in thread
From: Laurent Vivier @ 2007-08-29 16:45 UTC (permalink / raw)
To: kvm-devel
[-- Attachment #1: Type: text/plain, Size: 280 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: 9612 bytes --]
Index: kvm/drivers/kvm/kvm.h
===================================================================
--- kvm.orig/drivers/kvm/kvm.h 2007-08-29 18:02:41.000000000 +0200
+++ kvm/drivers/kvm/kvm.h 2007-08-29 18:02:45.000000000 +0200
@@ -206,6 +206,8 @@ enum {
VCPU_SREG_LDTR,
};
+#include "x86_emulate.h"
+
struct kvm_pio_request {
unsigned long count;
int cur_count;
@@ -372,6 +374,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 {
@@ -525,7 +531,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 realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
Index: kvm/drivers/kvm/kvm_main.c
===================================================================
--- kvm.orig/drivers/kvm/kvm_main.c 2007-08-29 18:02:41.000000000 +0200
+++ kvm/drivers/kvm/kvm_main.c 2007-08-29 18:02:45.000000000 +0200
@@ -1167,47 +1167,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;
vcpu->mmio_fault_cr2 = cr2;
kvm_arch_ops->cache_regs(vcpu);
+ vcpu->emulate_ctxt.cr2 = cr2;
- kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
-
- emulate_ctxt.vcpu = vcpu;
- emulate_ctxt.eflags = kvm_arch_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_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+
+ vcpu->emulate_ctxt.vcpu = vcpu;
+ vcpu->emulate_ctxt.eflags = kvm_arch_ops->get_rflags(vcpu);
+ 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(&emulate_ctxt, &emulate_ops);
- if (r)
- return EMULATE_FAIL;
+ r = x86_decode_insn(&vcpu->emulate_ctxt, &emulate_ops);
+ if (r)
+ return EMULATE_FAIL;
+ }
vcpu->mmio_is_write = 0;
vcpu->pio.string = 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;
@@ -1223,14 +1232,14 @@ int emulate_instruction(struct kvm_vcpu
if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
return EMULATE_DONE;
if (!vcpu->mmio_needed) {
- report_emulation_failure(&emulate_ctxt);
+ report_emulation_failure(&vcpu->emulate_ctxt);
return EMULATE_FAIL;
}
return EMULATE_DO_MMIO;
}
kvm_arch_ops->decache_regs(vcpu);
- kvm_arch_ops->set_rflags(vcpu, emulate_ctxt.eflags);
+ kvm_arch_ops->set_rflags(vcpu, vcpu->emulate_ctxt.eflags);
if (vcpu->mmio_is_write) {
vcpu->mmio_needed = 0;
@@ -1860,7 +1869,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, 0);
if (r == EMULATE_DO_MMIO) {
/*
* Read-modify-write. Back to userspace.
Index: kvm/drivers/kvm/svm.c
===================================================================
--- kvm.orig/drivers/kvm/svm.c 2007-08-29 18:02:41.000000000 +0200
+++ kvm/drivers/kvm/svm.c 2007-08-29 18:03:18.000000000 +0200
@@ -938,7 +938,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) {
@@ -994,7 +994,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;
}
@@ -1052,7 +1053,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-08-29 18:02:41.000000000 +0200
+++ kvm/drivers/kvm/vmx.c 2007-08-29 18:03:30.000000000 +0200
@@ -1659,7 +1659,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;
}
@@ -1715,7 +1715,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) {
@@ -1776,7 +1776,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-08-29 18:02:41.000000000 +0200
+++ kvm/drivers/kvm/x86_emulate.c 2007-08-29 18:02:45.000000000 +0200
@@ -888,8 +888,12 @@ x86_emulate_insn(struct x86_emulate_ctxt
int mode = ctxt->mode;
int no_wb = 0;
u64 msr_data;
+ unsigned long saved_rcx = 0, saved_eip = 0;
unsigned long _eflags = ctxt->eflags;
+ 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;
if ((rc = ops->read_emulated((unsigned long)decode->src.ptr,
@@ -1274,6 +1278,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;
}
@@ -1289,8 +1295,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);
@@ -1316,8 +1327,13 @@ special_insn:
decode->dst.ptr = (unsigned long *)&decode->regs[VCPU_REGS_RAX];
if ((rc = ops->read_emulated(ctxt->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);
@@ -1338,8 +1354,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);
[-- Attachment #3: Type: text/plain, Size: 315 bytes --]
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
[-- 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] 2+ messages in thread[parent not found: <46D5A2B0.7050802-6ktuUTfB/bM@public.gmane.org>]
* Re: [PATCH 5/5] Call x86_decode_insn() only when needed [not found] ` <46D5A2B0.7050802-6ktuUTfB/bM@public.gmane.org> @ 2007-08-29 17:03 ` Laurent Vivier 0 siblings, 0 replies; 2+ messages in thread From: Laurent Vivier @ 2007-08-29 17:03 UTC (permalink / raw) To: Laurent Vivier; +Cc: kvm-devel [-- Attachment #1: Type: text/plain, Size: 642 bytes --] Laurent Vivier wrote: > Index: kvm/drivers/kvm/kvm.h > @@ -1860,7 +1869,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, 0); > if (r == EMULATE_DO_MMIO) { > /* > * Read-modify-write. Back to userspace. Sorry this one is wrong, we must have here: + vcpu->mmio_fault_cr2, 0, 1); (good patch attached) Laurent -- ------------- Laurent.Vivier-6ktuUTfB/bM@public.gmane.org -------------- "Software is hard" - Donald Knuth [-- Attachment #2: x86_emulate-optimize --] [-- Type: text/plain, Size: 9897 bytes --] Index: kvm/drivers/kvm/kvm.h =================================================================== --- kvm.orig/drivers/kvm/kvm.h 2007-08-29 18:27:21.000000000 +0200 +++ kvm/drivers/kvm/kvm.h 2007-08-29 18:27:26.000000000 +0200 @@ -206,6 +206,8 @@ enum { VCPU_SREG_LDTR, }; +#include "x86_emulate.h" + struct kvm_pio_request { unsigned long count; int cur_count; @@ -372,6 +374,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 { @@ -525,7 +531,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 realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, Index: kvm/drivers/kvm/kvm_main.c =================================================================== --- kvm.orig/drivers/kvm/kvm_main.c 2007-08-29 18:27:26.000000000 +0200 +++ kvm/drivers/kvm/kvm_main.c 2007-08-29 18:55:58.000000000 +0200 @@ -1167,47 +1167,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; vcpu->mmio_fault_cr2 = cr2; kvm_arch_ops->cache_regs(vcpu); + vcpu->emulate_ctxt.cr2 = cr2; - kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); - - emulate_ctxt.vcpu = vcpu; - emulate_ctxt.eflags = kvm_arch_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_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); + + vcpu->emulate_ctxt.vcpu = vcpu; + vcpu->emulate_ctxt.eflags = kvm_arch_ops->get_rflags(vcpu); + 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(&emulate_ctxt, &emulate_ops); - if (r) - return EMULATE_FAIL; + r = x86_decode_insn(&vcpu->emulate_ctxt, &emulate_ops); + if (r) + return EMULATE_FAIL; + } vcpu->mmio_is_write = 0; vcpu->pio.string = 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; @@ -1223,14 +1232,14 @@ int emulate_instruction(struct kvm_vcpu if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) return EMULATE_DONE; if (!vcpu->mmio_needed) { - report_emulation_failure(&emulate_ctxt); + report_emulation_failure(&vcpu->emulate_ctxt); return EMULATE_FAIL; } return EMULATE_DO_MMIO; } kvm_arch_ops->decache_regs(vcpu); - kvm_arch_ops->set_rflags(vcpu, emulate_ctxt.eflags); + kvm_arch_ops->set_rflags(vcpu, vcpu->emulate_ctxt.eflags); if (vcpu->mmio_is_write) { vcpu->mmio_needed = 0; @@ -1860,7 +1869,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-08-29 18:27:21.000000000 +0200 +++ kvm/drivers/kvm/svm.c 2007-08-29 18:27:26.000000000 +0200 @@ -938,7 +938,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) { @@ -994,7 +994,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; } @@ -1052,7 +1053,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-08-29 18:27:21.000000000 +0200 +++ kvm/drivers/kvm/vmx.c 2007-08-29 18:27:26.000000000 +0200 @@ -1659,7 +1659,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; } @@ -1715,7 +1715,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) { @@ -1776,7 +1776,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-08-29 18:27:26.000000000 +0200 +++ kvm/drivers/kvm/x86_emulate.c 2007-08-29 18:27:26.000000000 +0200 @@ -888,8 +888,12 @@ x86_emulate_insn(struct x86_emulate_ctxt int mode = ctxt->mode; int no_wb = 0; u64 msr_data; + unsigned long saved_rcx = 0, saved_eip = 0; unsigned long _eflags = ctxt->eflags; + 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; if ((rc = ops->read_emulated((unsigned long)decode->src.ptr, @@ -1274,6 +1278,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; } @@ -1289,8 +1295,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); @@ -1316,8 +1327,13 @@ special_insn: decode->dst.ptr = (unsigned long *)&decode->regs[VCPU_REGS_RAX]; if ((rc = ops->read_emulated(ctxt->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); @@ -1338,8 +1354,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); [-- Attachment #3: Type: text/plain, Size: 315 bytes --] ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ [-- 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] 2+ messages in thread
end of thread, other threads:[~2007-08-29 17:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-29 16:45 [PATCH 5/5] Call x86_decode_insn() only when needed Laurent Vivier
[not found] ` <46D5A2B0.7050802-6ktuUTfB/bM@public.gmane.org>
2007-08-29 17:03 ` Laurent Vivier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox