# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 41de9cd7971b565dd3286ce499a6b8063f6d686c
# Parent 79d74ce206bbd4a4bfc5fa4890b442522da03223
Change the x86_emulate() interface to pack all context arguments
into a context structure. This context can then be handed to
callback operations.
Based on an original patch from Mats Petersson <mats.petersson@xxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
tools/tests/test_x86_emulator.c | 67 ++++++++++++++++++++------------------
xen/arch/x86/mm.c | 31 ++++++++++-------
xen/arch/x86/x86_emulate.c | 67 ++++++++++++++++++++------------------
xen/include/asm-x86/x86_emulate.h | 66 +++++++++++++++++++++++--------------
4 files changed, 133 insertions(+), 98 deletions(-)
diff -r 79d74ce206bb -r 41de9cd7971b tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c Thu May 25 14:54:43 2006 +0100
+++ b/tools/tests/test_x86_emulator.c Thu May 25 15:52:38 2006 +0100
@@ -17,7 +17,8 @@ static int read_any(
static int read_any(
unsigned long addr,
unsigned long *val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
switch ( bytes )
{
@@ -32,7 +33,8 @@ static int write_any(
static int write_any(
unsigned long addr,
unsigned long val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
switch ( bytes )
{
@@ -48,7 +50,8 @@ static int cmpxchg_any(
unsigned long addr,
unsigned long old,
unsigned long new,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
switch ( bytes )
{
@@ -65,34 +68,38 @@ static int cmpxchg8b_any(
unsigned long old_lo,
unsigned long old_hi,
unsigned long new_lo,
- unsigned long new_hi)
+ unsigned long new_hi,
+ struct x86_emulate_ctxt *ctxt)
{
((unsigned long *)addr)[0] = new_lo;
((unsigned long *)addr)[1] = new_hi;
return X86EMUL_CONTINUE;
}
-static struct x86_mem_emulator emulops = {
+static struct x86_emulate_ops emulops = {
read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any
};
int main(int argc, char **argv)
{
+ struct x86_emulate_ctxt ctxt;
struct cpu_user_regs regs;
char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
unsigned int res = 0x7FFFFFFF;
u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 };
- unsigned long cr2;
int rc;
+
+ ctxt.regs = ®s;
+ ctxt.mode = X86EMUL_MODE_PROT32;
printf("%-40s", "Testing addl %%ecx,(%%eax)...");
instr[0] = 0x01; instr[1] = 0x08;
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
+ ctxt.cr2 = (unsigned long)&res;
res = 0x7FFFFFFF;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x92345677) ||
(regs.eflags != 0xa94) ||
@@ -109,8 +116,8 @@ int main(int argc, char **argv)
#else
regs.ecx = 0x12345678UL;
#endif
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x92345677) ||
(regs.ecx != 0x8000000FUL) ||
@@ -124,8 +131,8 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.eax = 0x92345677UL;
regs.ecx = 0xAA;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x923456AA) ||
(regs.eflags != 0x244) ||
@@ -140,8 +147,8 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.eax = 0xAABBCC77UL;
regs.ecx = 0xFF;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x923456AA) ||
((regs.eflags&0x240) != 0x200) ||
@@ -156,8 +163,8 @@ int main(int argc, char **argv)
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x12345678) ||
(regs.eflags != 0x200) ||
@@ -173,8 +180,8 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.eax = 0x923456AAUL;
regs.ecx = 0xDDEEFF00L;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0xDDEEFF00) ||
(regs.eflags != 0x244) ||
@@ -192,8 +199,8 @@ int main(int argc, char **argv)
regs.esi = (unsigned long)&res + 0;
regs.edi = (unsigned long)&res + 2;
regs.error_code = 0; /* read fault */
- cr2 = regs.esi;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.esi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x44554455) ||
(regs.eflags != 0x200) ||
@@ -210,8 +217,8 @@ int main(int argc, char **argv)
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)&res;
- cr2 = regs.edi;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.edi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x2233445D) ||
((regs.eflags&0x201) != 0x201) ||
@@ -228,8 +235,8 @@ int main(int argc, char **argv)
regs.ecx = 0xCCCCFFFF;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)cmpxchg8b_res;
- cr2 = regs.edi;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.edi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
@@ -242,8 +249,8 @@ int main(int argc, char **argv)
instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)cmpxchg8b_res;
- cr2 = regs.edi;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.edi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
@@ -258,9 +265,9 @@ int main(int argc, char **argv)
instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
+ ctxt.cr2 = (unsigned long)&res;
res = 0x82;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x82) ||
(regs.ecx != 0xFFFFFF82) ||
@@ -273,9 +280,9 @@ int main(int argc, char **argv)
instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
+ ctxt.cr2 = (unsigned long)&res;
res = 0x1234aa82;
- rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x1234aa82) ||
(regs.ecx != 0xaa82) ||
diff -r 79d74ce206bb -r 41de9cd7971b xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu May 25 14:54:43 2006 +0100
+++ b/xen/arch/x86/mm.c Thu May 25 15:52:38 2006 +0100
@@ -3220,15 +3220,16 @@ static int ptwr_emulated_update(
/* Turn a sub-word access into a full-word access. */
if ( bytes != sizeof(paddr_t) )
{
- int rc;
- paddr_t full;
- unsigned int offset = addr & (sizeof(paddr_t)-1);
+ paddr_t full;
+ unsigned int offset = addr & (sizeof(paddr_t)-1);
/* Align address; read full word. */
addr &= ~(sizeof(paddr_t)-1);
- if ( (rc = x86_emulate_read_std(addr, (unsigned long *)&full,
- sizeof(paddr_t))) )
- return rc;
+ if ( copy_from_user(&full, (void *)addr, sizeof(paddr_t)) )
+ {
+ propagate_page_fault(addr, 4); /* user mode, read fault */
+ return X86EMUL_PROPAGATE_FAULT;
+ }
/* Mask out bits provided by caller. */
full &= ~((((paddr_t)1 << (bytes*8)) - 1) << (offset*8));
/* Shift the caller value and OR in the missing bits. */
@@ -3306,7 +3307,8 @@ static int ptwr_emulated_write(
static int ptwr_emulated_write(
unsigned long addr,
unsigned long val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
return ptwr_emulated_update(addr, 0, val, bytes, 0);
}
@@ -3315,7 +3317,8 @@ static int ptwr_emulated_cmpxchg(
unsigned long addr,
unsigned long old,
unsigned long new,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
return ptwr_emulated_update(addr, old, new, bytes, 1);
}
@@ -3325,7 +3328,8 @@ static int ptwr_emulated_cmpxchg8b(
unsigned long old,
unsigned long old_hi,
unsigned long new,
- unsigned long new_hi)
+ unsigned long new_hi,
+ struct x86_emulate_ctxt *ctxt)
{
if ( CONFIG_PAGING_LEVELS == 2 )
return X86EMUL_UNHANDLEABLE;
@@ -3334,7 +3338,7 @@ static int ptwr_emulated_cmpxchg8b(
addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1);
}
-static struct x86_mem_emulator ptwr_mem_emulator = {
+static struct x86_emulate_ops ptwr_emulate_ops = {
.read_std = x86_emulate_read_std,
.write_std = x86_emulate_write_std,
.read_emulated = x86_emulate_read_std,
@@ -3353,6 +3357,7 @@ int ptwr_do_page_fault(struct domain *d,
l2_pgentry_t *pl2e, l2e;
int which, flags;
unsigned long l2_idx;
+ struct x86_emulate_ctxt emul_ctxt;
if ( unlikely(shadow_mode_enabled(d)) )
return 0;
@@ -3507,8 +3512,10 @@ int ptwr_do_page_fault(struct domain *d,
return EXCRET_fault_fixed;
emulate:
- if ( x86_emulate_memop(guest_cpu_user_regs(), addr,
- &ptwr_mem_emulator, X86EMUL_MODE_HOST) )
+ emul_ctxt.regs = guest_cpu_user_regs();
+ emul_ctxt.cr2 = addr;
+ emul_ctxt.mode = X86EMUL_MODE_HOST;
+ if ( x86_emulate_memop(&emul_ctxt, &ptwr_emulate_ops) )
return 0;
perfc_incrc(ptwr_emulations);
return EXCRET_fault_fixed;
diff -r 79d74ce206bb -r 41de9cd7971b xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Thu May 25 14:54:43 2006 +0100
+++ b/xen/arch/x86/x86_emulate.c Thu May 25 15:52:38 2006 +0100
@@ -363,12 +363,13 @@ do{ __asm__ __volatile__ (
#endif /* __i386__ */
/* Fetch next part of the instruction being emulated. */
-#define insn_fetch(_type, _size, _eip) \
-({ unsigned long _x; \
- if ( (rc = ops->read_std((unsigned long)(_eip), &_x, (_size))) != 0 ) \
- goto done; \
- (_eip) += (_size); \
- (_type)_x; \
+#define insn_fetch(_type, _size, _eip) \
+({ unsigned long _x; \
+ rc = ops->read_std((unsigned long)(_eip), &_x, (_size), ctxt); \
+ if ( rc != 0 ) \
+ goto done; \
+ (_eip) += (_size); \
+ (_type)_x; \
})
/* Access/update address held in a register, based on addressing mode. */
@@ -426,12 +427,10 @@ decode_register(
return p;
}
-int
+int
x86_emulate_memop(
- struct cpu_user_regs *regs,
- unsigned long cr2,
- struct x86_mem_emulator *ops,
- int mode)
+ struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops)
{
uint8_t b, d, sib, twobyte = 0, rex_prefix = 0;
uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
@@ -439,9 +438,11 @@ x86_emulate_memop(
unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
int rc = 0;
struct operand src, dst;
+ unsigned long cr2 = ctxt->cr2;
+ int mode = ctxt->mode;
/* Shadow copy of register state. Committed on successful emulation. */
- struct cpu_user_regs _regs = *regs;
+ struct cpu_user_regs _regs = *ctxt->regs;
switch ( mode )
{
@@ -628,7 +629,7 @@ x86_emulate_memop(
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
((rc = ops->read_emulated((unsigned long)dst.ptr,
- &dst.val, dst.bytes)) != 0) )
+ &dst.val, dst.bytes, ctxt)) != 0) )
goto done;
break;
}
@@ -670,7 +671,7 @@ x86_emulate_memop(
src.type = OP_MEM;
src.ptr = (unsigned long *)cr2;
if ( (rc = ops->read_emulated((unsigned long)src.ptr,
- &src.val, src.bytes)) != 0 )
+ &src.val, src.bytes, ctxt)) != 0 )
goto done;
src.orig_val = src.val;
break;
@@ -776,7 +777,7 @@ x86_emulate_memop(
if ( mode == X86EMUL_MODE_PROT64 )
dst.bytes = 8;
if ( (rc = ops->read_std(register_address(_regs.ss, _regs.esp),
- &dst.val, dst.bytes)) != 0 )
+ &dst.val, dst.bytes, ctxt)) != 0 )
goto done;
register_address_increment(_regs.esp, dst.bytes);
break;
@@ -854,12 +855,12 @@ x86_emulate_memop(
{
dst.bytes = 8;
if ( (rc = ops->read_std((unsigned long)dst.ptr,
- &dst.val, 8)) != 0 )
+ &dst.val, 8, ctxt)) != 0 )
goto done;
}
register_address_increment(_regs.esp, -dst.bytes);
if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp),
- dst.val, dst.bytes)) != 0 )
+ dst.val, dst.bytes, ctxt)) != 0 )
goto done;
dst.val = dst.orig_val; /* skanky: disable writeback */
break;
@@ -887,10 +888,11 @@ x86_emulate_memop(
case OP_MEM:
if ( lock_prefix )
rc = ops->cmpxchg_emulated(
- (unsigned long)dst.ptr, dst.orig_val, dst.val, dst.bytes);
+ (unsigned long)dst.ptr, dst.orig_val,
+ dst.val, dst.bytes, ctxt);
else
rc = ops->write_emulated(
- (unsigned long)dst.ptr, dst.val, dst.bytes);
+ (unsigned long)dst.ptr, dst.val, dst.bytes, ctxt);
if ( rc != 0 )
goto done;
default:
@@ -899,7 +901,7 @@ x86_emulate_memop(
}
/* Commit shadow register state. */
- *regs = _regs;
+ *ctxt->regs = _regs;
done:
return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
@@ -911,11 +913,11 @@ x86_emulate_memop(
{
if ( _regs.ecx == 0 )
{
- regs->eip = _regs.eip;
+ ctxt->regs->eip = _regs.eip;
goto done;
}
_regs.ecx--;
- _regs.eip = regs->eip;
+ _regs.eip = ctxt->regs->eip;
}
switch ( b )
{
@@ -928,14 +930,15 @@ x86_emulate_memop(
dst.ptr = (unsigned long *)cr2;
if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds,
_regs.esi),
- &dst.val, dst.bytes)) != 0 )
+ &dst.val, dst.bytes, ctxt)) != 0 )
goto done;
}
else
{
/* Read fault: source is special memory. */
dst.ptr = (unsigned long *)register_address(_regs.es, _regs.edi);
- if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
+ if ( (rc = ops->read_emulated(cr2, &dst.val,
+ dst.bytes, ctxt)) != 0 )
goto done;
}
register_address_increment(
@@ -958,7 +961,7 @@ x86_emulate_memop(
dst.type = OP_REG;
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
dst.ptr = (unsigned long *)&_regs.eax;
- if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
+ if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0 )
goto done;
register_address_increment(
_regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
@@ -1074,8 +1077,8 @@ x86_emulate_memop(
#if defined(__i386__)
{
unsigned long old_lo, old_hi;
- if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4)) != 0) ||
- ((rc = ops->read_emulated(cr2+4, &old_hi, 4)) != 0) )
+ if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4, ctxt)) != 0) ||
+ ((rc = ops->read_emulated(cr2+4, &old_hi, 4, ctxt)) != 0) )
goto done;
if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) )
{
@@ -1090,8 +1093,8 @@ x86_emulate_memop(
}
else
{
- if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi,
- _regs.ebx, _regs.ecx)) != 0 )
+ if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi, _regs.ebx,
+ _regs.ecx, ctxt)) != 0 )
goto done;
_regs.eflags |= EFLG_ZF;
}
@@ -1136,7 +1139,8 @@ x86_emulate_read_std(
x86_emulate_read_std(
unsigned long addr,
unsigned long *val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
*val = 0;
if ( copy_from_user((void *)val, (void *)addr, bytes) )
@@ -1151,7 +1155,8 @@ x86_emulate_write_std(
x86_emulate_write_std(
unsigned long addr,
unsigned long val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
if ( copy_to_user((void *)addr, (void *)&val, bytes) )
{
diff -r 79d74ce206bb -r 41de9cd7971b xen/include/asm-x86/x86_emulate.h
--- a/xen/include/asm-x86/x86_emulate.h Thu May 25 14:54:43 2006 +0100
+++ b/xen/include/asm-x86/x86_emulate.h Thu May 25 15:52:38 2006 +0100
@@ -9,8 +9,10 @@
#ifndef __X86_EMULATE_H__
#define __X86_EMULATE_H__
-/*
- * x86_mem_emulator:
+struct x86_emulate_ctxt;
+
+/*
+ * x86_emulate_ops:
*
* These operations represent the instruction emulator's interface to memory.
* There are two categories of operation: those that act on ordinary memory
@@ -47,7 +49,7 @@
#define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
#define X86EMUL_RETRY_INSTR 2 /* retry the instruction for some reason */
#define X86EMUL_CMPXCHG_FAILED 2 /* cmpxchg did not see expected value */
-struct x86_mem_emulator
+struct x86_emulate_ops
{
/*
* read_std: Read bytes of standard (non-emulated/special) memory.
@@ -59,7 +61,8 @@ struct x86_mem_emulator
int (*read_std)(
unsigned long addr,
unsigned long *val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
/*
* write_std: Write bytes of standard (non-emulated/special) memory.
@@ -71,7 +74,8 @@ struct x86_mem_emulator
int (*write_std)(
unsigned long addr,
unsigned long val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
/*
* read_emulated: Read bytes from emulated/special memory area.
@@ -82,7 +86,8 @@ struct x86_mem_emulator
int (*read_emulated)(
unsigned long addr,
unsigned long *val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
/*
* write_emulated: Read bytes from emulated/special memory area.
@@ -93,7 +98,8 @@ struct x86_mem_emulator
int (*write_emulated)(
unsigned long addr,
unsigned long val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
/*
* cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
@@ -107,11 +113,12 @@ struct x86_mem_emulator
unsigned long addr,
unsigned long old,
unsigned long new,
- unsigned int bytes);
-
- /*
- * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
- * emulated/special memory area.
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
+
+ /*
+ * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
+ * emulated/special memory area.
* @addr: [IN ] Linear address to access.
* @old: [IN ] Value expected to be current at @addr.
* @new: [IN ] Value to write to @addr.
@@ -126,7 +133,8 @@ struct x86_mem_emulator
unsigned long old_lo,
unsigned long old_hi,
unsigned long new_lo,
- unsigned long new_hi);
+ unsigned long new_hi,
+ struct x86_emulate_ctxt *ctxt);
};
/* Standard reader/writer functions that callers may wish to use. */
@@ -134,14 +142,28 @@ x86_emulate_read_std(
x86_emulate_read_std(
unsigned long addr,
unsigned long *val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
extern int
x86_emulate_write_std(
unsigned long addr,
unsigned long val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
struct cpu_user_regs;
+
+struct x86_emulate_ctxt
+{
+ /* Register state before/after emulation. */
+ struct cpu_user_regs *regs;
+
+ /* Linear faulting address (if emulating a page-faulting instruction). */
+ unsigned long cr2;
+
+ /* Emulated execution mode, represented by an X86EMUL_MODE value. */
+ int mode;
+};
/* Execution mode, passed to the emulator. */
#define X86EMUL_MODE_REAL 0 /* Real mode. */
@@ -159,25 +181,19 @@ struct cpu_user_regs;
/*
* x86_emulate_memop: Emulate an instruction that faulted attempting to
* read/write a 'special' memory area.
- * @regs: Register state at time of fault.
- * @cr2: Linear faulting address within an emulated/special memory area.
- * @ops: Interface to access special memory.
- * @mode: Emulated execution mode, represented by an X86EMUL_MODE value.
* Returns -1 on failure, 0 on success.
*/
-extern int
+int
x86_emulate_memop(
- struct cpu_user_regs *regs,
- unsigned long cr2,
- struct x86_mem_emulator *ops,
- int mode);
+ struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops);
/*
* Given the 'reg' portion of a ModRM byte, and a register block, return a
* pointer into the block that addresses the relevant register.
* @highbyte_regs specifies whether to decode AH,CH,DH,BH.
*/
-extern void *
+void *
decode_register(
uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|