Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202239
b: refs/heads/master
c: 414e627
h: refs/heads/master
i:
  202237: c4cea8c
  202235: e4191aa
  202231: 1cbe2f5
  202223: 156d7af
  202207: 93ea7ff
  202175: 5deb974
  202111: 10e9a6f
  201983: 16e5380
  201727: bce1f8f
v: v3
  • Loading branch information
Gleb Natapov authored and Avi Kivity committed Aug 1, 2010
1 parent 230801c commit 87e0a68
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b8a98945ea5b735e083eaf92906aa0ff9ece92e8
refs/heads/master: 414e6277fd148f6470261cef50a7fed0d88a2825
6 changes: 5 additions & 1 deletion trunk/arch/x86/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ struct x86_emulate_ops {
struct operand {
enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
unsigned int bytes;
unsigned long val, orig_val, *ptr;
unsigned long orig_val, *ptr;
union {
unsigned long val;
char valptr[sizeof(unsigned long) + 2];
};
};

struct fetch_cache {
Expand Down
56 changes: 32 additions & 24 deletions trunk/arch/x86/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
#define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */
#define SrcImmU (9<<4) /* Immediate operand, unsigned */
#define SrcSI (0xa<<4) /* Source is in the DS:RSI */
#define SrcImmFAddr (0xb<<4) /* Source is immediate far address */
#define SrcMemFAddr (0xc<<4) /* Source is far address in memory */
#define SrcMask (0xf<<4)
/* Generic ModRM decode. */
#define ModRM (1<<8)
Expand All @@ -88,10 +90,6 @@
#define Src2CL (1<<29)
#define Src2ImmByte (2<<29)
#define Src2One (3<<29)
#define Src2Imm16 (4<<29)
#define Src2Mem16 (5<<29) /* Used for Ep encoding. First argument has to be
in memory and second argument is located
immediately after the first one in memory. */
#define Src2Mask (7<<29)

enum {
Expand Down Expand Up @@ -175,7 +173,7 @@ static u32 opcode_table[256] = {
/* 0x90 - 0x97 */
DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
/* 0x98 - 0x9F */
0, 0, SrcImm | Src2Imm16 | No64, 0,
0, 0, SrcImmFAddr | No64, 0,
ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
/* 0xA0 - 0xA7 */
ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
Expand Down Expand Up @@ -215,7 +213,7 @@ static u32 opcode_table[256] = {
ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc,
/* 0xE8 - 0xEF */
SrcImm | Stack, SrcImm | ImplicitOps,
SrcImmU | Src2Imm16 | No64, SrcImmByte | ImplicitOps,
SrcImmFAddr | No64, SrcImmByte | ImplicitOps,
SrcNone | ByteOp | DstAcc, SrcNone | DstAcc,
SrcNone | ByteOp | DstAcc, SrcNone | DstAcc,
/* 0xF0 - 0xF7 */
Expand Down Expand Up @@ -350,7 +348,7 @@ static u32 group_table[] = {
[Group5*8] =
DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
SrcMem | ModRM | Stack, 0,
SrcMem | ModRM | Stack, SrcMem | ModRM | Src2Mem16 | ImplicitOps,
SrcMem | ModRM | Stack, SrcMemFAddr | ModRM | ImplicitOps,
SrcMem | ModRM | Stack, 0,
[Group7*8] =
0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv,
Expand Down Expand Up @@ -576,6 +574,13 @@ static u32 group2_table[] = {
(_type)_x; \
})

#define insn_fetch_arr(_arr, _size, _eip) \
({ rc = do_insn_fetch(ctxt, ops, (_eip), _arr, (_size)); \
if (rc != X86EMUL_CONTINUE) \
goto done; \
(_eip) += (_size); \
})

static inline unsigned long ad_mask(struct decode_cache *c)
{
return (1UL << (c->ad_bytes << 3)) - 1;
Expand Down Expand Up @@ -1160,6 +1165,17 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
c->regs[VCPU_REGS_RSI]);
c->src.val = 0;
break;
case SrcImmFAddr:
c->src.type = OP_IMM;
c->src.ptr = (unsigned long *)c->eip;
c->src.bytes = c->op_bytes + 2;
insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
break;
case SrcMemFAddr:
c->src.type = OP_MEM;
c->src.ptr = (unsigned long *)c->modrm_ea;
c->src.bytes = c->op_bytes + 2;
break;
}

/*
Expand All @@ -1179,22 +1195,10 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
c->src2.bytes = 1;
c->src2.val = insn_fetch(u8, 1, c->eip);
break;
case Src2Imm16:
c->src2.type = OP_IMM;
c->src2.ptr = (unsigned long *)c->eip;
c->src2.bytes = 2;
c->src2.val = insn_fetch(u16, 2, c->eip);
break;
case Src2One:
c->src2.bytes = 1;
c->src2.val = 1;
break;
case Src2Mem16:
c->src2.type = OP_MEM;
c->src2.bytes = 2;
c->src2.ptr = (unsigned long *)(c->modrm_ea + c->src.bytes);
c->src2.val = 0;
break;
}

/* Decode and fetch the destination operand: register or memory. */
Expand Down Expand Up @@ -2558,7 +2562,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)

if (c->src.type == OP_MEM) {
rc = read_emulated(ctxt, ops, (unsigned long)c->src.ptr,
&c->src.val, c->src.bytes);
c->src.valptr, c->src.bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
c->src.orig_val = c->src.val;
Expand Down Expand Up @@ -2884,14 +2888,18 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
}
case 0xe9: /* jmp rel */
goto jmp;
case 0xea: /* jmp far */
case 0xea: { /* jmp far */
unsigned short sel;
jump_far:
if (load_segment_descriptor(ctxt, ops, c->src2.val,
VCPU_SREG_CS))
memcpy(&sel, c->src.valptr + c->op_bytes, 2);

if (load_segment_descriptor(ctxt, ops, sel, VCPU_SREG_CS))
goto done;

c->eip = c->src.val;
c->eip = 0;
memcpy(&c->eip, c->src.valptr, c->op_bytes);
break;
}
case 0xeb:
jmp: /* jmp rel short */
jmp_rel(c, c->src.val);
Expand Down

0 comments on commit 87e0a68

Please sign in to comment.