mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-23 01:37:44 +00:00
hv: rework EOI_EXIT_BITMAP update logic
This commit changes the EOI_EXIT_BITMAP as follows: - add a eoi_exit_bitmap to vlapic structure; - go through all the RTEs and set eoi_exit_bitmap in the vlapic structure when related RTE fields are modified; - add ACRN_REQUEST_EOI_EXIT_UPDATE, if eoi_exit_bitmap changed, request the corresponding vcpu to write the bitmap to VMCS. Tracked-On: #2343 Signed-off-by: Yan, Like <like.yan@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -166,6 +166,49 @@ void vcpu_set_guest_msr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the eoi_exit_bitmaps to VMCS fields
|
||||
*/
|
||||
void vcpu_set_vmcs_eoi_exit(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
pr_dbg("%s", __func__);
|
||||
|
||||
spinlock_obtain(&(vcpu->arch.lock));
|
||||
if (is_apicv_intr_delivery_supported()) {
|
||||
exec_vmwrite64(VMX_EOI_EXIT0_FULL, vcpu->arch.eoi_exit_bitmap[0]);
|
||||
exec_vmwrite64(VMX_EOI_EXIT1_FULL, vcpu->arch.eoi_exit_bitmap[1]);
|
||||
exec_vmwrite64(VMX_EOI_EXIT2_FULL, vcpu->arch.eoi_exit_bitmap[2]);
|
||||
exec_vmwrite64(VMX_EOI_EXIT3_FULL, vcpu->arch.eoi_exit_bitmap[3]);
|
||||
}
|
||||
spinlock_release(&(vcpu->arch.lock));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the eoi_exit_bitmap bit for specific vector
|
||||
* called with vcpu->arch.lock held
|
||||
* @pre vcpu != NULL && vector <= 255U
|
||||
*/
|
||||
void vcpu_set_eoi_exit(struct acrn_vcpu *vcpu, uint32_t vector)
|
||||
{
|
||||
pr_dbg("%s", __func__);
|
||||
|
||||
if (bitmap_test_and_set_nolock((uint16_t)(vector & 0x3fU),
|
||||
&(vcpu->arch.eoi_exit_bitmap[vector >> 6U]))) {
|
||||
pr_warn("Duplicated vector %u vcpu%u", vector, vcpu->vcpu_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset all eoi_exit_bitmaps
|
||||
* called with vcpu->arch.lock held
|
||||
*/
|
||||
void vcpu_reset_eoi_exit_all(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
pr_dbg("%s", __func__);
|
||||
|
||||
memset((void *)(vcpu->arch.eoi_exit_bitmap), 0U, sizeof(vcpu->arch.eoi_exit_bitmap));
|
||||
}
|
||||
|
||||
struct acrn_vcpu *get_ever_run_vcpu(uint16_t pcpu_id)
|
||||
{
|
||||
return per_cpu(ever_run_vcpu, pcpu_id);
|
||||
@@ -379,6 +422,8 @@ int32_t create_vcpu(uint16_t pcpu_id, struct acrn_vm *vm, struct acrn_vcpu **rtn
|
||||
init_vmtrr(vcpu);
|
||||
#endif
|
||||
|
||||
spinlock_init(&(vcpu->arch.lock));
|
||||
|
||||
/* Populate the return handle */
|
||||
*rtn_vcpu_handle = vcpu;
|
||||
|
||||
|
@@ -409,6 +409,10 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu)
|
||||
vioapic_update_tmr(vcpu);
|
||||
}
|
||||
|
||||
if (bitmap_test_and_clear_lock(ACRN_REQUEST_EOI_EXIT_UPDATE, pending_req_bits)) {
|
||||
vcpu_set_vmcs_eoi_exit(vcpu);
|
||||
}
|
||||
|
||||
/* handling cancelled event injection when vcpu is switched out */
|
||||
if (arch->inject_event_pending) {
|
||||
if ((arch->inject_info.intr_info & (EXCEPTION_ERROR_CODE_VALID << 8U)) != 0U) {
|
||||
|
Reference in New Issue
Block a user