diff options
author | Avi Kivity <avi@redhat.com> | 2010-08-26 04:59:01 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:42 -0400 |
commit | 34d1f4905eb66478a890ea808ec58bc842e6e589 (patch) | |
tree | 14062e3dbc2430bc74d29d02fce2c305310b1b34 /arch/x86/kvm/emulate.c | |
parent | f6b3597bded9ed261b42fdcb5e741489cb5ccbfe (diff) |
KVM: x86 emulator: trap and propagate #DE from DIV and IDIV
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e96cce170228..917b9b50fab0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -504,6 +504,12 @@ static void emulate_ts(struct x86_emulate_ctxt *ctxt, int err) | |||
504 | emulate_exception(ctxt, TS_VECTOR, err, true); | 504 | emulate_exception(ctxt, TS_VECTOR, err, true); |
505 | } | 505 | } |
506 | 506 | ||
507 | static int emulate_de(struct x86_emulate_ctxt *ctxt) | ||
508 | { | ||
509 | emulate_exception(ctxt, DE_VECTOR, 0, false); | ||
510 | return X86EMUL_PROPAGATE_FAULT; | ||
511 | } | ||
512 | |||
507 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, | 513 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, |
508 | struct x86_emulate_ops *ops, | 514 | struct x86_emulate_ops *ops, |
509 | unsigned long eip, u8 *dest) | 515 | unsigned long eip, u8 *dest) |
@@ -1458,6 +1464,7 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | |||
1458 | struct decode_cache *c = &ctxt->decode; | 1464 | struct decode_cache *c = &ctxt->decode; |
1459 | unsigned long *rax = &c->regs[VCPU_REGS_RAX]; | 1465 | unsigned long *rax = &c->regs[VCPU_REGS_RAX]; |
1460 | unsigned long *rdx = &c->regs[VCPU_REGS_RDX]; | 1466 | unsigned long *rdx = &c->regs[VCPU_REGS_RDX]; |
1467 | u8 de = 0; | ||
1461 | 1468 | ||
1462 | switch (c->modrm_reg) { | 1469 | switch (c->modrm_reg) { |
1463 | case 0 ... 1: /* test */ | 1470 | case 0 ... 1: /* test */ |
@@ -1476,14 +1483,18 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | |||
1476 | emulate_1op_rax_rdx("imul", c->src, *rax, *rdx, ctxt->eflags); | 1483 | emulate_1op_rax_rdx("imul", c->src, *rax, *rdx, ctxt->eflags); |
1477 | break; | 1484 | break; |
1478 | case 6: /* div */ | 1485 | case 6: /* div */ |
1479 | emulate_1op_rax_rdx("div", c->src, *rax, *rdx, ctxt->eflags); | 1486 | emulate_1op_rax_rdx_ex("div", c->src, *rax, *rdx, |
1487 | ctxt->eflags, de); | ||
1480 | break; | 1488 | break; |
1481 | case 7: /* idiv */ | 1489 | case 7: /* idiv */ |
1482 | emulate_1op_rax_rdx("idiv", c->src, *rax, *rdx, ctxt->eflags); | 1490 | emulate_1op_rax_rdx_ex("idiv", c->src, *rax, *rdx, |
1491 | ctxt->eflags, de); | ||
1483 | break; | 1492 | break; |
1484 | default: | 1493 | default: |
1485 | return X86EMUL_UNHANDLEABLE; | 1494 | return X86EMUL_UNHANDLEABLE; |
1486 | } | 1495 | } |
1496 | if (de) | ||
1497 | return emulate_de(ctxt); | ||
1487 | return X86EMUL_CONTINUE; | 1498 | return X86EMUL_CONTINUE; |
1488 | } | 1499 | } |
1489 | 1500 | ||
@@ -3413,8 +3424,9 @@ special_insn: | |||
3413 | ctxt->eflags ^= EFLG_CF; | 3424 | ctxt->eflags ^= EFLG_CF; |
3414 | break; | 3425 | break; |
3415 | case 0xf6 ... 0xf7: /* Grp3 */ | 3426 | case 0xf6 ... 0xf7: /* Grp3 */ |
3416 | if (emulate_grp3(ctxt, ops) != X86EMUL_CONTINUE) | 3427 | rc = emulate_grp3(ctxt, ops); |
3417 | goto cannot_emulate; | 3428 | if (rc != X86EMUL_CONTINUE) |
3429 | goto done; | ||
3418 | break; | 3430 | break; |
3419 | case 0xf8: /* clc */ | 3431 | case 0xf8: /* clc */ |
3420 | ctxt->eflags &= ~EFLG_CF; | 3432 | ctxt->eflags &= ~EFLG_CF; |