diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 906a29f00..845adee09 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -166,21 +166,35 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) /* Filter out the bits should not set by DM and then assign it to guest_flags */ vm_config->guest_flags |= (cv.vm_flag & DM_OWNED_GUEST_FLAG_MASK); - /* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */ - if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U) - && ((vm_config->guest_flags & GUEST_FLAG_RT) == 0U)) { - pr_err("Wrong guest flags 0x%lx\n", vm_config->guest_flags); + /* post-launched VM is allowed to choose pCPUs from vm_config->cpu_affinity_bitmap only */ + if ((cv.cpu_affinity & ~(vm_config->cpu_affinity_bitmap)) != 0UL) { + pr_err("%s: Post-launch VM can't share PCPU with Pre-launch VM!", __func__); } else { - if (create_vm(vm_id, vm_config, &target_vm) != 0) { - dev_dbg(DBG_LEVEL_HYCALL, "HCALL: Create VM failed"); - cv.vmid = ACRN_INVALID_VMID; - } else { - /* return a relative vm_id from SOS view */ - cv.vmid = vmid_2_rel_vmid(vm->vm_id, vm_id); - cv.vcpu_num = vm_config->vcpu_num; + /* DM could overwrite the statically configured PCPU bitmap */ + if (bitmap_weight(cv.cpu_affinity) != 0U) { + vm_config->vcpu_num = bitmap_weight(cv.cpu_affinity); + vm_config->cpu_affinity_bitmap = cv.cpu_affinity; } - ret = copy_to_gpa(vm, &cv, param, sizeof(cv)); + /* + * GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH + * set in guest_flags + */ + if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0UL) + && ((vm_config->guest_flags & GUEST_FLAG_RT) == 0UL)) { + pr_err("Wrong guest flags 0x%lx\n", vm_config->guest_flags); + } else { + if (create_vm(vm_id, vm_config, &target_vm) != 0) { + dev_dbg(DBG_LEVEL_HYCALL, "HCALL: Create VM failed"); + cv.vmid = ACRN_INVALID_VMID; + } else { + /* return a relative vm_id from SOS view */ + cv.vmid = vmid_2_rel_vmid(vm->vm_id, vm_id); + cv.vcpu_num = vm_config->vcpu_num; + } + + ret = copy_to_gpa(vm, &cv, param, sizeof(cv)); + } } } } diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index f89429486..4289f37e9 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -360,8 +360,15 @@ struct acrn_create_vm { uint64_t req_buf; + /** + * The least significant set bit is the PCPU # the VCPU 0 maps to; + * second set least significant bit is the PCPU # the VCPU 1 maps to; + * and so on... + */ + uint64_t cpu_affinity; + /** Reserved for future use*/ - uint8_t reserved2[16]; + uint8_t reserved2[8]; } __aligned(8); /**