diff --git a/libsel4vm/src/boot.c b/libsel4vm/src/boot.c index fa05dab18..29d4cade4 100644 --- a/libsel4vm/src/boot.c +++ b/libsel4vm/src/boot.c @@ -88,7 +88,7 @@ int vm_assign_vcpu_target(vm_vcpu_t *vcpu, int target_cpu) return -1; } vm_vcpu_t *target_vcpu = vm_vcpu_for_target_cpu(vcpu->vm, target_cpu); - if (target_vcpu) { + if (target_vcpu && (target_vcpu != vcpu)) { ZF_LOGE("Failed to assign target cpu - A VCPU is already assigned to core %d", target_cpu); return -1; } diff --git a/libsel4vmmplatsupport/src/arch/arm/psci.c b/libsel4vmmplatsupport/src/arch/arm/psci.c index 504bbf58c..a093ee8a7 100644 --- a/libsel4vmmplatsupport/src/arch/arm/psci.c +++ b/libsel4vmmplatsupport/src/arch/arm/psci.c @@ -70,12 +70,19 @@ int handle_psci(vm_vcpu_t *vcpu, seL4_Word fn_number, bool convention) ZF_LOGE("[vCPU %u] no unused physical core left", vcpu->vcpu_id); smc_set_return_value(®s, PSCI_INTERNAL_FAILURE); } - } else { + } else if ((target_vcpu->target_cpu >= 0) && (target_vcpu->target_cpu < CONFIG_MAX_NUM_NODES)) { + /* Assign vcpu to physical cpu specified in config */ if (is_vcpu_online(target_vcpu)) { smc_set_return_value(®s, PSCI_ALREADY_ON); + } else if (start_new_vcpu(target_vcpu, entry_point_address, context_id, target_vcpu->target_cpu) == 0) { + smc_set_return_value(®s, PSCI_SUCCESS); } else { + ZF_LOGE("[vCPU %u] could not start vCPU", vcpu->vcpu_id); smc_set_return_value(®s, PSCI_INTERNAL_FAILURE); } + } else { + ZF_LOGE("[vCPU %u] invalid target CPU %d", vcpu->vcpu_id, target_vcpu->target_cpu); + smc_set_return_value(®s, PSCI_INTERNAL_FAILURE); } break;