mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-24 10:17:28 +00:00
hv: maintain a per-pCPU array of vCPUs and handle posted interrupt IRQs
Maintain a per-pCPU array of vCPUs (struct acrn_vcpu *vcpu_array[CONFIG_MAX_VM_NUM]), one VM cannot have multiple vCPUs share one pcpu, so we can utilize this property and use the containing VM's vm_id as the index to the vCPU array: In create_vcpu(), we simply do: per_cpu(vcpu_array, pcpu_id)[vm->vm_id] = vcpu; In offline_vcpu(): per_cpu(vcpu_array, pcpuid_from_vcpu(vcpu))[vcpu->vm->vm_id] = NULL; so basically we use the containing VM's vm_id as the index to the vCPU array, as well as the index of posted interrupt IRQ/vector pair that are assigned to this vCPU: 0: first vCPU and first posted interrupt IRQs/vector pair (POSTED_INTR_IRQ/POSTED_INTR_VECTOR) ... CONFIG_MAX_VM_NUM-1: last vCPU and last posted interrupt IRQs/vector pair ((POSTED_INTR_IRQ + CONFIG_MAX_VM_NUM - 1U)/(POSTED_INTR_VECTOR + CONFIG_MAX_VM_NUM - 1U) In the posted interrupt handler, it will do the following: Translate the IRQ into a zero based index of where the vCPU is located in the vCPU list for current pCPU. Once the vCPU is found, we wake up the waiting thread and record this request as ACRN_REQUEST_EVENT Tracked-On: #4506 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Reviewed-by: Eddie Dong <eddie.dong@Intel.com> Signed-off-by: dongshen <dongsheng.x.zhang@intel.com>
This commit is contained in:
@@ -700,6 +700,19 @@ int32_t prepare_vcpu(struct acrn_vm *vm, uint16_t pcpu_id);
|
||||
*/
|
||||
uint64_t vcpumask2pcpumask(struct acrn_vm *vm, uint64_t vdmask);
|
||||
bool is_lapic_pt_enabled(struct acrn_vcpu *vcpu);
|
||||
|
||||
/**
|
||||
* @brief handle posted interrupts
|
||||
*
|
||||
* VT-d PI handler, find the corresponding vCPU for this IRQ,
|
||||
* if the associated PID's bit ON is set, wake it up.
|
||||
*
|
||||
* @param[in] vcpu_index a zero based index of where the vCPU is located in the vCPU list for current pCPU
|
||||
* @pre vcpu_index < CONFIG_MAX_VM_NUM
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void vcpu_handle_pi_notification(uint32_t vcpu_index);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@@ -59,6 +59,14 @@ struct per_cpu_region {
|
||||
#endif
|
||||
uint16_t shutdown_vm_id;
|
||||
uint64_t tsc_suspend;
|
||||
/*
|
||||
* We maintain a per-pCPU array of vCPUs. vCPUs of a VM won't
|
||||
* share same pCPU. So the maximum possible # of vCPUs that can
|
||||
* run on a pCPU is CONFIG_MAX_VM_NUM.
|
||||
* vcpu_array address must be aligned to 64-bit for atomic access
|
||||
* to avoid contention between offline_vcpu and posted interrupt handler
|
||||
*/
|
||||
struct acrn_vcpu *vcpu_array[CONFIG_MAX_VM_NUM] __aligned(8);
|
||||
} __aligned(PAGE_SIZE); /* per_cpu_region size aligned with PAGE_SIZE */
|
||||
|
||||
extern struct per_cpu_region per_cpu_data[MAX_PCPU_NUM];
|
||||
|
Reference in New Issue
Block a user