From 2cf00d824324b48e3ff4f9f3ee002411a37caa76 Mon Sep 17 00:00:00 2001 From: Alex Pavey Date: Mon, 19 Oct 2020 10:19:39 -0400 Subject: [PATCH 1/3] libsel4vm: set affinity in vm_assign_vcpu_target Calling seL4_TCB_SetAffinity in the vm_assign_vcpu_target function allows the vcpu to correctly run on the cpu it is assigned to. Previously the vcpu was getting assigned to the same core as it's ID. Signed-off-by: Alex Pavey --- libsel4vm/src/arch/arm/boot.c | 6 ------ libsel4vm/src/boot.c | 9 +++++++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libsel4vm/src/arch/arm/boot.c b/libsel4vm/src/arch/arm/boot.c index a4b171412..25f13fced 100644 --- a/libsel4vm/src/arch/arm/boot.c +++ b/libsel4vm/src/arch/arm/boot.c @@ -110,12 +110,6 @@ int vm_create_vcpu_arch(vm_t *vm, vm_vcpu_t *vcpu) vcpu->vcpu_arch.unhandled_vcpu_callback = NULL; vcpu->vcpu_arch.unhandled_vcpu_callback_cookie = NULL; -#if CONFIG_MAX_NUM_NODES > 1 - if (seL4_TCB_SetAffinity(vcpu->tcb.tcb.cptr, vcpu->vcpu_id)) { - err = -1; - } -#endif /* CONFIG_MAX_NUM_NODES > 1 */ - #ifdef CONFIG_DEBUG_BUILD char vcpu_name[32]; snprintf(vcpu_name, sizeof(vcpu_name), "%s:%d", vm->vm_name, vcpu->vcpu_id); diff --git a/libsel4vm/src/boot.c b/libsel4vm/src/boot.c index 656ef9a8b..fa05dab18 100644 --- a/libsel4vm/src/boot.c +++ b/libsel4vm/src/boot.c @@ -92,6 +92,15 @@ int vm_assign_vcpu_target(vm_vcpu_t *vcpu, int target_cpu) ZF_LOGE("Failed to assign target cpu - A VCPU is already assigned to core %d", target_cpu); return -1; } + +#if CONFIG_MAX_NUM_NODES > 1 + int err = seL4_TCB_SetAffinity(vcpu->tcb.tcb.cptr, target_cpu); + if (err) { + ZF_LOGE("[vCPU %u] Failed to set vCPU affinity to %d", vcpu->vcpu_id, target_cpu); + return -1; + } +#endif /* CONFIG_MAX_NUM_NODES > 1 */ + vcpu->target_cpu = target_cpu; return 0; } From cd1aab7abc5a2d23595fd3c599cfab20c2aa9731 Mon Sep 17 00:00:00 2001 From: Alex Pavey Date: Mon, 11 Jan 2021 15:18:42 -0500 Subject: [PATCH 2/3] libsel4vm: start a vcpu even if assigned a pcpu Previously the target_cpu member was being used to determine if a vcpu was started in conjunction with the is_vcpu_online function. This is unneccessary and has been repurposed to keep track of whether or not the vcpu has been previously assigned a pcpu or not. Signed-off-by: Alex Pavey --- libsel4vm/src/boot.c | 2 +- libsel4vmmplatsupport/src/arch/arm/psci.c | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) 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 fca47f874..e372a24cb 100644 --- a/libsel4vmmplatsupport/src/arch/arm/psci.c +++ b/libsel4vmmplatsupport/src/arch/arm/psci.c @@ -55,12 +55,19 @@ int handle_psci(vm_vcpu_t *vcpu, seL4_UserContext *regs, seL4_Word fn_number, bo } else { smc_set_return_value(regs, 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(regs, PSCI_ALREADY_ON); + } else if (start_new_vcpu(target_vcpu, entry_point_address, context_id, target_vcpu->target_cpu) == 0) { + smc_set_return_value(regs, PSCI_SUCCESS); } else { + ZF_LOGE("[vCPU %u] could not start vCPU", vcpu->vcpu_id); smc_set_return_value(regs, PSCI_INTERNAL_FAILURE); } + } else { + ZF_LOGE("[vCPU %u] invalid target CPU %d", vcpu->vcpu_id, target_vcpu->target_cpu); + smc_set_return_value(regs, PSCI_INTERNAL_FAILURE); } break; From 2094fefc63093b4b6a96e09b04edaf95085da6a0 Mon Sep 17 00:00:00 2001 From: Alex Pavey Date: Wed, 21 Apr 2021 21:13:26 -0400 Subject: [PATCH 3/3] trivial: Set vmpidr value to vcpu instead pcpu Signed-off-by: Alex Pavey --- libsel4vm/src/arch/arm/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsel4vm/src/arch/arm/vm.c b/libsel4vm/src/arch/arm/vm.c index ceb7993b8..40d6d4414 100644 --- a/libsel4vm/src/arch/arm/vm.c +++ b/libsel4vm/src/arch/arm/vm.c @@ -181,7 +181,7 @@ int vcpu_start(vm_vcpu_t *vcpu) */ vmpidr_val = BIT(24) | BIT(31); } else { - vmpidr_val = vcpu->target_cpu; + vmpidr_val = vcpu->vcpu_id; } err = vm_set_arm_vcpu_reg(vcpu, vmpidr_reg, vmpidr_val); if (err) {