Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202347
b: refs/heads/master
c: c37eda1
h: refs/heads/master
i:
  202345: 480585e
  202343: a00dda6
v: v3
  • Loading branch information
Wei Yongjun authored and Avi Kivity committed Aug 1, 2010
1 parent c2f3b0f commit 31fd517
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 61 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: bd371396b38ffc4bd6444b0203f33b99d18cedd0
refs/heads/master: c37eda138473f8c843f2b4aa8da252fdfdaaafa3
133 changes: 73 additions & 60 deletions trunk/arch/x86/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,64 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
return X86EMUL_PROPAGATE_FAULT;
}

static inline int writeback(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
int rc;
struct decode_cache *c = &ctxt->decode;
u32 err;

switch (c->dst.type) {
case OP_REG:
/* The 4-byte case *is* correct:
* in 64-bit mode we zero-extend.
*/
switch (c->dst.bytes) {
case 1:
*(u8 *)c->dst.ptr = (u8)c->dst.val;
break;
case 2:
*(u16 *)c->dst.ptr = (u16)c->dst.val;
break;
case 4:
*c->dst.ptr = (u32)c->dst.val;
break; /* 64b: zero-ext */
case 8:
*c->dst.ptr = c->dst.val;
break;
}
break;
case OP_MEM:
if (c->lock_prefix)
rc = ops->cmpxchg_emulated(
(unsigned long)c->dst.ptr,
&c->dst.orig_val,
&c->dst.val,
c->dst.bytes,
&err,
ctxt->vcpu);
else
rc = ops->write_emulated(
(unsigned long)c->dst.ptr,
&c->dst.val,
c->dst.bytes,
&err,
ctxt->vcpu);
if (rc == X86EMUL_PROPAGATE_FAULT)
emulate_pf(ctxt,
(unsigned long)c->dst.ptr, err);
if (rc != X86EMUL_CONTINUE)
return rc;
break;
case OP_NONE:
/* no writeback */
break;
default:
break;
}
return X86EMUL_CONTINUE;
}

static inline void emulate_push(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
Expand Down Expand Up @@ -1651,20 +1709,31 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
return rc;
}

static void emulate_pusha(struct x86_emulate_ctxt *ctxt,
static int emulate_pusha(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
struct decode_cache *c = &ctxt->decode;
unsigned long old_esp = c->regs[VCPU_REGS_RSP];
int rc = X86EMUL_CONTINUE;
int reg = VCPU_REGS_RAX;

while (reg <= VCPU_REGS_RDI) {
(reg == VCPU_REGS_RSP) ?
(c->src.val = old_esp) : (c->src.val = c->regs[reg]);

emulate_push(ctxt, ops);

rc = writeback(ctxt, ops);
if (rc != X86EMUL_CONTINUE)
return rc;

++reg;
}

/* Disable writeback. */
c->dst.type = OP_NONE;

return rc;
}

static int emulate_popa(struct x86_emulate_ctxt *ctxt,
Expand Down Expand Up @@ -1817,64 +1886,6 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
return rc;
}

static inline int writeback(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
int rc;
struct decode_cache *c = &ctxt->decode;
u32 err;

switch (c->dst.type) {
case OP_REG:
/* The 4-byte case *is* correct:
* in 64-bit mode we zero-extend.
*/
switch (c->dst.bytes) {
case 1:
*(u8 *)c->dst.ptr = (u8)c->dst.val;
break;
case 2:
*(u16 *)c->dst.ptr = (u16)c->dst.val;
break;
case 4:
*c->dst.ptr = (u32)c->dst.val;
break; /* 64b: zero-ext */
case 8:
*c->dst.ptr = c->dst.val;
break;
}
break;
case OP_MEM:
if (c->lock_prefix)
rc = ops->cmpxchg_emulated(
(unsigned long)c->dst.ptr,
&c->dst.orig_val,
&c->dst.val,
c->dst.bytes,
&err,
ctxt->vcpu);
else
rc = ops->write_emulated(
(unsigned long)c->dst.ptr,
&c->dst.val,
c->dst.bytes,
&err,
ctxt->vcpu);
if (rc == X86EMUL_PROPAGATE_FAULT)
emulate_pf(ctxt,
(unsigned long)c->dst.ptr, err);
if (rc != X86EMUL_CONTINUE)
return rc;
break;
case OP_NONE:
/* no writeback */
break;
default:
break;
}
return X86EMUL_CONTINUE;
}

static inline void
setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops, struct desc_struct *cs,
Expand Down Expand Up @@ -2689,7 +2700,9 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
goto done;
break;
case 0x60: /* pusha */
emulate_pusha(ctxt, ops);
rc = emulate_pusha(ctxt, ops);
if (rc != X86EMUL_CONTINUE)
goto done;
break;
case 0x61: /* popa */
rc = emulate_popa(ctxt, ops);
Expand Down

0 comments on commit 31fd517

Please sign in to comment.