mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 04:02:05 +00:00
vm: allocated all pcpus to vm0 at the beginning
allocated all pcpus to vm0 to handle possible AP wakeup flow for all cpus, as we pass org ACPI table to VM0 - that means VM0 can see all CPUs. SOS(VM0) start expected CPUs through "maxcpus=" kernel cmdline option. During first hypercall from SOS, calling vm_fixup to free un-expect-enabled vcpus from VM0. Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Xu, Anthony <anthony.xu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
d2a7a9c91d
commit
a6ff3a9bdc
@ -56,7 +56,14 @@ static void init_vm(struct vm_description *vm_desc,
|
|||||||
struct vm *vm_handle)
|
struct vm *vm_handle)
|
||||||
{
|
{
|
||||||
/* Populate VM attributes from VM description */
|
/* Populate VM attributes from VM description */
|
||||||
vm_handle->hw.num_vcpus = vm_desc->vm_hw_num_cores;
|
if (is_vm0(vm_handle)) {
|
||||||
|
/* Allocate all cpus to vm0 at the beginning */
|
||||||
|
vm_handle->hw.num_vcpus = phy_cpu_num;
|
||||||
|
vm_handle->hw.exp_num_vcpus = vm_desc->vm_hw_num_cores;
|
||||||
|
} else {
|
||||||
|
vm_handle->hw.num_vcpus = vm_desc->vm_hw_num_cores;
|
||||||
|
vm_handle->hw.exp_num_vcpus = vm_desc->vm_hw_num_cores;
|
||||||
|
}
|
||||||
vm_handle->state_info.privilege = vm_desc->vm_state_info_privilege;
|
vm_handle->state_info.privilege = vm_desc->vm_state_info_privilege;
|
||||||
vm_handle->state_info.boot_count = 0;
|
vm_handle->state_info.boot_count = 0;
|
||||||
}
|
}
|
||||||
@ -316,11 +323,9 @@ int prepare_vm0(void)
|
|||||||
ret = create_vm(vm_desc, &vm);
|
ret = create_vm(vm_desc, &vm);
|
||||||
ASSERT(ret == 0, "VM creation failed!");
|
ASSERT(ret == 0, "VM creation failed!");
|
||||||
|
|
||||||
prepare_vcpu(vm, vm_desc->vm_hw_logical_core_ids[0]);
|
/* Allocate all cpus to vm0 at the beginning */
|
||||||
|
for (i = 0; i < phy_cpu_num; i++)
|
||||||
/* Prepare the AP for vm0 */
|
prepare_vcpu(vm, i);
|
||||||
for (i = 1; i < vm_desc->vm_hw_num_cores; i++)
|
|
||||||
prepare_vcpu(vm, vm_desc->vm_hw_logical_core_ids[i]);
|
|
||||||
|
|
||||||
/* start vm0 BSP automatically */
|
/* start vm0 BSP automatically */
|
||||||
start_vm(vm);
|
start_vm(vm);
|
||||||
@ -329,3 +334,48 @@ int prepare_vm0(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool vcpu_in_vm_desc(struct vcpu *vcpu,
|
||||||
|
struct vm_description *vm_desc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < vm_desc->vm_hw_num_cores; i++) {
|
||||||
|
if (vcpu->pcpu_id == vm_desc->vm_hw_logical_core_ids[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fixup vm0 for expected vcpu:
|
||||||
|
* vm0 is starting with all physical cpus, it's mainly for UEFI boot to
|
||||||
|
* handle all physical mapped APs wakeup during boot service exit.
|
||||||
|
* this fixup is used to pause then destroy non-expect-enabled vcpus from VM0.
|
||||||
|
*
|
||||||
|
* NOTE: if you want to enable mult-vpucs for vm0, please make sure the pcpu_id
|
||||||
|
* is in order, for example:
|
||||||
|
* - one vcpu: VM0_CPUS[VM0_NUM_CPUS] = {0};
|
||||||
|
* - two vcpus: VM0_CPUS[VM0_NUM_CPUS] = {0, 1};
|
||||||
|
* - three vcpus: VM0_CPUS[VM0_NUM_CPUS] = {0, 1, 2};
|
||||||
|
*/
|
||||||
|
void vm_fixup(struct vm *vm)
|
||||||
|
{
|
||||||
|
if (is_vm0(vm) && (vm->hw.exp_num_vcpus < vm->hw.num_vcpus)) {
|
||||||
|
struct vm_description *vm_desc = NULL;
|
||||||
|
struct vcpu *vcpu;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
vm_desc = get_vm_desc(0);
|
||||||
|
foreach_vcpu(i, vm, vcpu) {
|
||||||
|
if (!vcpu_in_vm_desc(vcpu, vm_desc)) {
|
||||||
|
pause_vcpu(vcpu, VCPU_ZOMBIE);
|
||||||
|
reset_vcpu(vcpu);
|
||||||
|
destroy_vcpu(vcpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vm->hw.num_vcpus = vm->hw.exp_num_vcpus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,6 +55,10 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
|
|||||||
/* Dispatch the hypercall handler */
|
/* Dispatch the hypercall handler */
|
||||||
switch (hypcall_id) {
|
switch (hypcall_id) {
|
||||||
case HC_GET_API_VERSION:
|
case HC_GET_API_VERSION:
|
||||||
|
/* vm0 will call HC_GET_API_VERSION as first hypercall, fixup
|
||||||
|
* vm0 vcpu here.
|
||||||
|
*/
|
||||||
|
vm_fixup(vm);
|
||||||
ret = hcall_get_api_version(vm, param1);
|
ret = hcall_get_api_version(vm, param1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ struct vm_attr {
|
|||||||
|
|
||||||
struct vm_hw_info {
|
struct vm_hw_info {
|
||||||
int num_vcpus; /* Number of total virtual cores */
|
int num_vcpus; /* Number of total virtual cores */
|
||||||
|
int exp_num_vcpus; /* Number of real expected virtual cores */
|
||||||
uint32_t created_vcpus; /* Number of created vcpus */
|
uint32_t created_vcpus; /* Number of created vcpus */
|
||||||
struct vcpu **vcpu_array; /* vcpu array of this VM */
|
struct vcpu **vcpu_array; /* vcpu array of this VM */
|
||||||
uint64_t gpa_lowtop; /* top lowmem gpa of this VM */
|
uint64_t gpa_lowtop; /* top lowmem gpa of this VM */
|
||||||
@ -218,6 +219,7 @@ int pause_vm(struct vm *vm);
|
|||||||
int start_vm(struct vm *vm);
|
int start_vm(struct vm *vm);
|
||||||
int create_vm(struct vm_description *vm_desc, struct vm **vm);
|
int create_vm(struct vm_description *vm_desc, struct vm **vm);
|
||||||
int prepare_vm0(void);
|
int prepare_vm0(void);
|
||||||
|
void vm_fixup(struct vm *vm);
|
||||||
|
|
||||||
struct vm *get_vm_from_vmid(int vm_id);
|
struct vm *get_vm_from_vmid(int vm_id);
|
||||||
struct vm_description *get_vm_desc(int idx);
|
struct vm_description *get_vm_desc(int idx);
|
||||||
|
Loading…
Reference in New Issue
Block a user