aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-09-13 03:45:40 -0400
committerAvi Kivity <avi@redhat.com>2011-09-25 12:52:47 -0400
commitf09ed83e211d253809e575e05bd4de1e335c0cb2 (patch)
treebb769d8d7375b457e70adadb121663af43186561 /arch
parent3329ece161ad65ea31d825720e270f3a79ebba92 (diff)
KVM: x86 emulator: move memop, memopp into emulation context
Simplifies further generalization of decode. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm_emulate.h2
-rw-r--r--arch/x86/kvm/emulate.c34
2 files changed, 19 insertions, 17 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 6040d115ef51..56bac3e3423e 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -275,6 +275,8 @@ struct x86_emulate_ctxt {
275 unsigned long _eip; 275 unsigned long _eip;
276 /* Fields above regs are cleared together. */ 276 /* Fields above regs are cleared together. */
277 unsigned long regs[NR_VCPU_REGS]; 277 unsigned long regs[NR_VCPU_REGS];
278 struct operand memop;
279 struct operand *memopp;
278 struct fetch_cache fetch; 280 struct fetch_cache fetch;
279 struct read_cache io_read; 281 struct read_cache io_read;
280 struct read_cache mem_read; 282 struct read_cache mem_read;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ed819bdf475d..58172fb9a09a 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3323,8 +3323,9 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
3323 int def_op_bytes, def_ad_bytes, goffset, simd_prefix; 3323 int def_op_bytes, def_ad_bytes, goffset, simd_prefix;
3324 bool op_prefix = false; 3324 bool op_prefix = false;
3325 struct opcode opcode; 3325 struct opcode opcode;
3326 struct operand memop = { .type = OP_NONE }, *memopp = NULL;
3327 3326
3327 ctxt->memop.type = OP_NONE;
3328 ctxt->memopp = NULL;
3328 ctxt->_eip = ctxt->eip; 3329 ctxt->_eip = ctxt->eip;
3329 ctxt->fetch.start = ctxt->_eip; 3330 ctxt->fetch.start = ctxt->_eip;
3330 ctxt->fetch.end = ctxt->fetch.start + insn_len; 3331 ctxt->fetch.end = ctxt->fetch.start + insn_len;
@@ -3482,21 +3483,21 @@ done_prefixes:
3482 3483
3483 /* ModRM and SIB bytes. */ 3484 /* ModRM and SIB bytes. */
3484 if (ctxt->d & ModRM) { 3485 if (ctxt->d & ModRM) {
3485 rc = decode_modrm(ctxt, &memop); 3486 rc = decode_modrm(ctxt, &ctxt->memop);
3486 if (!ctxt->has_seg_override) 3487 if (!ctxt->has_seg_override)
3487 set_seg_override(ctxt, ctxt->modrm_seg); 3488 set_seg_override(ctxt, ctxt->modrm_seg);
3488 } else if (ctxt->d & MemAbs) 3489 } else if (ctxt->d & MemAbs)
3489 rc = decode_abs(ctxt, &memop); 3490 rc = decode_abs(ctxt, &ctxt->memop);
3490 if (rc != X86EMUL_CONTINUE) 3491 if (rc != X86EMUL_CONTINUE)
3491 goto done; 3492 goto done;
3492 3493
3493 if (!ctxt->has_seg_override) 3494 if (!ctxt->has_seg_override)
3494 set_seg_override(ctxt, VCPU_SREG_DS); 3495 set_seg_override(ctxt, VCPU_SREG_DS);
3495 3496
3496 memop.addr.mem.seg = seg_override(ctxt); 3497 ctxt->memop.addr.mem.seg = seg_override(ctxt);
3497 3498
3498 if (memop.type == OP_MEM && ctxt->ad_bytes != 8) 3499 if (ctxt->memop.type == OP_MEM && ctxt->ad_bytes != 8)
3499 memop.addr.mem.ea = (u32)memop.addr.mem.ea; 3500 ctxt->memop.addr.mem.ea = (u32)ctxt->memop.addr.mem.ea;
3500 3501
3501 /* 3502 /*
3502 * Decode and fetch the source operand: register, memory 3503 * Decode and fetch the source operand: register, memory
@@ -3509,17 +3510,16 @@ done_prefixes:
3509 decode_register_operand(ctxt, &ctxt->src, 0); 3510 decode_register_operand(ctxt, &ctxt->src, 0);
3510 break; 3511 break;
3511 case SrcMem16: 3512 case SrcMem16:
3512 memop.bytes = 2; 3513 ctxt->memop.bytes = 2;
3513 goto srcmem_common; 3514 goto srcmem_common;
3514 case SrcMem32: 3515 case SrcMem32:
3515 memop.bytes = 4; 3516 ctxt->memop.bytes = 4;
3516 goto srcmem_common; 3517 goto srcmem_common;
3517 case SrcMem: 3518 case SrcMem:
3518 memop.bytes = (ctxt->d & ByteOp) ? 1 : 3519 ctxt->memop.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
3519 ctxt->op_bytes;
3520 srcmem_common: 3520 srcmem_common:
3521 ctxt->src = memop; 3521 ctxt->src = ctxt->memop;
3522 memopp = &ctxt->src; 3522 ctxt->memopp = &ctxt->src;
3523 break; 3523 break;
3524 case SrcImmU16: 3524 case SrcImmU16:
3525 rc = decode_imm(ctxt, &ctxt->src, 2, false); 3525 rc = decode_imm(ctxt, &ctxt->src, 2, false);
@@ -3561,7 +3561,7 @@ done_prefixes:
3561 insn_fetch_arr(ctxt->src.valptr, ctxt->src.bytes, ctxt); 3561 insn_fetch_arr(ctxt->src.valptr, ctxt->src.bytes, ctxt);
3562 break; 3562 break;
3563 case SrcMemFAddr: 3563 case SrcMemFAddr:
3564 memop.bytes = ctxt->op_bytes + 2; 3564 ctxt->memop.bytes = ctxt->op_bytes + 2;
3565 goto srcmem_common; 3565 goto srcmem_common;
3566 break; 3566 break;
3567 case SrcDX: 3567 case SrcDX:
@@ -3615,8 +3615,8 @@ done_prefixes:
3615 break; 3615 break;
3616 case DstMem: 3616 case DstMem:
3617 case DstMem64: 3617 case DstMem64:
3618 ctxt->dst = memop; 3618 ctxt->dst = ctxt->memop;
3619 memopp = &ctxt->dst; 3619 ctxt->memopp = &ctxt->dst;
3620 if ((ctxt->d & DstMask) == DstMem64) 3620 if ((ctxt->d & DstMask) == DstMem64)
3621 ctxt->dst.bytes = 8; 3621 ctxt->dst.bytes = 8;
3622 else 3622 else
@@ -3654,8 +3654,8 @@ done_prefixes:
3654 } 3654 }
3655 3655
3656done: 3656done:
3657 if (memopp && memopp->type == OP_MEM && ctxt->rip_relative) 3657 if (ctxt->memopp && ctxt->memopp->type == OP_MEM && ctxt->rip_relative)
3658 memopp->addr.mem.ea += ctxt->_eip; 3658 ctxt->memopp->addr.mem.ea += ctxt->_eip;
3659 3659
3660 return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; 3660 return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
3661} 3661}