From 286731d9d1f99fe20ab190dea8b5c9bbd9b3a278 Mon Sep 17 00:00:00 2001 From: Jason Chen CJ Date: Sun, 24 Feb 2019 20:19:33 +0800 Subject: [PATCH] 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 Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/instr_emul.c | 105 +++++++----------- hypervisor/arch/x86/guest/io_emul.c | 2 +- hypervisor/arch/x86/pm.c | 2 + hypervisor/arch/x86/timer.c | 2 + hypervisor/arch/x86/vmx.c | 1 + .../include/arch/x86/guest/instr_emul.h | 6 +- hypervisor/include/arch/x86/guest/vcpu.h | 2 + hypervisor/include/arch/x86/per_cpu.h | 4 +- 8 files changed, 57 insertions(+), 67 deletions(-) diff --git a/hypervisor/arch/x86/guest/instr_emul.c b/hypervisor/arch/x86/guest/instr_emul.c index a2430cd66..164022e5f 100644 --- a/hypervisor/arch/x86/guest/instr_emul.c +++ b/hypervisor/arch/x86/guest/instr_emul.c @@ -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); } -static void get_guest_paging_info(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt, - uint32_t csar) +static void get_guest_paging_info(struct acrn_vcpu *vcpu, uint32_t csar) { uint8_t cpl; + struct instr_emul_ctxt *emul_ctxt = &vcpu->inst_ctxt; cpl = (uint8_t)((csar >> 5U) & 3U); 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; } -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 acrn_vcpu *vcpu = ctxt->vcpu; + struct instr_emul_vie *vie = &vcpu->inst_ctxt.vie; int32_t error; 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. */ -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; - struct instr_emul_vie *vie = &emul_ctxt->vie; + struct instr_emul_vie *vie = &vcpu->inst_ctxt.vie; uint64_t 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; } -static int32_t instr_check_gva(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt, - enum vm_cpu_mode cpu_mode) +static int32_t instr_check_gva(struct acrn_vcpu *vcpu, enum vm_cpu_mode cpu_mode) { int32_t ret = 0; uint64_t base, segbase, idx, gva, gpa; uint32_t err_code; enum cpu_reg_name seg; - struct instr_emul_vie *vie = &emul_ctxt->vie; + struct instr_emul_vie *vie = &vcpu->inst_ctxt.vie; base = 0UL; if (vie->base_register != CPU_REG_LAST) { @@ -2351,51 +2349,44 @@ int32_t decode_instruction(struct acrn_vcpu *vcpu) int32_t retval; enum vm_cpu_mode cpu_mode; - emul_ctxt = &per_cpu(g_inst_ctxt, vcpu->pcpu_id); - if (emul_ctxt == NULL) { - pr_err("%s: Failed to get emul_ctxt", __func__); - retval = -1; + emul_ctxt = &vcpu->inst_ctxt; + retval = vie_init(&emul_ctxt->vie, vcpu); + if (retval < 0) { + if (retval != -EFAULT) { + pr_err("init vie failed @ 0x%016llx:", vcpu_get_rip(vcpu)); + } } else { - emul_ctxt->vcpu = vcpu; - retval = vie_init(&emul_ctxt->vie, vcpu); - if (retval < 0) { - if (retval != -EFAULT) { - pr_err("init vie failed @ 0x%016llx:", vcpu_get_rip(vcpu)); - } + csar = exec_vmread32(VMX_GUEST_CS_ATTR); + get_guest_paging_info(vcpu, csar); + cpu_mode = get_vcpu_mode(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 { - - csar = exec_vmread32(VMX_GUEST_CS_ATTR); - get_guest_paging_info(vcpu, emul_ctxt, csar); - cpu_mode = get_vcpu_mode(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; + /* + * We do operand check in instruction decode phase and + * inject exception accordingly. In late instruction + * emulation, it will always success. + * + * 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); } else { - /* - * 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); - } + retval = instr_check_gva(vcpu, cpu_mode); + } - if (retval >= 0) { - retval = (int32_t)(emul_ctxt->vie.opsize); - } + if (retval >= 0) { + retval = (int32_t)(emul_ctxt->vie.opsize); } } } @@ -2403,17 +2394,7 @@ int32_t decode_instruction(struct acrn_vcpu *vcpu) 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); - 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; + return vmm_emulate_instruction(vcpu); } diff --git a/hypervisor/arch/x86/guest/io_emul.c b/hypervisor/arch/x86/guest/io_emul.c index 0c9e1583d..abfcd2b21 100644 --- a/hypervisor/arch/x86/guest/io_emul.c +++ b/hypervisor/arch/x86/guest/io_emul.c @@ -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 * 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; diff --git a/hypervisor/arch/x86/pm.c b/hypervisor/arch/x86/pm.c index 0703b2d34..3a0d1b2c2 100644 --- a/hypervisor/arch/x86/pm.c +++ b/hypervisor/arch/x86/pm.c @@ -12,11 +12,13 @@ #include #include #include + #include #include #include #include #include #include + #include struct cpu_context cpu_ctx; diff --git a/hypervisor/arch/x86/timer.c b/hypervisor/arch/x86/timer.c index c713333fa..8330115d9 100644 --- a/hypervisor/arch/x86/timer.c +++ b/hypervisor/arch/x86/timer.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index 6a4f9f3d3..850e32cb9 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -7,6 +7,7 @@ */ #include +#include #include #include diff --git a/hypervisor/include/arch/x86/guest/instr_emul.h b/hypervisor/include/arch/x86/guest/instr_emul.h index c51b96735..8f03493fe 100644 --- a/hypervisor/include/arch/x86/guest/instr_emul.h +++ b/hypervisor/include/arch/x86/guest/instr_emul.h @@ -32,8 +32,9 @@ #include #include -#include +#include +struct acrn_vcpu; struct instr_emul_vie_op { uint8_t op_type; /* type of operation (e.g. MOV) */ uint16_t op_flags; @@ -94,10 +95,9 @@ struct vm_guest_paging { struct instr_emul_ctxt { struct instr_emul_vie vie; 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); #endif diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index c2e0beb52..6512cfffe 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -60,6 +60,7 @@ #include #include #include +#include /** * @brief vcpu @@ -326,6 +327,7 @@ struct acrn_vcpu { bool launched; /* Whether the vcpu is launched on target pcpu */ uint32_t running; /* vcpu is picked up and run? */ + struct instr_emul_ctxt inst_ctxt; struct io_request req; /* used by io/ept emulation */ uint64_t reg_cached; diff --git a/hypervisor/include/arch/x86/per_cpu.h b/hypervisor/include/arch/x86/per_cpu.h index 87cb34ed8..e9030fe64 100644 --- a/hypervisor/include/arch/x86/per_cpu.h +++ b/hypervisor/include/arch/x86/per_cpu.h @@ -10,10 +10,13 @@ #include #include #include +#include +#include #include #include #include #include +#include #include struct per_cpu_region { @@ -36,7 +39,6 @@ struct per_cpu_region { struct per_cpu_timers cpu_timers; struct sched_context sched_ctx; struct sched_object idle; - struct instr_emul_ctxt g_inst_ctxt; struct host_gdt gdt; struct tss_64 tss; enum pcpu_boot_state boot_state;