aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorLaurent Vivier <Laurent.Vivier@bull.net>2007-09-18 05:27:37 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:47 -0500
commit3427318fd2244737a466a06a93c5fe579852f871 (patch)
tree7c6760dbbdd067498c470e6e4f711e5baeef491c /drivers/kvm/x86_emulate.c
parent1be3aa47182e94944e57b176a5c4ee4e74f1ce33 (diff)
KVM: 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. Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r--drivers/kvm/x86_emulate.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index c191093982d..dc9d2a870fb 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -913,10 +913,19 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
913 unsigned long cr2 = ctxt->cr2; 913 unsigned long cr2 = ctxt->cr2;
914 int no_wb = 0; 914 int no_wb = 0;
915 u64 msr_data; 915 u64 msr_data;
916 unsigned long saved_eip = 0;
916 unsigned long _eflags = ctxt->eflags; 917 unsigned long _eflags = ctxt->eflags;
917 struct decode_cache *c = &ctxt->decode; 918 struct decode_cache *c = &ctxt->decode;
918 int rc = 0; 919 int rc = 0;
919 920
921 /* Shadow copy of register state. Committed on successful emulation.
922 * NOTE: we can copy them from vcpu as x86_decode_insn() doesn't
923 * modify them.
924 */
925
926 memcpy(c->regs, ctxt->vcpu->regs, sizeof c->regs);
927 saved_eip = c->eip;
928
920 if ((c->d & ModRM) && (c->modrm_mod != 3)) 929 if ((c->d & ModRM) && (c->modrm_mod != 3))
921 cr2 = c->modrm_ea; 930 cr2 = c->modrm_ea;
922 931
@@ -1250,7 +1259,11 @@ writeback:
1250 ctxt->vcpu->rip = c->eip; 1259 ctxt->vcpu->rip = c->eip;
1251 1260
1252done: 1261done:
1253 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; 1262 if (rc == X86EMUL_UNHANDLEABLE) {
1263 c->eip = saved_eip;
1264 return -1;
1265 }
1266 return 0;
1254 1267
1255special_insn: 1268special_insn:
1256 if (c->twobyte) 1269 if (c->twobyte)
@@ -1305,8 +1318,10 @@ push:
1305 register_address(ctxt->es_base, 1318 register_address(ctxt->es_base,
1306 c->regs[VCPU_REGS_RDI]), 1319 c->regs[VCPU_REGS_RDI]),
1307 c->rep_prefix, 1320 c->rep_prefix,
1308 c->regs[VCPU_REGS_RDX]) == 0) 1321 c->regs[VCPU_REGS_RDX]) == 0) {
1322 c->eip = saved_eip;
1309 return -1; 1323 return -1;
1324 }
1310 return 0; 1325 return 0;
1311 case 0x6e: /* outsb */ 1326 case 0x6e: /* outsb */
1312 case 0x6f: /* outsw/outsd */ 1327 case 0x6f: /* outsw/outsd */
@@ -1321,8 +1336,10 @@ push:
1321 ctxt->ds_base, 1336 ctxt->ds_base,
1322 c->regs[VCPU_REGS_RSI]), 1337 c->regs[VCPU_REGS_RSI]),
1323 c->rep_prefix, 1338 c->rep_prefix,
1324 c->regs[VCPU_REGS_RDX]) == 0) 1339 c->regs[VCPU_REGS_RDX]) == 0) {
1340 c->eip = saved_eip;
1325 return -1; 1341 return -1;
1342 }
1326 return 0; 1343 return 0;
1327 case 0x70 ... 0x7f: /* jcc (short) */ { 1344 case 0x70 ... 0x7f: /* jcc (short) */ {
1328 int rel = insn_fetch(s8, 1, c->eip); 1345 int rel = insn_fetch(s8, 1, c->eip);
@@ -1711,5 +1728,6 @@ twobyte_special_insn:
1711 1728
1712cannot_emulate: 1729cannot_emulate:
1713 DPRINTF("Cannot emulate %02x\n", c->b); 1730 DPRINTF("Cannot emulate %02x\n", c->b);
1731 c->eip = saved_eip;
1714 return -1; 1732 return -1;
1715} 1733}