From 8f732f28097165ded40480ad1b09af34fa94fe29 Mon Sep 17 00:00:00 2001 From: dongshen Date: Wed, 18 Mar 2020 11:47:35 -0700 Subject: [PATCH] hv: move pi_desc related code from vlapic.h/vlapic.c to vmx.h/vmx.c/vcpu.h The posted interrupt descriptor is more of a vmx/vmcs concept than a vlapic concept. struct acrn_vcpu_arch stores the vmx/vmcs info, so put struct pi_desc in struct acrn_vcpu_arch. Remove the function apicv_get_pir_desc_paddr() A few coding style/typo fixes Tracked-On: #4506 Signed-off-by: dongshen Reviewed-by: Eddie Dong --- hypervisor/arch/x86/guest/vlapic.c | 31 +++++----------------- hypervisor/arch/x86/guest/vmcs.c | 2 +- hypervisor/include/arch/x86/guest/vcpu.h | 23 +++++++++++++--- hypervisor/include/arch/x86/guest/vlapic.h | 26 +----------------- hypervisor/include/arch/x86/vmx.h | 8 ++++++ 5 files changed, 36 insertions(+), 54 deletions(-) diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index aff6ffb29..dc4077fef 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -612,26 +612,6 @@ static void apicv_post_intr(uint16_t dest_pcpu_id) send_single_ipi(dest_pcpu_id, POSTED_INTR_VECTOR); } -/** - * @brief Get physical address to PIR description. - * - * If APICv Posted-interrupt is supported, this address will be configured - * to VMCS "Posted-interrupt descriptor address" field. - * - * @param[in] vcpu Target vCPU - * - * @return physicall address to PIR - * - * @pre vcpu != NULL - */ -uint64_t apicv_get_pir_desc_paddr(struct acrn_vcpu *vcpu) -{ - struct acrn_vlapic *vlapic; - - vlapic = &vcpu->arch.vlapic; - return hva2hpa(&(vlapic->pid)); -} - /** * @pre offset value shall be one of the folllowing values: * APIC_OFFSET_CMCI_LVT @@ -1672,7 +1652,6 @@ vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops, enum lapic = &(vlapic->apic_page); (void)memset((void *)lapic, 0U, sizeof(struct lapic_regs)); - (void)memset((void *)&(vlapic->pid), 0U, sizeof(vlapic->pid)); if (mode == INIT_RESET) { if ((preserved_lapic_mode & APICBASE_ENABLED) != 0U ) { @@ -2225,7 +2204,8 @@ void vlapic_free(struct acrn_vcpu *vcpu) /** * APIC-v functions - * **/ + * @pre get_pi_desc(vlapic->vcpu) != NULL + */ static bool apicv_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector) { @@ -2233,7 +2213,7 @@ apicv_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector) uint32_t idx; bool notify = false; - pid = &(vlapic->pid); + pid = get_pi_desc(vlapic->vcpu); idx = vector >> 6U; @@ -2286,6 +2266,7 @@ static bool apicv_basic_inject_intr(struct acrn_vlapic *vlapic, /* * Transfer the pending interrupts in the PIR descriptor to the IRR * in the virtual APIC page. + * @pre get_pi_desc(vlapic->vcpu) != NULL */ static void vlapic_apicv_inject_pir(struct acrn_vlapic *vlapic) { @@ -2296,7 +2277,7 @@ static void vlapic_apicv_inject_pir(struct acrn_vlapic *vlapic) uint16_t intr_status_old, intr_status_new; struct lapic_reg *irr = NULL; - pid = &(vlapic->pid); + pid = get_pi_desc(vlapic->vcpu); if (atomic_cmpxchg64(&pid->pending, 1UL, 0UL) == 1UL) { pirval = 0UL; lapic = &(vlapic->apic_page); @@ -2464,7 +2445,7 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu) * 2 = linear access for an instruction fetch * c) we suppose the guest goes wrong when it will access the APIC-access page * when process event-delivery. According chap 26.5.1.2 VM Exits During Event Injection, - * vol 3, sdm: If the “virtualize APIC accesses” VM-execution control is 1 and + * vol 3, sdm: If the "virtualize APIC accesses"� VM-execution control is 1 and * event delivery generates an access to the APIC-access page, that access is treated as * described in Section 29.4 and may cause a VM exit. * 3 = linear access (read or write) during event delivery diff --git a/hypervisor/arch/x86/guest/vmcs.c b/hypervisor/arch/x86/guest/vmcs.c index bc3f0344e..b639cf1b5 100644 --- a/hypervisor/arch/x86/guest/vmcs.c +++ b/hypervisor/arch/x86/guest/vmcs.c @@ -353,7 +353,7 @@ static void init_exec_ctrl(struct acrn_vcpu *vcpu) exec_vmwrite16(VMX_GUEST_INTR_STATUS, 0U); exec_vmwrite16(VMX_POSTED_INTR_VECTOR, POSTED_INTR_VECTOR); - exec_vmwrite64(VMX_PIR_DESC_ADDR_FULL, apicv_get_pir_desc_paddr(vcpu)); + exec_vmwrite64(VMX_PIR_DESC_ADDR_FULL, hva2hpa(get_pi_desc(vcpu))); } /* Load EPTP execution control diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index 4667aad49..2edf921e6 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -27,6 +27,7 @@ #include #include #include +#include /** * @brief vcpu @@ -200,6 +201,9 @@ struct acrn_vcpu_arch { /* per vcpu lapic */ struct acrn_vlapic vlapic; + /* pid MUST be 64 bytes aligned */ + struct pi_desc pid __aligned(64); + struct acrn_vmtrr vmtrr; int32_t cur_context; @@ -297,12 +301,25 @@ static inline void vcpu_retain_rip(struct acrn_vcpu *vcpu) (vcpu)->arch.inst_len = 0U; } -static inline struct acrn_vlapic * -vcpu_vlapic(struct acrn_vcpu *vcpu) +static inline struct acrn_vlapic *vcpu_vlapic(struct acrn_vcpu *vcpu) { return &(vcpu->arch.vlapic); } +/** + * @brief Get pointer to PI description. + * + * @param[in] vcpu Target vCPU + * + * @return pointer to PI description + * + * @pre vcpu != NULL + */ +static inline struct pi_desc *get_pi_desc(struct acrn_vcpu *vcpu) +{ + return &(vcpu->arch.pid); +} + uint16_t pcpuid_from_vcpu(const struct acrn_vcpu *vcpu); void default_idle(__unused struct thread_object *obj); void vcpu_thread(struct thread_object *obj); @@ -557,7 +574,7 @@ static inline bool is_pae(struct acrn_vcpu *vcpu) } struct acrn_vcpu *get_running_vcpu(uint16_t pcpu_id); -struct acrn_vcpu* get_ever_run_vcpu(uint16_t pcpu_id); +struct acrn_vcpu *get_ever_run_vcpu(uint16_t pcpu_id); void save_xsave_area(struct ext_context *ectx); void rstore_xsave_area(const struct ext_context *ectx); diff --git a/hypervisor/include/arch/x86/guest/vlapic.h b/hypervisor/include/arch/x86/guest/vlapic.h index 848f11d87..5c9d193bc 100644 --- a/hypervisor/include/arch/x86/guest/vlapic.h +++ b/hypervisor/include/arch/x86/guest/vlapic.h @@ -43,14 +43,6 @@ #define VLAPIC_MAXLVT_INDEX APIC_LVT_CMCI -/* Posted Interrupt Descriptor (PID) in VT-d spec */ -struct pi_desc { - /* Posted Interrupt Requests, one bit per requested vector */ - uint64_t pir[4]; - uint64_t pending; - uint64_t unused[3]; -} __aligned(64); - struct vlapic_timer { struct hv_timer timer; uint32_t mode; @@ -60,16 +52,14 @@ struct vlapic_timer { struct acrn_vlapic { /* - * Please keep 'apic_page' and 'pid' be the first two fields in + * Please keep 'apic_page' as the first field in * current structure, as below alignment restrictions are mandatory * to support APICv features: * - 'apic_page' MUST be 4KB aligned. - * - 'pid' MUST be 64 bytes aligned. * IRR, TMR and PIR could be accessed by other vCPUs when deliver * an interrupt to vLAPIC. */ struct lapic_regs apic_page; - struct pi_desc pid; struct acrn_vm *vm; struct acrn_vcpu *vcpu; @@ -124,20 +114,6 @@ bool vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu); bool vlapic_has_pending_intr(struct acrn_vcpu *vcpu); -/** - * @brief Get physical address to PIR description. - * - * If APICv Posted-interrupt is supported, this address will be configured - * to VMCS "Posted-interrupt descriptor address" field. - * - * @param[in] vcpu Target vCPU - * - * @return physicall address to PIR - * - * @pre vcpu != NULL - */ -uint64_t apicv_get_pir_desc_paddr(struct acrn_vcpu *vcpu); - uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic); void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg); uint64_t vlapic_get_apicbase(const struct acrn_vlapic *vlapic); diff --git a/hypervisor/include/arch/x86/vmx.h b/hypervisor/include/arch/x86/vmx.h index f41ec9e93..1fd83af45 100644 --- a/hypervisor/include/arch/x86/vmx.h +++ b/hypervisor/include/arch/x86/vmx.h @@ -374,6 +374,14 @@ #define VMX_INT_TYPE_HW_EXP 3U #define VMX_INT_TYPE_SW_EXP 6U +/* Posted Interrupt Descriptor (PID) in VT-d spec */ +struct pi_desc { + /* Posted Interrupt Requests, one bit per requested vector */ + uint64_t pir[4]; + uint64_t pending; + uint32_t unused[3]; +} __aligned(64); + /* External Interfaces */ void vmx_on(void); void vmx_off(void);