HV: instr_emul: Unify params passing to emulate_xxx

There are so many __unused prefix spaning the emulate_xxx functions. This patch
unify the parameters of emulate_xxx to avoid it.

  - All emulate_xxx functions are defined as emulate_xxx(struct vcpu *vcpu, instr_emul_vie *vie)
    or emulate_xxx(struct vcpu *vcpu, instr_emul_vie *vie, struct vm_guest_paging *paging).

  - Move mmio_read/write to instr_emul.c and call them directly.

Signed-off-by: Kaige Fu <kaige.fu@intel.com>
Reviewed-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
Kaige Fu 2018-07-31 15:57:02 +08:00 committed by lijinxia
parent cebc8d9a01
commit 8836abef21
3 changed files with 96 additions and 200 deletions

View File

@ -191,6 +191,26 @@ static uint64_t size2mask[9] = {
[8] = ~0UL, [8] = ~0UL,
}; };
static int mmio_read(struct vcpu *vcpu, uint64_t *rval)
{
if (vcpu == NULL) {
return -EINVAL;
}
*rval = vcpu->req.reqs.mmio.value;
return 0;
}
static int mmio_write(struct vcpu *vcpu, uint64_t wval)
{
if (vcpu == NULL) {
return -EINVAL;
}
vcpu->req.reqs.mmio.value = wval;
return 0;
}
static void static void
vie_calc_bytereg(struct instr_emul_vie *vie, enum cpu_reg_name *reg, int *lhbr) vie_calc_bytereg(struct instr_emul_vie *vie, enum cpu_reg_name *reg, int *lhbr)
{ {
@ -355,10 +375,7 @@ getcc(uint8_t opsize, uint64_t x, uint64_t y)
} }
} }
static int static int emulate_mov(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, mem_region_write_t memwrite,
void *arg)
{ {
int error; int error;
uint8_t size; uint8_t size;
@ -378,8 +395,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
size = 1U; /* override for byte operation */ size = 1U; /* override for byte operation */
error = vie_read_bytereg(vcpu, vie, &byte); error = vie_read_bytereg(vcpu, vie, &byte);
if (error == 0) { if (error == 0) {
error = memwrite(vcpu, gpa, byte, size, error = mmio_write(vcpu, byte);
arg);
} }
break; break;
case 0x89U: case 0x89U:
@ -394,8 +410,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
error = vm_get_register(vcpu, reg, &val); error = vm_get_register(vcpu, reg, &val);
if (error == 0) { if (error == 0) {
val &= size2mask[size]; val &= size2mask[size];
error = memwrite(vcpu, gpa, val, size, error = mmio_write(vcpu, val);
arg);
} }
break; break;
case 0x8AU: case 0x8AU:
@ -405,7 +420,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* REX + 8A/r: mov r8, r/m8 * REX + 8A/r: mov r8, r/m8
*/ */
size = 1U; /* override for byte operation */ size = 1U; /* override for byte operation */
error = memread(vcpu, gpa, &val, size, arg); error = mmio_read(vcpu, &val);
if (error == 0) { if (error == 0) {
error = vie_write_bytereg(vcpu, vie, (uint8_t)val); error = vie_write_bytereg(vcpu, vie, (uint8_t)val);
} }
@ -417,7 +432,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* 8B/r: mov r32, r/m32 * 8B/r: mov r32, r/m32
* REX.W 8B/r: mov r64, r/m64 * REX.W 8B/r: mov r64, r/m64
*/ */
error = memread(vcpu, gpa, &val, size, arg); error = mmio_read(vcpu, &val);
if (error == 0) { if (error == 0) {
reg = vie->reg; reg = vie->reg;
error = vie_update_register(vcpu, reg, error = vie_update_register(vcpu, reg,
@ -431,7 +446,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* A1: mov EAX, moffs32 * A1: mov EAX, moffs32
* REX.W + A1: mov RAX, moffs64 * REX.W + A1: mov RAX, moffs64
*/ */
error = memread(vcpu, gpa, &val, size, arg); error = mmio_read(vcpu, &val);
if (error == 0) { if (error == 0) {
reg = CPU_REG_RAX; reg = CPU_REG_RAX;
error = vie_update_register(vcpu, reg, error = vie_update_register(vcpu, reg,
@ -449,8 +464,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
&val); &val);
if (error == 0) { if (error == 0) {
val &= size2mask[size]; val &= size2mask[size];
error = memwrite(vcpu, gpa, val, size, error = mmio_write(vcpu, val);
arg);
} }
break; break;
case 0xC6U: case 0xC6U:
@ -460,8 +474,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* REX + C6/0 mov r/m8, imm8 * REX + C6/0 mov r/m8, imm8
*/ */
size = 1U; /* override for byte operation */ size = 1U; /* override for byte operation */
error = memwrite(vcpu, gpa, vie->immediate, size, error = mmio_write(vcpu, vie->immediate);
arg);
break; break;
case 0xC7U: case 0xC7U:
/* /*
@ -472,7 +485,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* (sign-extended to 64-bits) * (sign-extended to 64-bits)
*/ */
val = (uint64_t)vie->immediate & size2mask[size]; val = (uint64_t)vie->immediate & size2mask[size];
error = memwrite(vcpu, gpa, val, size, arg); error = mmio_write(vcpu, val);
break; break;
default: default:
break; break;
@ -481,10 +494,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return error; return error;
} }
static int static int emulate_movx(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_movx(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, __unused mem_region_write_t memwrite,
void *arg)
{ {
int error; int error;
uint8_t size; uint8_t size;
@ -506,7 +516,7 @@ emulate_movx(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
*/ */
/* get the first operand */ /* get the first operand */
error = memread(vcpu, gpa, &val, 1U, arg); error = mmio_read(vcpu, &val);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -528,7 +538,7 @@ emulate_movx(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* 0F B7/r movzx r32, r/m16 * 0F B7/r movzx r32, r/m16
* REX.W + 0F B7/r movzx r64, r/m16 * REX.W + 0F B7/r movzx r64, r/m16
*/ */
error = memread(vcpu, gpa, &val, 2U, arg); error = mmio_read(vcpu, &val);
if (error != 0) { if (error != 0) {
return error; return error;
} }
@ -551,7 +561,7 @@ emulate_movx(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
*/ */
/* get the first operand */ /* get the first operand */
error = memread(vcpu, gpa, &val, 1U, arg); error = mmio_read(vcpu, &val);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -632,12 +642,8 @@ guest_fault:
return 0; return 0;
} }
static int static int emulate_movs(struct vcpu *vcpu, struct instr_emul_vie *vie,
emulate_movs(struct vcpu *vcpu, __unused uint64_t gpa, struct instr_emul_vie *vie, struct vm_guest_paging *paging)
struct vm_guest_paging *paging,
__unused mem_region_read_t memread,
__unused mem_region_write_t memwrite,
__unused void *arg)
{ {
uint64_t dstaddr, srcaddr; uint64_t dstaddr, srcaddr;
uint64_t rcx, rdi, rsi, rflags; uint64_t rcx, rdi, rsi, rflags;
@ -721,11 +727,7 @@ done:
return error; return error;
} }
static int static int emulate_stos(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_stos(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
__unused struct vm_guest_paging *paging,
__unused mem_region_read_t memread,
mem_region_write_t memwrite, void *arg)
{ {
int error, repeat; int error, repeat;
uint8_t opsize; uint8_t opsize;
@ -749,7 +751,7 @@ emulate_stos(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
error = vm_get_register(vcpu, CPU_REG_RAX, &val); error = vm_get_register(vcpu, CPU_REG_RAX, &val);
error = memwrite(vcpu, gpa, val, opsize, arg); error = mmio_write(vcpu, val);
if (error != 0) { if (error != 0) {
return error; return error;
} }
@ -782,10 +784,7 @@ emulate_stos(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return 0; return 0;
} }
static int static int emulate_test(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_test(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, __unused mem_region_write_t memwrite,
void *arg)
{ {
int error; int error;
uint8_t size; uint8_t size;
@ -821,7 +820,7 @@ emulate_test(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
} }
/* get the second operand */ /* get the second operand */
error = memread(vcpu, gpa, &val2, size, arg); error = mmio_read(vcpu, &val2);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -848,10 +847,7 @@ emulate_test(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return error; return error;
} }
static int static int emulate_and(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_and(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, mem_region_write_t memwrite,
void *arg)
{ {
int error; int error;
uint8_t size; uint8_t size;
@ -880,7 +876,7 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
} }
/* get the second operand */ /* get the second operand */
error = memread(vcpu, gpa, &val2, size, arg); error = mmio_read(vcpu, &val2);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -906,7 +902,7 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
*/ */
/* get the first operand */ /* get the first operand */
error = memread(vcpu, gpa, &val1, size, arg); error = mmio_read(vcpu, &val1);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -916,7 +912,7 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* operand and write the result * operand and write the result
*/ */
result = val1 & vie->immediate; result = val1 & vie->immediate;
error = memwrite(vcpu, gpa, result, size, arg); error = mmio_write(vcpu, result);
break; break;
default: default:
break; break;
@ -937,10 +933,7 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return error; return error;
} }
static int static int emulate_or(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_or(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, mem_region_write_t memwrite,
void *arg)
{ {
int error; int error;
uint8_t size; uint8_t size;
@ -971,7 +964,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
*/ */
/* get the first operand */ /* get the first operand */
error = memread(vcpu, gpa, &val1, size, arg); error = mmio_read(vcpu, &val1);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -981,7 +974,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
* operand and write the result * operand and write the result
*/ */
result = val1 | (uint64_t)vie->immediate; result = val1 | (uint64_t)vie->immediate;
error = memwrite(vcpu, gpa, result, size, arg); error = mmio_write(vcpu, result);
break; break;
case 0x09U: case 0x09U:
/* /*
@ -992,7 +985,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
*/ */
/* get the first operand */ /* get the first operand */
error = memread(vcpu, gpa, &val1, size, arg); error = mmio_read(vcpu, &val1);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -1008,7 +1001,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
result = val1 | val2; result = val1 | val2;
result &= size2mask[size]; result &= size2mask[size];
error = memwrite(vcpu, gpa, result, size, arg); error = mmio_write(vcpu, result);
break; break;
default: default:
break; break;
@ -1029,10 +1022,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return error; return error;
} }
static int static int emulate_cmp(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, __unused mem_region_write_t memwrite,
void *arg)
{ {
int error; int error;
uint8_t size; uint8_t size;
@ -1066,7 +1056,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
} }
/* Get the memory operand */ /* Get the memory operand */
error = memread(vcpu, gpa, &memop, size, arg); error = mmio_read(vcpu, &memop);
if (error != 0) { if (error != 0) {
return error; return error;
} }
@ -1111,7 +1101,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
} }
/* get the first operand */ /* get the first operand */
error = memread(vcpu, gpa, &op1, size, arg); error = mmio_read(vcpu, &op1);
if (error != 0) { if (error != 0) {
return error; return error;
} }
@ -1127,10 +1117,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return error; return error;
} }
static int static int emulate_sub(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, __unused mem_region_write_t memwrite,
void *arg)
{ {
int error; int error;
uint8_t size; uint8_t size;
@ -1158,7 +1145,7 @@ emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
} }
/* get the second operand */ /* get the second operand */
error = memread(vcpu, gpa, &val2, size, arg); error = mmio_read(vcpu, &val2);
if (error != 0) { if (error != 0) {
break; break;
} }
@ -1182,10 +1169,8 @@ emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return error; return error;
} }
static int static int emulate_stack_op(struct vcpu *vcpu, struct instr_emul_vie *vie,
emulate_stack_op(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vie, struct vm_guest_paging *paging)
struct vm_guest_paging *paging, mem_region_read_t memread,
mem_region_write_t memwrite, void *arg)
{ {
struct seg_desc ss_desc; struct seg_desc ss_desc;
uint64_t cr0, rflags, rsp, stack_gla, stack_gpa, val; uint64_t cr0, rflags, rsp, stack_gla, stack_gpa, val;
@ -1257,11 +1242,6 @@ emulate_stack_op(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vi
return 0; return 0;
} }
/* TODO: currently emulate_instruction is only for mmio, so here
* stack_gpa actually is unused for mmio_write & mmio_read, need
* take care of data trans if stack_gpa be used for memwrite in
* the future.
*/
if (pushop != 0) { if (pushop != 0) {
err_code |= PAGE_FAULT_WR_FLAG; err_code |= PAGE_FAULT_WR_FLAG;
} }
@ -1273,14 +1253,14 @@ emulate_stack_op(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vi
return error; return error;
} }
if (pushop != 0) { if (pushop != 0) {
error = memread(vcpu, mmio_gpa, &val, size, arg); error = mmio_read(vcpu, &val);
if (error == 0) { if (error == 0) {
error = memwrite(vcpu, stack_gpa, val, size, arg); error = mmio_write(vcpu, val);
} }
} else { } else {
error = memread(vcpu, stack_gpa, &val, size, arg); error = mmio_read(vcpu, &val);
if (error == 0) { if (error == 0) {
error = memwrite(vcpu, mmio_gpa, val, size, arg); error = mmio_write(vcpu, val);
} }
rsp += size; rsp += size;
} }
@ -1293,13 +1273,9 @@ emulate_stack_op(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vi
return error; return error;
} }
static int static int emulate_push(struct vcpu *vcpu, struct instr_emul_vie *vie,
emulate_push(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vie, struct vm_guest_paging *paging)
struct vm_guest_paging *paging, mem_region_read_t memread,
mem_region_write_t memwrite, void *arg)
{ {
int error;
/* /*
* Table A-6, "Opcode Extensions", Intel SDM, Vol 2. * Table A-6, "Opcode Extensions", Intel SDM, Vol 2.
* *
@ -1310,18 +1286,12 @@ emulate_push(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vie,
return -EINVAL; return -EINVAL;
} }
error = emulate_stack_op(vcpu, mmio_gpa, vie, paging, memread, return emulate_stack_op(vcpu, vie, paging);
memwrite, arg);
return error;
} }
static int static int emulate_pop(struct vcpu *vcpu, struct instr_emul_vie *vie,
emulate_pop(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vie, struct vm_guest_paging *paging)
struct vm_guest_paging *paging, mem_region_read_t memread,
mem_region_write_t memwrite, void *arg)
{ {
int error;
/* /*
* Table A-6, "Opcode Extensions", Intel SDM, Vol 2. * Table A-6, "Opcode Extensions", Intel SDM, Vol 2.
* *
@ -1332,31 +1302,22 @@ emulate_pop(struct vcpu *vcpu, uint64_t mmio_gpa, struct instr_emul_vie *vie,
return -EINVAL; return -EINVAL;
} }
error = emulate_stack_op(vcpu, mmio_gpa, vie, paging, memread, return emulate_stack_op(vcpu, vie, paging);
memwrite, arg);
return error;
} }
static int static int emulate_group1(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_group1(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
__unused struct vm_guest_paging *paging,
mem_region_read_t memread,
mem_region_write_t memwrite, void *memarg)
{ {
int error; int error;
switch (vie->reg & 7U) { switch (vie->reg & 7U) {
case 0x1U: /* OR */ case 0x1U: /* OR */
error = emulate_or(vcpu, gpa, vie, error = emulate_or(vcpu, vie);
memread, memwrite, memarg);
break; break;
case 0x4U: /* AND */ case 0x4U: /* AND */
error = emulate_and(vcpu, gpa, vie, error = emulate_and(vcpu, vie);
memread, memwrite, memarg);
break; break;
case 0x7U: /* CMP */ case 0x7U: /* CMP */
error = emulate_cmp(vcpu, gpa, vie, error = emulate_cmp(vcpu, vie);
memread, memwrite, memarg);
break; break;
default: default:
error = EINVAL; error = EINVAL;
@ -1366,10 +1327,7 @@ emulate_group1(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return error; return error;
} }
static int static int emulate_bittest(struct vcpu *vcpu, struct instr_emul_vie *vie)
emulate_bittest(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
mem_region_read_t memread, __unused mem_region_write_t memwrite,
void *memarg)
{ {
uint64_t val, rflags, bitmask; uint64_t val, rflags, bitmask;
int error; int error;
@ -1388,7 +1346,7 @@ emulate_bittest(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
error = vm_get_register(vcpu, CPU_REG_RFLAGS, &rflags); error = vm_get_register(vcpu, CPU_REG_RFLAGS, &rflags);
error = memread(vcpu, gpa, &val, vie->opsize, memarg); error = mmio_read(vcpu, &val);
if (error != 0) { if (error != 0) {
return error; return error;
} }
@ -1412,11 +1370,11 @@ emulate_bittest(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
return 0; return 0;
} }
int int vmm_emulate_instruction(struct instr_emul_ctxt *ctxt)
vmm_emulate_instruction(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
struct vm_guest_paging *paging, mem_region_read_t memread,
mem_region_write_t memwrite, void *memarg)
{ {
struct vm_guest_paging *paging = &ctxt->paging;
struct instr_emul_vie *vie = &ctxt->vie;
struct vcpu *vcpu = ctxt->vcpu;
int error; int error;
if (vie->decoded == 0U) { if (vie->decoded == 0U) {
@ -1424,57 +1382,44 @@ vmm_emulate_instruction(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *
} }
switch (vie->op.op_type) { switch (vie->op.op_type) {
case VIE_OP_TYPE_GROUP1: case VIE_OP_TYPE_GROUP1:
error = emulate_group1(vcpu, gpa, vie, paging, error = emulate_group1(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_POP: case VIE_OP_TYPE_POP:
error = emulate_pop(vcpu, gpa, vie, paging, error = emulate_pop(vcpu, vie, paging);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_PUSH: case VIE_OP_TYPE_PUSH:
error = emulate_push(vcpu, gpa, vie, paging, error = emulate_push(vcpu, vie, paging);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_CMP: case VIE_OP_TYPE_CMP:
error = emulate_cmp(vcpu, gpa, vie, error = emulate_cmp(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_MOV: case VIE_OP_TYPE_MOV:
error = emulate_mov(vcpu, gpa, vie, error = emulate_mov(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_MOVSX: case VIE_OP_TYPE_MOVSX:
case VIE_OP_TYPE_MOVZX: case VIE_OP_TYPE_MOVZX:
error = emulate_movx(vcpu, gpa, vie, error = emulate_movx(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_MOVS: case VIE_OP_TYPE_MOVS:
error = emulate_movs(vcpu, gpa, vie, paging, error = emulate_movs(vcpu, vie, paging);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_STOS: case VIE_OP_TYPE_STOS:
error = emulate_stos(vcpu, gpa, vie, paging, error = emulate_stos(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_AND: case VIE_OP_TYPE_AND:
error = emulate_and(vcpu, gpa, vie, error = emulate_and(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_TEST: case VIE_OP_TYPE_TEST:
error = emulate_test(vcpu, gpa, vie, error = emulate_test(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_OR: case VIE_OP_TYPE_OR:
error = emulate_or(vcpu, gpa, vie, error = emulate_or(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_SUB: case VIE_OP_TYPE_SUB:
error = emulate_sub(vcpu, gpa, vie, error = emulate_sub(vcpu, vie);
memread, memwrite, memarg);
break; break;
case VIE_OP_TYPE_BITTEST: case VIE_OP_TYPE_BITTEST:
error = emulate_bittest(vcpu, gpa, vie, error = emulate_bittest(vcpu, vie);
memread, memwrite, memarg);
break; break;
default: default:
error = -EINVAL; error = -EINVAL;

View File

@ -32,29 +32,8 @@
#include "instr_emul_wrapper.h" #include "instr_emul_wrapper.h"
/* /* Emulate the decoded 'ctxt->vie' instruction. */
* Callback functions to read and write memory regions. int vmm_emulate_instruction(struct instr_emul_ctxt *ctxt);
*/
typedef int (*mem_region_read_t)(struct vcpu *vcpu, uint64_t gpa,
uint64_t *rval, uint8_t rsize, void *arg);
typedef int (*mem_region_write_t)(struct vcpu *vcpu, uint64_t gpa,
uint64_t wval, uint8_t wsize, void *arg);
/*
* Emulate the decoded 'vie' instruction.
*
* The callbacks 'mrr' and 'mrw' emulate reads and writes to the memory region
* containing 'gpa'. 'memarg' is an opaque argument that is passed into the
* callback functions.
*
* 'void *vm' should be 'struct vm *' when called from kernel context and
* 'struct vmctx *' when called from user context.
* s
*/
int vmm_emulate_instruction(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
struct vm_guest_paging *paging, mem_region_read_t mrr,
mem_region_write_t mrw, void *memarg);
int vie_update_register(struct vcpu *vcpu, enum cpu_reg_name reg, int vie_update_register(struct vcpu *vcpu, enum cpu_reg_name reg,
uint64_t val_arg, uint8_t size); uint64_t val_arg, uint8_t size);

View File

@ -305,28 +305,6 @@ static void get_guest_paging_info(struct vcpu *vcpu, struct instr_emul_ctxt *emu
emul_ctxt->paging.paging_mode = get_vcpu_paging_mode(vcpu); emul_ctxt->paging.paging_mode = get_vcpu_paging_mode(vcpu);
} }
static int mmio_read(struct vcpu *vcpu, __unused uint64_t gpa, uint64_t *rval,
__unused uint8_t size, __unused void *arg)
{
if (vcpu == NULL) {
return -EINVAL;
}
*rval = vcpu->req.reqs.mmio.value;
return 0;
}
static int mmio_write(struct vcpu *vcpu, __unused uint64_t gpa, uint64_t wval,
__unused uint8_t size, __unused void *arg)
{
if (vcpu == NULL) {
return -EINVAL;
}
vcpu->req.reqs.mmio.value = wval;
return 0;
}
int decode_instruction(struct vcpu *vcpu) int decode_instruction(struct vcpu *vcpu)
{ {
struct instr_emul_ctxt *emul_ctxt; struct instr_emul_ctxt *emul_ctxt;
@ -364,18 +342,12 @@ int decode_instruction(struct vcpu *vcpu)
int emulate_instruction(struct vcpu *vcpu) int emulate_instruction(struct vcpu *vcpu)
{ {
struct instr_emul_ctxt *emul_ctxt; struct instr_emul_ctxt *ctxt = &per_cpu(g_inst_ctxt, vcpu->pcpu_id);
struct vm_guest_paging *paging;
int retval = 0;
uint64_t gpa = vcpu->req.reqs.mmio.address;
mem_region_read_t mread = mmio_read;
mem_region_write_t mwrite = mmio_write;
emul_ctxt = &per_cpu(g_inst_ctxt, vcpu->pcpu_id); if (ctxt == NULL) {
paging = &emul_ctxt->paging; pr_err("%s: Failed to get instr_emul_ctxt", __func__);
return -1;
}
retval = vmm_emulate_instruction(vcpu, gpa, return vmm_emulate_instruction(ctxt);
&emul_ctxt->vie, paging, mread, mwrite, NULL);
return retval;
} }