From 60c05ace1a7381849dc0fcd1bdd094ab426103f3 Mon Sep 17 00:00:00 2001 From: Mingqiang Chi Date: Mon, 10 Sep 2018 19:26:30 +0800 Subject: [PATCH] hv:Replace vlapic pointer with instance in vcpu_arch -- update 'vlapic' in 'struct vcpu_arch' from pointer to instance -- add inline function(vcpu_vlapic) in vcpu.h Tracked-On: #861 Signed-off-by: Mingqiang Chi Acked-by: Eddie Dong --- hypervisor/arch/x86/cpuid.c | 4 +- hypervisor/arch/x86/guest/vcpu.c | 2 +- hypervisor/arch/x86/guest/vlapic.c | 57 +++++++++++------------- hypervisor/arch/x86/virq.c | 6 +-- hypervisor/arch/x86/vmexit.c | 4 +- hypervisor/arch/x86/vmx.c | 2 +- hypervisor/bsp/uefi/uefi.c | 4 +- hypervisor/common/hypercall.c | 2 +- hypervisor/dm/vioapic.c | 2 +- hypervisor/include/arch/x86/cpuid.h | 2 +- hypervisor/include/arch/x86/guest/vcpu.h | 10 ++++- 11 files changed, 47 insertions(+), 48 deletions(-) diff --git a/hypervisor/arch/x86/cpuid.c b/hypervisor/arch/x86/cpuid.c index 5bdac2d15..f5c0775f4 100644 --- a/hypervisor/arch/x86/cpuid.c +++ b/hypervisor/arch/x86/cpuid.c @@ -297,7 +297,7 @@ int set_vcpuid_entries(struct vm *vm) return 0; } -void guest_cpuid(const struct vcpu *vcpu, +void guest_cpuid(struct vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { @@ -329,7 +329,7 @@ void guest_cpuid(const struct vcpu *vcpu, case 0x01U: { cpuid(leaf, eax, ebx, ecx, edx); - uint32_t apicid = vlapic_get_id(vcpu->arch_vcpu.vlapic); + uint32_t apicid = vlapic_get_id(vcpu_vlapic(vcpu)); /* Patching initial APIC ID */ *ebx &= ~APIC_ID_MASK; *ebx |= (apicid & APIC_ID_MASK); diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index 061fe077e..8b1ffde3e 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -417,7 +417,7 @@ void reset_vcpu(struct vcpu *vcpu) } vcpu->arch_vcpu.cur_context = NORMAL_WORLD; - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); vlapic_reset(vlapic); } diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 28225302f..0c8dc3240 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -111,7 +111,7 @@ vm_lapic_from_vcpu_id(struct vm *vm, uint16_t vcpu_id) vcpu = vcpu_from_vid(vm, vcpu_id); ASSERT(vcpu != NULL, "vm%d, vcpu%hu", vm->vm_id, vcpu_id); - return vcpu->arch_vcpu.vlapic; + return vcpu_vlapic(vcpu); } struct acrn_vlapic * @@ -122,7 +122,7 @@ vm_lapic_from_pcpuid(struct vm *vm, uint16_t pcpu_id) vcpu = vcpu_from_pid(vm, pcpu_id); ASSERT(vcpu != NULL, "vm%d, pcpu%hu", vm->vm_id, pcpu_id); - return vcpu->arch_vcpu.vlapic; + return vcpu_vlapic(vcpu); } static uint16_t vm_apicid2vcpu_id(struct vm *vm, uint8_t lapicid) @@ -131,7 +131,7 @@ static uint16_t vm_apicid2vcpu_id(struct vm *vm, uint8_t lapicid) struct vcpu *vcpu; foreach_vcpu(i, vm, vcpu) { - struct acrn_vlapic *vlapic = vcpu->arch_vcpu.vlapic; + struct acrn_vlapic *vlapic = vcpu_vlapic(vcpu); if (vlapic_get_apicid(vlapic) == lapicid) { return vcpu->vcpu_id; } @@ -272,14 +272,13 @@ vlapic_lvtt_masked(struct acrn_vlapic *vlapic) != 0U; } +/** + * @pre vlapic != NULL + */ static void vlapic_create_timer(struct acrn_vlapic *vlapic) { struct vlapic_timer *vtimer; - if (vlapic == NULL) { - return; - } - vtimer = &vlapic->vtimer; (void)memset(vtimer, 0U, sizeof(struct vlapic_timer)); @@ -288,14 +287,13 @@ static void vlapic_create_timer(struct acrn_vlapic *vlapic) 0UL, 0, 0UL); } +/** + * @pre vlapic != NULL + */ static void vlapic_reset_timer(struct acrn_vlapic *vlapic) { struct hv_timer *timer; - if (vlapic == NULL) { - return; - } - timer = &vlapic->vtimer.timer; del_timer(timer); timer->mode = 0; @@ -1591,10 +1589,12 @@ vlapic_reset(struct acrn_vlapic *vlapic) vlapic->isrvec_stk_top = 0U; } +/** + * @pre vlapic->vm != NULL + */ void vlapic_init(struct acrn_vlapic *vlapic) { - ASSERT(vlapic->vm != NULL, "%s: vm is not initialized", __func__); ASSERT(vlapic->vcpu->vcpu_id < phys_cpu_num, "%s: vcpu_id is not initialized", __func__); @@ -1695,7 +1695,7 @@ vlapic_deliver_intr(struct vm *vm, bool level, uint32_t dest, bool phys, } /* only make request when vlapic enabled */ - vlapic = target_vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(target_vcpu); if (vlapic_enabled(vlapic)) { if (delmode == IOAPIC_RTE_DELEXINT) { vcpu_inject_extint(target_vcpu); @@ -1811,7 +1811,7 @@ vlapic_set_intr(struct vcpu *vcpu, uint32_t vector, bool level) return -EINVAL; } - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); if (vlapic_set_intr_ready(vlapic, vector, level) != 0) { vcpu_make_request(vcpu, ACRN_REQUEST_EVENT); } else { @@ -1898,7 +1898,7 @@ static void vlapic_timer_expired(void *data) struct acrn_vlapic *vlapic; struct lapic_regs *lapic; - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); lapic = &(vlapic->apic_page); /* inject vcpu timer interrupt if not masked */ @@ -1918,7 +1918,7 @@ vlapic_rdmsr(struct vcpu *vcpu, uint32_t msr, uint64_t *rval) struct acrn_vlapic *vlapic; dev_dbg(ACRN_DBG_LAPIC, "cpu[%hu] rdmsr: %x", vcpu->vcpu_id, msr); - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); switch (msr) { case MSR_IA32_APIC_BASE: @@ -1944,7 +1944,7 @@ vlapic_wrmsr(struct vcpu *vcpu, uint32_t msr, uint64_t wval) int error = 0; struct acrn_vlapic *vlapic; - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); switch (msr) { case MSR_IA32_APIC_BASE: @@ -1968,11 +1968,8 @@ vlapic_wrmsr(struct vcpu *vcpu, uint32_t msr, uint64_t wval) int vlapic_create(struct vcpu *vcpu) { - struct acrn_vlapic *vlapic = calloc(1U, sizeof(struct acrn_vlapic)); - - ASSERT(vlapic != NULL, "vlapic allocate failed"); - vlapic->vm = vcpu->vm; - vlapic->vcpu = vcpu; + vcpu->arch_vcpu.vlapic.vm = vcpu->vm; + vcpu->arch_vcpu.vlapic.vcpu = vcpu; if (is_vcpu_bsp(vcpu)) { uint64_t *pml4_page = @@ -1988,8 +1985,7 @@ int vlapic_create(struct vcpu *vcpu) EPT_WR | EPT_RD | EPT_UNCACHED); } - vcpu->arch_vcpu.vlapic = vlapic; - vlapic_init(vlapic); + vlapic_init(vcpu_vlapic(vcpu)); return 0; } @@ -2001,13 +1997,10 @@ void vlapic_free(struct vcpu *vcpu) return; } - vlapic = vcpu->arch_vcpu.vlapic; - if (vlapic == NULL) { - return; - } + vlapic = vcpu_vlapic(vcpu); + del_timer(&vlapic->vtimer.timer); - free(vlapic); } /** @@ -2196,7 +2189,7 @@ int apic_access_vmexit_handler(struct vcpu *vcpu) offset = (uint32_t)apic_access_offset(qual); } - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); err = decode_instruction(vcpu); /* apic access should already fetched instruction, decode_instruction @@ -2236,7 +2229,7 @@ int veoi_vmexit_handler(struct vcpu *vcpu) vcpu_retain_rip(vcpu); - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); lapic = &(vlapic->apic_page); vector = (uint32_t)(vcpu->arch_vcpu.exit_qualification & 0xFFUL); @@ -2266,7 +2259,7 @@ int apic_write_vmexit_handler(struct vcpu *vcpu) handled = 1; vcpu_retain_rip(vcpu); - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); switch (offset) { case APIC_OFFSET_ID: diff --git a/hypervisor/arch/x86/virq.c b/hypervisor/arch/x86/virq.c index 956c1e0d9..915a82d96 100644 --- a/hypervisor/arch/x86/virq.c +++ b/hypervisor/arch/x86/virq.c @@ -78,7 +78,7 @@ static bool vcpu_pending_request(struct vcpu *vcpu) int ret = 0; /* Query vLapic to get vector to inject */ - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); ret = vlapic_pending_intr(vlapic, &vector); /* we need to check and raise request if we have pending event @@ -111,7 +111,7 @@ void vcpu_make_request(struct vcpu *vcpu, uint16_t eventid) static int vcpu_inject_vlapic_int(struct vcpu *vcpu) { - struct acrn_vlapic *vlapic = vcpu->arch_vcpu.vlapic; + struct acrn_vlapic *vlapic = vcpu_vlapic(vcpu); uint32_t vector = 0U; int ret = 0; @@ -390,7 +390,7 @@ int acrn_handle_pending_request(struct vcpu *vcpu) uint32_t error_code; struct vcpu_arch * arch_vcpu = &vcpu->arch_vcpu; uint64_t *pending_req_bits = &arch_vcpu->pending_req; - struct acrn_vlapic *vlapic = vcpu->arch_vcpu.vlapic; + struct acrn_vlapic *vlapic = vcpu_vlapic(vcpu); if (bitmap_test_and_clear_lock(ACRN_REQUEST_TRP_FAULT, pending_req_bits)) { pr_fatal("Triple fault happen -> shutdown!"); diff --git a/hypervisor/arch/x86/vmexit.c b/hypervisor/arch/x86/vmexit.c index 311098b52..278288d97 100644 --- a/hypervisor/arch/x86/vmexit.c +++ b/hypervisor/arch/x86/vmexit.c @@ -294,11 +294,11 @@ int cr_access_vmexit_handler(struct vcpu *vcpu) vcpu_inject_gp(vcpu, 0U); break; } - vlapic_set_cr8(vcpu->arch_vcpu.vlapic, reg); + vlapic_set_cr8(vcpu_vlapic(vcpu), reg); break; case 0x18UL: /* mov from cr8 */ - reg = vlapic_get_cr8(vcpu->arch_vcpu.vlapic); + reg = vlapic_get_cr8(vcpu_vlapic(vcpu)); vcpu_set_gpreg(vcpu, idx, reg); break; default: diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index edb8f0195..cc716a4f1 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -972,7 +972,7 @@ static void init_exec_ctrl(struct vcpu *vcpu) exec_vmwrite64(VMX_APIC_ACCESS_ADDR_FULL, value64); /*APIC-v, config APIC virtualized page address*/ - value64 = vlapic_apicv_get_apic_page_addr(vcpu->arch_vcpu.vlapic); + value64 = vlapic_apicv_get_apic_page_addr(vcpu_vlapic(vcpu)); exec_vmwrite64(VMX_VIRTUAL_APIC_PAGE_ADDR_FULL, value64); if (is_apicv_intr_delivery_supported()) { diff --git a/hypervisor/bsp/uefi/uefi.c b/hypervisor/bsp/uefi/uefi.c index 744c2219f..5b90bdbc3 100644 --- a/hypervisor/bsp/uefi/uefi.c +++ b/hypervisor/bsp/uefi/uefi.c @@ -37,7 +37,7 @@ void efi_spurious_handler(int vector) return; vcpu = per_cpu(vcpu, 0); - if ((vcpu != NULL) && vcpu->arch_vcpu.vlapic) { + if (vcpu != NULL) { ret = vlapic_set_intr(vcpu, vector, 0); if (ret != 0) pr_err("%s vlapic set intr fail, interrupt lost\n", @@ -62,7 +62,7 @@ int uefi_sw_loader(struct vm *vm, struct vcpu *vcpu) if (!is_vm0(vm)) return load_guest(vm, vcpu); - vlapic_restore(vcpu->arch_vcpu.vlapic, &uefi_lapic_regs); + vlapic_restore(vcpu_vlapic(vcpu), &uefi_lapic_regs); vcpu->entry_addr = (void *)efi_ctx->rip; memcpy_s(&cur_context->guest_cpu_regs, sizeof(struct cpu_gp_regs), diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 7d5b4d060..b038b0933 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -36,7 +36,7 @@ int32_t hcall_sos_offline_cpu(struct vm *vm, uint64_t lapicid) pr_info("sos offline cpu with lapicid %lld", lapicid); foreach_vcpu(i, vm, vcpu) { - if (vlapic_get_apicid(vcpu->arch_vcpu.vlapic) == lapicid) { + if (vlapic_get_apicid(vcpu_vlapic(vcpu)) == lapicid) { /* should not offline BSP */ if (vcpu->vcpu_id == BOOT_CPU_ID) return -1; diff --git a/hypervisor/dm/vioapic.c b/hypervisor/dm/vioapic.c index ec9a174be..48a6b5bcc 100644 --- a/hypervisor/dm/vioapic.c +++ b/hypervisor/dm/vioapic.c @@ -189,7 +189,7 @@ vioapic_update_tmr(struct vcpu *vcpu) bool level; uint32_t pin, pincount; - vlapic = vcpu->arch_vcpu.vlapic; + vlapic = vcpu_vlapic(vcpu); vioapic = vm_ioapic(vcpu->vm); VIOAPIC_LOCK(vioapic); diff --git a/hypervisor/include/arch/x86/cpuid.h b/hypervisor/include/arch/x86/cpuid.h index 350039285..8fef50fc4 100644 --- a/hypervisor/include/arch/x86/cpuid.h +++ b/hypervisor/include/arch/x86/cpuid.h @@ -132,7 +132,7 @@ static inline void cpuid_subleaf(uint32_t leaf, uint32_t subleaf, } int set_vcpuid_entries(struct vm *vm); -void guest_cpuid(const struct vcpu *vcpu, +void guest_cpuid(struct vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index d05396885..12ec7defb 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -166,6 +166,8 @@ struct cpu_context { struct vcpu_arch { /* vmcs region for this vcpu, MUST be 4KB-aligned */ uint8_t vmcs[CPU_PAGE_SIZE]; + /* per vcpu lapic */ + struct acrn_vlapic vlapic; int cur_context; struct cpu_context contexts[NR_WORLD]; @@ -203,8 +205,6 @@ struct vcpu_arch { bool inject_event_pending; struct event_injection_info inject_info; - /* per vcpu lapic */ - void *vlapic; } __aligned(CPU_PAGE_SIZE); struct vm; @@ -264,6 +264,12 @@ static inline void vcpu_retain_rip(struct vcpu *vcpu) (vcpu)->arch_vcpu.inst_len = 0U; } +static inline struct acrn_vlapic * +vcpu_vlapic(struct vcpu *vcpu) +{ + return &(vcpu->arch_vcpu.vlapic); +} + /* External Interfaces */ uint64_t vcpu_get_gpreg(struct vcpu *vcpu, uint32_t reg); void vcpu_set_gpreg(struct vcpu *vcpu, uint32_t reg, uint64_t val);