aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.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/kvm_main.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/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 800ab5028ed3..710483669f34 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1251,45 +1251,56 @@ struct x86_emulate_ops emulate_ops = {
1251int emulate_instruction(struct kvm_vcpu *vcpu, 1251int emulate_instruction(struct kvm_vcpu *vcpu,
1252 struct kvm_run *run, 1252 struct kvm_run *run,
1253 unsigned long cr2, 1253 unsigned long cr2,
1254 u16 error_code) 1254 u16 error_code,
1255 int no_decode)
1255{ 1256{
1256 struct x86_emulate_ctxt emulate_ctxt; 1257 int r = 0;
1257 int r;
1258 int cs_db, cs_l;
1259 1258
1260 vcpu->mmio_fault_cr2 = cr2; 1259 vcpu->mmio_fault_cr2 = cr2;
1261 kvm_x86_ops->cache_regs(vcpu); 1260 kvm_x86_ops->cache_regs(vcpu);
1262 1261
1263 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
1264
1265 emulate_ctxt.vcpu = vcpu;
1266 emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
1267 emulate_ctxt.cr2 = cr2;
1268 emulate_ctxt.mode = (emulate_ctxt.eflags & X86_EFLAGS_VM)
1269 ? X86EMUL_MODE_REAL : cs_l
1270 ? X86EMUL_MODE_PROT64 : cs_db
1271 ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
1272
1273 if (emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
1274 emulate_ctxt.cs_base = 0;
1275 emulate_ctxt.ds_base = 0;
1276 emulate_ctxt.es_base = 0;
1277 emulate_ctxt.ss_base = 0;
1278 } else {
1279 emulate_ctxt.cs_base = get_segment_base(vcpu, VCPU_SREG_CS);
1280 emulate_ctxt.ds_base = get_segment_base(vcpu, VCPU_SREG_DS);
1281 emulate_ctxt.es_base = get_segment_base(vcpu, VCPU_SREG_ES);
1282 emulate_ctxt.ss_base = get_segment_base(vcpu, VCPU_SREG_SS);
1283 }
1284
1285 emulate_ctxt.gs_base = get_segment_base(vcpu, VCPU_SREG_GS);
1286 emulate_ctxt.fs_base = get_segment_base(vcpu, VCPU_SREG_FS);
1287
1288 vcpu->mmio_is_write = 0; 1262 vcpu->mmio_is_write = 0;
1289 vcpu->pio.string = 0; 1263 vcpu->pio.string = 0;
1290 r = x86_decode_insn(&emulate_ctxt, &emulate_ops); 1264
1265 if (!no_decode) {
1266 int cs_db, cs_l;
1267 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
1268
1269 vcpu->emulate_ctxt.vcpu = vcpu;
1270 vcpu->emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
1271 vcpu->emulate_ctxt.cr2 = cr2;
1272 vcpu->emulate_ctxt.mode =
1273 (vcpu->emulate_ctxt.eflags & X86_EFLAGS_VM)
1274 ? X86EMUL_MODE_REAL : cs_l
1275 ? X86EMUL_MODE_PROT64 : cs_db
1276 ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
1277
1278 if (vcpu->emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
1279 vcpu->emulate_ctxt.cs_base = 0;
1280 vcpu->emulate_ctxt.ds_base = 0;
1281 vcpu->emulate_ctxt.es_base = 0;
1282 vcpu->emulate_ctxt.ss_base = 0;
1283 } else {
1284 vcpu->emulate_ctxt.cs_base =
1285 get_segment_base(vcpu, VCPU_SREG_CS);
1286 vcpu->emulate_ctxt.ds_base =
1287 get_segment_base(vcpu, VCPU_SREG_DS);
1288 vcpu->emulate_ctxt.es_base =
1289 get_segment_base(vcpu, VCPU_SREG_ES);
1290 vcpu->emulate_ctxt.ss_base =
1291 get_segment_base(vcpu, VCPU_SREG_SS);
1292 }
1293
1294 vcpu->emulate_ctxt.gs_base =
1295 get_segment_base(vcpu, VCPU_SREG_GS);
1296 vcpu->emulate_ctxt.fs_base =
1297 get_segment_base(vcpu, VCPU_SREG_FS);
1298
1299 r = x86_decode_insn(&vcpu->emulate_ctxt, &emulate_ops);
1300 }
1301
1291 if (r == 0) 1302 if (r == 0)
1292 r = x86_emulate_insn(&emulate_ctxt, &emulate_ops); 1303 r = x86_emulate_insn(&vcpu->emulate_ctxt, &emulate_ops);
1293 1304
1294 if (vcpu->pio.string) 1305 if (vcpu->pio.string)
1295 return EMULATE_DO_MMIO; 1306 return EMULATE_DO_MMIO;
@@ -1313,7 +1324,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
1313 } 1324 }
1314 1325
1315 kvm_x86_ops->decache_regs(vcpu); 1326 kvm_x86_ops->decache_regs(vcpu);
1316 kvm_x86_ops->set_rflags(vcpu, emulate_ctxt.eflags); 1327 kvm_x86_ops->set_rflags(vcpu, vcpu->emulate_ctxt.eflags);
1317 1328
1318 if (vcpu->mmio_is_write) { 1329 if (vcpu->mmio_is_write) {
1319 vcpu->mmio_needed = 0; 1330 vcpu->mmio_needed = 0;
@@ -2055,7 +2066,7 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2055 vcpu->mmio_read_completed = 1; 2066 vcpu->mmio_read_completed = 1;
2056 vcpu->mmio_needed = 0; 2067 vcpu->mmio_needed = 0;
2057 r = emulate_instruction(vcpu, kvm_run, 2068 r = emulate_instruction(vcpu, kvm_run,
2058 vcpu->mmio_fault_cr2, 0); 2069 vcpu->mmio_fault_cr2, 0, 1);
2059 if (r == EMULATE_DO_MMIO) { 2070 if (r == EMULATE_DO_MMIO) {
2060 /* 2071 /*
2061 * Read-modify-write. Back to userspace. 2072 * Read-modify-write. Back to userspace.