refactor: cpu_on helper
Decouple the cpu_on helper from enabling a corresponding vCPU.
Extract the vCPU enabling logic and add explicitly within the PVM PSCI
cpu on handler and SPMC's psci resume where cpu_on is called.
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: I6a044a94853adf35f1008b5fe6e5fb9c7c0c3ca2
diff --git a/inc/hf/cpu.h b/inc/hf/cpu.h
index 74d61c1..305f2f8 100644
--- a/inc/hf/cpu.h
+++ b/inc/hf/cpu.h
@@ -33,7 +33,7 @@
size_t cpu_index(struct cpu *c);
struct cpu *cpu_find_index(size_t index);
-bool cpu_on(struct cpu *c, ipaddr_t entry, uintreg_t arg);
+bool cpu_on(struct cpu *c);
void cpu_off(struct cpu *c);
struct cpu *cpu_find(cpu_id_t id);
uint8_t *cpu_get_buffer(struct cpu *c);
diff --git a/src/arch/aarch64/hypervisor/psci_handler.c b/src/arch/aarch64/hypervisor/psci_handler.c
index 053afad..b1e1843 100644
--- a/src/arch/aarch64/hypervisor/psci_handler.c
+++ b/src/arch/aarch64/hypervisor/psci_handler.c
@@ -38,6 +38,8 @@
{
struct cpu *c;
struct ffa_value smc_res;
+ struct vcpu *vcpu_target;
+ struct vcpu_locked vcpu_locked;
/*
* If there's a problem with the EL3 PSCI, block standard secure service
@@ -160,11 +162,16 @@
break;
}
- if (cpu_on(c, ipa_init(arg1), arg2)) {
+ if (cpu_on(c)) {
*ret = PSCI_ERROR_ALREADY_ON;
break;
}
+ vcpu_target = vm_get_vcpu(vcpu->vm, cpu_index(c));
+ vcpu_locked = vcpu_lock(vcpu_target);
+ vcpu_on(vcpu_locked, ipa_init(arg1), arg2);
+ vcpu_unlock(&vcpu_locked);
+
/*
* There's a race when turning a CPU on when it's in the
* process of turning off. We need to loop here while it is
diff --git a/src/arch/aarch64/plat/psci/spmc.c b/src/arch/aarch64/plat/psci/spmc.c
index 8395ab0..d99e744 100644
--- a/src/arch/aarch64/plat/psci/spmc.c
+++ b/src/arch/aarch64/plat/psci/spmc.c
@@ -8,6 +8,7 @@
#include "hf/cpu.h"
#include "hf/dlog.h"
+#include "hf/vm.h"
#include "psci.h"
@@ -51,11 +52,14 @@
void plat_psci_cpu_resume(struct cpu *c, ipaddr_t entry_point)
{
- if (cpu_on(c, entry_point, 0UL)) {
- /*
- * This is the boot time PSCI cold reset path (svc_cpu_on_finish
- * handler relayed by SPMD) on secondary cores.
- */
- dlog_verbose("%s: cpu mpidr 0x%x ON\n", __func__, c->id);
+ struct vcpu *vcpu = vcpu_get_boot_vcpu();
+ struct vm *vm = vcpu->vm;
+ struct vcpu_locked vcpu_locked;
+
+ if (!cpu_on(c)) {
+ vcpu = vm_get_vcpu(vm, cpu_index(c));
+ vcpu_locked = vcpu_lock(vcpu);
+ vcpu_on(vcpu_locked, entry_point, 0LL);
+ vcpu_unlock(&vcpu_locked);
}
}
diff --git a/src/cpu.c b/src/cpu.c
index 8469531..0895cc8 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -141,7 +141,7 @@
/**
* Turns CPU on and returns the previous state.
*/
-bool cpu_on(struct cpu *c, ipaddr_t entry, uintreg_t arg)
+bool cpu_on(struct cpu *c)
{
bool prev;
@@ -150,16 +150,6 @@
c->is_on = true;
sl_unlock(&c->lock);
- if (!prev) {
- struct vcpu *boot_vcpu = vcpu_get_boot_vcpu();
- struct vcpu_locked vcpu_locked;
-
- vcpu_locked =
- vcpu_lock(vm_get_vcpu(boot_vcpu->vm, cpu_index(c)));
- vcpu_on(vcpu_locked, entry, arg);
- vcpu_unlock(&vcpu_locked);
- }
-
return prev;
}