Skip to content

Commit a6ff3a9

Browse files
JasonChenCJlijinxia
authored andcommitted
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>
1 parent d2a7a9c commit a6ff3a9

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

hypervisor/arch/x86/guest/vm.c

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,14 @@ static void init_vm(struct vm_description *vm_desc,
5656
struct vm *vm_handle)
5757
{
5858
/* Populate VM attributes from VM description */
59-
vm_handle->hw.num_vcpus = vm_desc->vm_hw_num_cores;
59+
if (is_vm0(vm_handle)) {
60+
/* Allocate all cpus to vm0 at the beginning */
61+
vm_handle->hw.num_vcpus = phy_cpu_num;
62+
vm_handle->hw.exp_num_vcpus = vm_desc->vm_hw_num_cores;
63+
} else {
64+
vm_handle->hw.num_vcpus = vm_desc->vm_hw_num_cores;
65+
vm_handle->hw.exp_num_vcpus = vm_desc->vm_hw_num_cores;
66+
}
6067
vm_handle->state_info.privilege = vm_desc->vm_state_info_privilege;
6168
vm_handle->state_info.boot_count = 0;
6269
}
@@ -316,11 +323,9 @@ int prepare_vm0(void)
316323
ret = create_vm(vm_desc, &vm);
317324
ASSERT(ret == 0, "VM creation failed!");
318325

319-
prepare_vcpu(vm, vm_desc->vm_hw_logical_core_ids[0]);
320-
321-
/* Prepare the AP for vm0 */
322-
for (i = 1; i < vm_desc->vm_hw_num_cores; i++)
323-
prepare_vcpu(vm, vm_desc->vm_hw_logical_core_ids[i]);
326+
/* Allocate all cpus to vm0 at the beginning */
327+
for (i = 0; i < phy_cpu_num; i++)
328+
prepare_vcpu(vm, i);
324329

325330
/* start vm0 BSP automatically */
326331
start_vm(vm);
@@ -329,3 +334,48 @@ int prepare_vm0(void)
329334

330335
return 0;
331336
}
337+
338+
static inline bool vcpu_in_vm_desc(struct vcpu *vcpu,
339+
struct vm_description *vm_desc)
340+
{
341+
int i;
342+
343+
for (i = 0; i < vm_desc->vm_hw_num_cores; i++) {
344+
if (vcpu->pcpu_id == vm_desc->vm_hw_logical_core_ids[i])
345+
return true;
346+
}
347+
348+
return false;
349+
}
350+
351+
/*
352+
* fixup vm0 for expected vcpu:
353+
* vm0 is starting with all physical cpus, it's mainly for UEFI boot to
354+
* handle all physical mapped APs wakeup during boot service exit.
355+
* this fixup is used to pause then destroy non-expect-enabled vcpus from VM0.
356+
*
357+
* NOTE: if you want to enable mult-vpucs for vm0, please make sure the pcpu_id
358+
* is in order, for example:
359+
* - one vcpu: VM0_CPUS[VM0_NUM_CPUS] = {0};
360+
* - two vcpus: VM0_CPUS[VM0_NUM_CPUS] = {0, 1};
361+
* - three vcpus: VM0_CPUS[VM0_NUM_CPUS] = {0, 1, 2};
362+
*/
363+
void vm_fixup(struct vm *vm)
364+
{
365+
if (is_vm0(vm) && (vm->hw.exp_num_vcpus < vm->hw.num_vcpus)) {
366+
struct vm_description *vm_desc = NULL;
367+
struct vcpu *vcpu;
368+
int i;
369+
370+
vm_desc = get_vm_desc(0);
371+
foreach_vcpu(i, vm, vcpu) {
372+
if (!vcpu_in_vm_desc(vcpu, vm_desc)) {
373+
pause_vcpu(vcpu, VCPU_ZOMBIE);
374+
reset_vcpu(vcpu);
375+
destroy_vcpu(vcpu);
376+
}
377+
}
378+
379+
vm->hw.num_vcpus = vm->hw.exp_num_vcpus;
380+
}
381+
}

hypervisor/arch/x86/guest/vmcall.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
5555
/* Dispatch the hypercall handler */
5656
switch (hypcall_id) {
5757
case HC_GET_API_VERSION:
58+
/* vm0 will call HC_GET_API_VERSION as first hypercall, fixup
59+
* vm0 vcpu here.
60+
*/
61+
vm_fixup(vm);
5862
ret = hcall_get_api_version(vm, param1);
5963
break;
6064

hypervisor/include/arch/x86/guest/vm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct vm_attr {
4646

4747
struct vm_hw_info {
4848
int num_vcpus; /* Number of total virtual cores */
49+
int exp_num_vcpus; /* Number of real expected virtual cores */
4950
uint32_t created_vcpus; /* Number of created vcpus */
5051
struct vcpu **vcpu_array; /* vcpu array of this VM */
5152
uint64_t gpa_lowtop; /* top lowmem gpa of this VM */
@@ -218,6 +219,7 @@ int pause_vm(struct vm *vm);
218219
int start_vm(struct vm *vm);
219220
int create_vm(struct vm_description *vm_desc, struct vm **vm);
220221
int prepare_vm0(void);
222+
void vm_fixup(struct vm *vm);
221223

222224
struct vm *get_vm_from_vmid(int vm_id);
223225
struct vm_description *get_vm_desc(int idx);

0 commit comments

Comments
 (0)