Add support for PSCI CPU_OFF, relying on KVM emulation of a 'powered off' vCPU by setting the MP state to KVM_MP_STATE_STOPPED. Signed-off-by: Oliver Upton <oliver.upton@xxxxxxxxx> --- arm/aarch64/psci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c index abfdc764b7e0..72429b36a835 100644 --- a/arm/aarch64/psci.c +++ b/arm/aarch64/psci.c @@ -17,6 +17,7 @@ static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res) switch (arg) { case PSCI_0_2_FN_CPU_SUSPEND: case PSCI_0_2_FN64_CPU_SUSPEND: + case PSCI_0_2_FN_CPU_OFF: case ARM_SMCCC_VERSION_FUNC_ID: res->a0 = PSCI_RET_SUCCESS; break; @@ -36,6 +37,16 @@ static void cpu_suspend(struct kvm_cpu *vcpu, struct arm_smccc_res *res) res->a0 = PSCI_RET_SUCCESS; } +static void cpu_off(struct kvm_cpu *vcpu, struct arm_smccc_res *res) +{ + struct kvm_mp_state mp_state = { + .mp_state = KVM_MP_STATE_STOPPED, + }; + + if (ioctl(vcpu->vcpu_fd, KVM_SET_MP_STATE, &mp_state)) + die_perror("KVM_SET_MP_STATE failed"); +} + void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res) { switch (vcpu->kvm_run->hypercall.nr) { @@ -49,6 +60,9 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res) case PSCI_0_2_FN64_CPU_SUSPEND: cpu_suspend(vcpu, res); break; + case PSCI_0_2_FN_CPU_OFF: + cpu_off(vcpu, res); + break; default: res->a0 = PSCI_RET_NOT_SUPPORTED; } -- 2.41.0.rc0.172.g3f132b7071-goog