KVM: Change the emulator_{read,write,cmpxchg}_* functions to take a vcpu
... instead of a x86_emulate_ctxt, so that other callers can use it easily. Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
0e5017d4ae
commit
cebff02b11
@ -1020,9 +1020,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
|
|||||||
static int emulator_read_std(unsigned long addr,
|
static int emulator_read_std(unsigned long addr,
|
||||||
void *val,
|
void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt *ctxt)
|
struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
|
||||||
void *data = val;
|
void *data = val;
|
||||||
|
|
||||||
while (bytes) {
|
while (bytes) {
|
||||||
@ -1056,7 +1055,7 @@ static int emulator_read_std(unsigned long addr,
|
|||||||
static int emulator_write_std(unsigned long addr,
|
static int emulator_write_std(unsigned long addr,
|
||||||
const void *val,
|
const void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt *ctxt)
|
struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "emulator_write_std: addr %lx n %d\n",
|
printk(KERN_ERR "emulator_write_std: addr %lx n %d\n",
|
||||||
addr, bytes);
|
addr, bytes);
|
||||||
@ -1083,9 +1082,8 @@ static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
|
|||||||
static int emulator_read_emulated(unsigned long addr,
|
static int emulator_read_emulated(unsigned long addr,
|
||||||
void *val,
|
void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt *ctxt)
|
struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
|
||||||
struct kvm_io_device *mmio_dev;
|
struct kvm_io_device *mmio_dev;
|
||||||
gpa_t gpa;
|
gpa_t gpa;
|
||||||
|
|
||||||
@ -1093,7 +1091,7 @@ static int emulator_read_emulated(unsigned long addr,
|
|||||||
memcpy(val, vcpu->mmio_data, bytes);
|
memcpy(val, vcpu->mmio_data, bytes);
|
||||||
vcpu->mmio_read_completed = 0;
|
vcpu->mmio_read_completed = 0;
|
||||||
return X86EMUL_CONTINUE;
|
return X86EMUL_CONTINUE;
|
||||||
} else if (emulator_read_std(addr, val, bytes, ctxt)
|
} else if (emulator_read_std(addr, val, bytes, vcpu)
|
||||||
== X86EMUL_CONTINUE)
|
== X86EMUL_CONTINUE)
|
||||||
return X86EMUL_CONTINUE;
|
return X86EMUL_CONTINUE;
|
||||||
|
|
||||||
@ -1140,9 +1138,8 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
|
|||||||
static int emulator_write_emulated_onepage(unsigned long addr,
|
static int emulator_write_emulated_onepage(unsigned long addr,
|
||||||
const void *val,
|
const void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt *ctxt)
|
struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
|
||||||
struct kvm_io_device *mmio_dev;
|
struct kvm_io_device *mmio_dev;
|
||||||
gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
|
gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
|
||||||
|
|
||||||
@ -1175,28 +1172,28 @@ static int emulator_write_emulated_onepage(unsigned long addr,
|
|||||||
static int emulator_write_emulated(unsigned long addr,
|
static int emulator_write_emulated(unsigned long addr,
|
||||||
const void *val,
|
const void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt *ctxt)
|
struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
/* Crossing a page boundary? */
|
/* Crossing a page boundary? */
|
||||||
if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
|
if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
|
||||||
int rc, now;
|
int rc, now;
|
||||||
|
|
||||||
now = -addr & ~PAGE_MASK;
|
now = -addr & ~PAGE_MASK;
|
||||||
rc = emulator_write_emulated_onepage(addr, val, now, ctxt);
|
rc = emulator_write_emulated_onepage(addr, val, now, vcpu);
|
||||||
if (rc != X86EMUL_CONTINUE)
|
if (rc != X86EMUL_CONTINUE)
|
||||||
return rc;
|
return rc;
|
||||||
addr += now;
|
addr += now;
|
||||||
val += now;
|
val += now;
|
||||||
bytes -= now;
|
bytes -= now;
|
||||||
}
|
}
|
||||||
return emulator_write_emulated_onepage(addr, val, bytes, ctxt);
|
return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emulator_cmpxchg_emulated(unsigned long addr,
|
static int emulator_cmpxchg_emulated(unsigned long addr,
|
||||||
const void *old,
|
const void *old,
|
||||||
const void *new,
|
const void *new,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt *ctxt)
|
struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
static int reported;
|
static int reported;
|
||||||
|
|
||||||
@ -1204,7 +1201,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
|
|||||||
reported = 1;
|
reported = 1;
|
||||||
printk(KERN_WARNING "kvm: emulating exchange as write\n");
|
printk(KERN_WARNING "kvm: emulating exchange as write\n");
|
||||||
}
|
}
|
||||||
return emulator_write_emulated(addr, new, bytes, ctxt);
|
return emulator_write_emulated(addr, new, bytes, vcpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
|
static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
|
||||||
@ -1266,7 +1263,7 @@ static void report_emulation_failure(struct x86_emulate_ctxt *ctxt)
|
|||||||
if (reported)
|
if (reported)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt);
|
emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt->vcpu);
|
||||||
|
|
||||||
printk(KERN_ERR "emulation failed but !mmio_needed?"
|
printk(KERN_ERR "emulation failed but !mmio_needed?"
|
||||||
" rip %lx %02x %02x %02x %02x\n",
|
" rip %lx %02x %02x %02x %02x\n",
|
||||||
|
@ -420,7 +420,7 @@ struct operand {
|
|||||||
#define insn_fetch(_type, _size, _eip) \
|
#define insn_fetch(_type, _size, _eip) \
|
||||||
({ unsigned long _x; \
|
({ unsigned long _x; \
|
||||||
rc = ops->read_std((unsigned long)(_eip) + ctxt->cs_base, &_x, \
|
rc = ops->read_std((unsigned long)(_eip) + ctxt->cs_base, &_x, \
|
||||||
(_size), ctxt); \
|
(_size), ctxt->vcpu); \
|
||||||
if ( rc != 0 ) \
|
if ( rc != 0 ) \
|
||||||
goto done; \
|
goto done; \
|
||||||
(_eip) += (_size); \
|
(_eip) += (_size); \
|
||||||
@ -469,10 +469,12 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
|
|||||||
if (op_bytes == 2)
|
if (op_bytes == 2)
|
||||||
op_bytes = 3;
|
op_bytes = 3;
|
||||||
*address = 0;
|
*address = 0;
|
||||||
rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, ctxt);
|
rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
|
||||||
|
ctxt->vcpu);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, ctxt);
|
rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
|
||||||
|
ctxt->vcpu);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,7 +782,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
src.type = OP_MEM;
|
src.type = OP_MEM;
|
||||||
src.ptr = (unsigned long *)cr2;
|
src.ptr = (unsigned long *)cr2;
|
||||||
if ((rc = ops->read_emulated((unsigned long)src.ptr,
|
if ((rc = ops->read_emulated((unsigned long)src.ptr,
|
||||||
&src.val, src.bytes, ctxt)) != 0)
|
&src.val, src.bytes, ctxt->vcpu)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
src.orig_val = src.val;
|
src.orig_val = src.val;
|
||||||
break;
|
break;
|
||||||
@ -850,7 +852,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
}
|
}
|
||||||
if (!(d & Mov) && /* optimisation - avoid slow emulated read */
|
if (!(d & Mov) && /* optimisation - avoid slow emulated read */
|
||||||
((rc = ops->read_emulated((unsigned long)dst.ptr,
|
((rc = ops->read_emulated((unsigned long)dst.ptr,
|
||||||
&dst.val, dst.bytes, ctxt)) != 0))
|
&dst.val, dst.bytes, ctxt->vcpu)) != 0))
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -963,7 +965,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
dst.bytes = 8;
|
dst.bytes = 8;
|
||||||
if ((rc = ops->read_std(register_address(ctxt->ss_base,
|
if ((rc = ops->read_std(register_address(ctxt->ss_base,
|
||||||
_regs[VCPU_REGS_RSP]),
|
_regs[VCPU_REGS_RSP]),
|
||||||
&dst.val, dst.bytes, ctxt)) != 0)
|
&dst.val, dst.bytes, ctxt->vcpu)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
register_address_increment(_regs[VCPU_REGS_RSP], dst.bytes);
|
register_address_increment(_regs[VCPU_REGS_RSP], dst.bytes);
|
||||||
break;
|
break;
|
||||||
@ -1048,7 +1050,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
dst.bytes = 8;
|
dst.bytes = 8;
|
||||||
if ((rc = ops->read_std((unsigned long)dst.ptr,
|
if ((rc = ops->read_std((unsigned long)dst.ptr,
|
||||||
&dst.val, 8,
|
&dst.val, 8,
|
||||||
ctxt)) != 0)
|
ctxt->vcpu)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
register_address_increment(_regs[VCPU_REGS_RSP],
|
register_address_increment(_regs[VCPU_REGS_RSP],
|
||||||
@ -1056,7 +1058,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
if ((rc = ops->write_std(
|
if ((rc = ops->write_std(
|
||||||
register_address(ctxt->ss_base,
|
register_address(ctxt->ss_base,
|
||||||
_regs[VCPU_REGS_RSP]),
|
_regs[VCPU_REGS_RSP]),
|
||||||
&dst.val, dst.bytes, ctxt)) != 0)
|
&dst.val, dst.bytes, ctxt->vcpu)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
no_wb = 1;
|
no_wb = 1;
|
||||||
break;
|
break;
|
||||||
@ -1091,11 +1093,11 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
rc = ops->cmpxchg_emulated((unsigned long)dst.
|
rc = ops->cmpxchg_emulated((unsigned long)dst.
|
||||||
ptr, &dst.orig_val,
|
ptr, &dst.orig_val,
|
||||||
&dst.val, dst.bytes,
|
&dst.val, dst.bytes,
|
||||||
ctxt);
|
ctxt->vcpu);
|
||||||
else
|
else
|
||||||
rc = ops->write_emulated((unsigned long)dst.ptr,
|
rc = ops->write_emulated((unsigned long)dst.ptr,
|
||||||
&dst.val, dst.bytes,
|
&dst.val, dst.bytes,
|
||||||
ctxt);
|
ctxt->vcpu);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
goto done;
|
goto done;
|
||||||
default:
|
default:
|
||||||
@ -1130,7 +1132,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
_regs[VCPU_REGS_RDI]);
|
_regs[VCPU_REGS_RDI]);
|
||||||
if ((rc = ops->read_emulated(register_address(
|
if ((rc = ops->read_emulated(register_address(
|
||||||
override_base ? *override_base : ctxt->ds_base,
|
override_base ? *override_base : ctxt->ds_base,
|
||||||
_regs[VCPU_REGS_RSI]), &dst.val, dst.bytes, ctxt)) != 0)
|
_regs[VCPU_REGS_RSI]), &dst.val, dst.bytes, ctxt->vcpu)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
register_address_increment(_regs[VCPU_REGS_RSI],
|
register_address_increment(_regs[VCPU_REGS_RSI],
|
||||||
(_eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
|
(_eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
|
||||||
@ -1152,7 +1154,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
dst.type = OP_REG;
|
dst.type = OP_REG;
|
||||||
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
|
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
|
||||||
dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX];
|
dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX];
|
||||||
if ((rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0)
|
if ((rc = ops->read_emulated(cr2, &dst.val, dst.bytes,
|
||||||
|
ctxt->vcpu)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
register_address_increment(_regs[VCPU_REGS_RSI],
|
register_address_increment(_regs[VCPU_REGS_RSI],
|
||||||
(_eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
|
(_eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
|
||||||
@ -1171,7 +1174,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
|
|
||||||
pop_instruction:
|
pop_instruction:
|
||||||
if ((rc = ops->read_std(register_address(ctxt->ss_base,
|
if ((rc = ops->read_std(register_address(ctxt->ss_base,
|
||||||
_regs[VCPU_REGS_RSP]), dst.ptr, op_bytes, ctxt)) != 0)
|
_regs[VCPU_REGS_RSP]), dst.ptr, op_bytes, ctxt->vcpu))
|
||||||
|
!= 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
|
register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
|
||||||
@ -1378,7 +1382,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
case 0xc7: /* Grp9 (cmpxchg8b) */
|
case 0xc7: /* Grp9 (cmpxchg8b) */
|
||||||
{
|
{
|
||||||
u64 old, new;
|
u64 old, new;
|
||||||
if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0)
|
if ((rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu))
|
||||||
|
!= 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) ||
|
if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) ||
|
||||||
((u32) (old >> 32) != (u32) _regs[VCPU_REGS_RDX])) {
|
((u32) (old >> 32) != (u32) _regs[VCPU_REGS_RDX])) {
|
||||||
@ -1389,7 +1394,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
|||||||
new = ((u64)_regs[VCPU_REGS_RCX] << 32)
|
new = ((u64)_regs[VCPU_REGS_RCX] << 32)
|
||||||
| (u32) _regs[VCPU_REGS_RBX];
|
| (u32) _regs[VCPU_REGS_RBX];
|
||||||
if ((rc = ops->cmpxchg_emulated(cr2, &old,
|
if ((rc = ops->cmpxchg_emulated(cr2, &old,
|
||||||
&new, 8, ctxt)) != 0)
|
&new, 8, ctxt->vcpu)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
_eflags |= EFLG_ZF;
|
_eflags |= EFLG_ZF;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ struct x86_emulate_ops {
|
|||||||
* @bytes: [IN ] Number of bytes to read from memory.
|
* @bytes: [IN ] Number of bytes to read from memory.
|
||||||
*/
|
*/
|
||||||
int (*read_std)(unsigned long addr, void *val,
|
int (*read_std)(unsigned long addr, void *val,
|
||||||
unsigned int bytes, struct x86_emulate_ctxt * ctxt);
|
unsigned int bytes, struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write_std: Write bytes of standard (non-emulated/special) memory.
|
* write_std: Write bytes of standard (non-emulated/special) memory.
|
||||||
@ -71,7 +71,7 @@ struct x86_emulate_ops {
|
|||||||
* @bytes: [IN ] Number of bytes to write to memory.
|
* @bytes: [IN ] Number of bytes to write to memory.
|
||||||
*/
|
*/
|
||||||
int (*write_std)(unsigned long addr, const void *val,
|
int (*write_std)(unsigned long addr, const void *val,
|
||||||
unsigned int bytes, struct x86_emulate_ctxt * ctxt);
|
unsigned int bytes, struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read_emulated: Read bytes from emulated/special memory area.
|
* read_emulated: Read bytes from emulated/special memory area.
|
||||||
@ -82,7 +82,7 @@ struct x86_emulate_ops {
|
|||||||
int (*read_emulated) (unsigned long addr,
|
int (*read_emulated) (unsigned long addr,
|
||||||
void *val,
|
void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt * ctxt);
|
struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write_emulated: Read bytes from emulated/special memory area.
|
* write_emulated: Read bytes from emulated/special memory area.
|
||||||
@ -94,7 +94,7 @@ struct x86_emulate_ops {
|
|||||||
int (*write_emulated) (unsigned long addr,
|
int (*write_emulated) (unsigned long addr,
|
||||||
const void *val,
|
const void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt * ctxt);
|
struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
|
* cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
|
||||||
@ -108,7 +108,7 @@ struct x86_emulate_ops {
|
|||||||
const void *old,
|
const void *old,
|
||||||
const void *new,
|
const void *new,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
struct x86_emulate_ctxt * ctxt);
|
struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user