hv:move instr_emul_ctxt instance to struct vcpu

move instr_emul_ctxt instance from struct per_cpu_region
to struct vcpu, and rename it from g_inst_ctxt to inst_ctxt

Tracked-On: #1842
Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Jason Chen CJ 2019-02-24 20:19:33 +08:00 committed by Eddie Dong
parent 5331b39520
commit 286731d9d1
8 changed files with 57 additions and 67 deletions

View File

@ -478,10 +478,10 @@ static void vm_get_seg_desc(enum cpu_reg_name seg, struct seg_desc *desc)
desc->access = exec_vmread32(tdesc.access_field); desc->access = exec_vmread32(tdesc.access_field);
} }
static void get_guest_paging_info(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt, static void get_guest_paging_info(struct acrn_vcpu *vcpu, uint32_t csar)
uint32_t csar)
{ {
uint8_t cpl; uint8_t cpl;
struct instr_emul_ctxt *emul_ctxt = &vcpu->inst_ctxt;
cpl = (uint8_t)((csar >> 5U) & 3U); cpl = (uint8_t)((csar >> 5U) & 3U);
emul_ctxt->paging.cr3 = exec_vmread(VMX_GUEST_CR3); emul_ctxt->paging.cr3 = exec_vmread(VMX_GUEST_CR3);
@ -1629,10 +1629,9 @@ static int32_t emulate_bittest(struct acrn_vcpu *vcpu, const struct instr_emul_v
return ret; return ret;
} }
static int32_t vmm_emulate_instruction(struct instr_emul_ctxt *ctxt) static int32_t vmm_emulate_instruction(struct acrn_vcpu *vcpu)
{ {
struct instr_emul_vie *vie = &ctxt->vie; struct instr_emul_vie *vie = &vcpu->inst_ctxt.vie;
struct acrn_vcpu *vcpu = ctxt->vcpu;
int32_t error; int32_t error;
if (vie->decoded != 0U) { if (vie->decoded != 0U) {
@ -2242,10 +2241,10 @@ static int32_t local_decode_instruction(enum vm_cpu_mode cpu_mode,
} }
/* for instruction MOVS/STO, check the gva gotten from DI/SI. */ /* for instruction MOVS/STO, check the gva gotten from DI/SI. */
static int32_t instr_check_di(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt) static int32_t instr_check_di(struct acrn_vcpu *vcpu)
{ {
int32_t ret; int32_t ret;
struct instr_emul_vie *vie = &emul_ctxt->vie; struct instr_emul_vie *vie = &vcpu->inst_ctxt.vie;
uint64_t gva; uint64_t gva;
ret = get_gva_di_check(vcpu, vie, vie->addrsize, &gva); ret = get_gva_di_check(vcpu, vie, vie->addrsize, &gva);
@ -2259,14 +2258,13 @@ static int32_t instr_check_di(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *em
return ret; return ret;
} }
static int32_t instr_check_gva(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt, static int32_t instr_check_gva(struct acrn_vcpu *vcpu, enum vm_cpu_mode cpu_mode)
enum vm_cpu_mode cpu_mode)
{ {
int32_t ret = 0; int32_t ret = 0;
uint64_t base, segbase, idx, gva, gpa; uint64_t base, segbase, idx, gva, gpa;
uint32_t err_code; uint32_t err_code;
enum cpu_reg_name seg; enum cpu_reg_name seg;
struct instr_emul_vie *vie = &emul_ctxt->vie; struct instr_emul_vie *vie = &vcpu->inst_ctxt.vie;
base = 0UL; base = 0UL;
if (vie->base_register != CPU_REG_LAST) { if (vie->base_register != CPU_REG_LAST) {
@ -2351,51 +2349,44 @@ int32_t decode_instruction(struct acrn_vcpu *vcpu)
int32_t retval; int32_t retval;
enum vm_cpu_mode cpu_mode; enum vm_cpu_mode cpu_mode;
emul_ctxt = &per_cpu(g_inst_ctxt, vcpu->pcpu_id); emul_ctxt = &vcpu->inst_ctxt;
if (emul_ctxt == NULL) { retval = vie_init(&emul_ctxt->vie, vcpu);
pr_err("%s: Failed to get emul_ctxt", __func__); if (retval < 0) {
retval = -1; if (retval != -EFAULT) {
pr_err("init vie failed @ 0x%016llx:", vcpu_get_rip(vcpu));
}
} else { } else {
emul_ctxt->vcpu = vcpu;
retval = vie_init(&emul_ctxt->vie, vcpu); csar = exec_vmread32(VMX_GUEST_CS_ATTR);
if (retval < 0) { get_guest_paging_info(vcpu, csar);
if (retval != -EFAULT) { cpu_mode = get_vcpu_mode(vcpu);
pr_err("init vie failed @ 0x%016llx:", vcpu_get_rip(vcpu));
} retval = local_decode_instruction(cpu_mode, seg_desc_def32(csar), &emul_ctxt->vie);
if (retval != 0) {
pr_err("decode instruction failed @ 0x%016llx:", vcpu_get_rip(vcpu));
vcpu_inject_ud(vcpu);
retval = -EFAULT;
} else { } else {
/*
csar = exec_vmread32(VMX_GUEST_CS_ATTR); * We do operand check in instruction decode phase and
get_guest_paging_info(vcpu, emul_ctxt, csar); * inject exception accordingly. In late instruction
cpu_mode = get_vcpu_mode(vcpu); * emulation, it will always success.
*
retval = local_decode_instruction(cpu_mode, seg_desc_def32(csar), &emul_ctxt->vie); * We only need to do dst check for movs. For other instructions,
* they always has one register and one mmio which trigger EPT
if (retval != 0) { * by access mmio. With VMX enabled, the related check is done
pr_err("decode instruction failed @ 0x%016llx:", vcpu_get_rip(vcpu)); * by VMX itself before hit EPT violation.
vcpu_inject_ud(vcpu); *
retval = -EFAULT; */
if ((emul_ctxt->vie.op.op_flags & VIE_OP_F_CHECK_GVA_DI) != 0U) {
retval = instr_check_di(vcpu);
} else { } else {
/* retval = instr_check_gva(vcpu, cpu_mode);
* We do operand check in instruction decode phase and }
* inject exception accordingly. In late instruction
* emulation, it will always sucess.
*
* We only need to do dst check for movs. For other instructions,
* they always has one register and one mmio which trigger EPT
* by access mmio. With VMX enabled, the related check is done
* by VMX itself before hit EPT violation.
*
*/
if ((emul_ctxt->vie.op.op_flags & VIE_OP_F_CHECK_GVA_DI) != 0U) {
retval = instr_check_di(vcpu, emul_ctxt);
} else {
retval = instr_check_gva(vcpu, emul_ctxt, cpu_mode);
}
if (retval >= 0) { if (retval >= 0) {
retval = (int32_t)(emul_ctxt->vie.opsize); retval = (int32_t)(emul_ctxt->vie.opsize);
}
} }
} }
} }
@ -2403,17 +2394,7 @@ int32_t decode_instruction(struct acrn_vcpu *vcpu)
return retval; return retval;
} }
int32_t emulate_instruction(const struct acrn_vcpu *vcpu) int32_t emulate_instruction(struct acrn_vcpu *vcpu)
{ {
struct instr_emul_ctxt *ctxt = &per_cpu(g_inst_ctxt, vcpu->pcpu_id); return vmm_emulate_instruction(vcpu);
int32_t ret;
if (ctxt == NULL) {
pr_err("%s: Failed to get instr_emul_ctxt", __func__);
ret = -1;
} else {
ret = vmm_emulate_instruction(ctxt);
}
return ret;
} }

View File

@ -53,7 +53,7 @@ emulate_pio_complete(struct acrn_vcpu *vcpu, const struct io_request *io_req)
* either a previous call to emulate_io() returning 0 or the corresponding VHM * either a previous call to emulate_io() returning 0 or the corresponding VHM
* request transferring to the COMPLETE state. * request transferring to the COMPLETE state.
*/ */
static void emulate_mmio_complete(const struct acrn_vcpu *vcpu, const struct io_request *io_req) static void emulate_mmio_complete(struct acrn_vcpu *vcpu, const struct io_request *io_req)
{ {
const struct mmio_request *mmio_req = &io_req->reqs.mmio; const struct mmio_request *mmio_req = &io_req->reqs.mmio;

View File

@ -12,11 +12,13 @@
#include <pgtable.h> #include <pgtable.h>
#include <host_pm.h> #include <host_pm.h>
#include <trampoline.h> #include <trampoline.h>
#include <msr.h>
#include <vmx.h> #include <vmx.h>
#include <console.h> #include <console.h>
#include <ioapic.h> #include <ioapic.h>
#include <vtd.h> #include <vtd.h>
#include <lapic.h> #include <lapic.h>
#include <vcpu.h>
struct cpu_context cpu_ctx; struct cpu_context cpu_ctx;

View File

@ -7,6 +7,8 @@
#include <types.h> #include <types.h>
#include <errno.h> #include <errno.h>
#include <io.h> #include <io.h>
#include <msr.h>
#include <apicreg.h>
#include <cpuid.h> #include <cpuid.h>
#include <cpu_caps.h> #include <cpu_caps.h>
#include <softirq.h> #include <softirq.h>

View File

@ -7,6 +7,7 @@
*/ */
#include <types.h> #include <types.h>
#include <msr.h>
#include <per_cpu.h> #include <per_cpu.h>
#include <pgtable.h> #include <pgtable.h>

View File

@ -32,8 +32,9 @@
#include <types.h> #include <types.h>
#include <cpu.h> #include <cpu.h>
#include <vcpu.h> #include <guest_memory.h>
struct acrn_vcpu;
struct instr_emul_vie_op { struct instr_emul_vie_op {
uint8_t op_type; /* type of operation (e.g. MOV) */ uint8_t op_type; /* type of operation (e.g. MOV) */
uint16_t op_flags; uint16_t op_flags;
@ -94,10 +95,9 @@ struct vm_guest_paging {
struct instr_emul_ctxt { struct instr_emul_ctxt {
struct instr_emul_vie vie; struct instr_emul_vie vie;
struct vm_guest_paging paging; struct vm_guest_paging paging;
struct acrn_vcpu *vcpu;
}; };
int32_t emulate_instruction(const struct acrn_vcpu *vcpu); int32_t emulate_instruction(struct acrn_vcpu *vcpu);
int32_t decode_instruction(struct acrn_vcpu *vcpu); int32_t decode_instruction(struct acrn_vcpu *vcpu);
#endif #endif

View File

@ -60,6 +60,7 @@
#include <io_req.h> #include <io_req.h>
#include <msr.h> #include <msr.h>
#include <cpu.h> #include <cpu.h>
#include <instr_emul.h>
/** /**
* @brief vcpu * @brief vcpu
@ -326,6 +327,7 @@ struct acrn_vcpu {
bool launched; /* Whether the vcpu is launched on target pcpu */ bool launched; /* Whether the vcpu is launched on target pcpu */
uint32_t running; /* vcpu is picked up and run? */ uint32_t running; /* vcpu is picked up and run? */
struct instr_emul_ctxt inst_ctxt;
struct io_request req; /* used by io/ept emulation */ struct io_request req; /* used by io/ept emulation */
uint64_t reg_cached; uint64_t reg_cached;

View File

@ -10,10 +10,13 @@
#include <types.h> #include <types.h>
#include <sbuf.h> #include <sbuf.h>
#include <irq.h> #include <irq.h>
#include <page.h>
#include <timer.h>
#include <instr_emul.h> #include <instr_emul.h>
#include <profiling.h> #include <profiling.h>
#include <logmsg.h> #include <logmsg.h>
#include <gdt.h> #include <gdt.h>
#include <schedule.h>
#include <security.h> #include <security.h>
struct per_cpu_region { struct per_cpu_region {
@ -36,7 +39,6 @@ struct per_cpu_region {
struct per_cpu_timers cpu_timers; struct per_cpu_timers cpu_timers;
struct sched_context sched_ctx; struct sched_context sched_ctx;
struct sched_object idle; struct sched_object idle;
struct instr_emul_ctxt g_inst_ctxt;
struct host_gdt gdt; struct host_gdt gdt;
struct tss_64 tss; struct tss_64 tss;
enum pcpu_boot_state boot_state; enum pcpu_boot_state boot_state;