Commit d945f8d9 authored by David Brazdil's avatar David Brazdil Committed by Marc Zyngier

KVM: arm64: Intercept host's SYSTEM_SUSPEND PSCI SMCs

Add a handler of SYSTEM_SUSPEND host PSCI SMCs. The semantics are
equivalent to CPU_SUSPEND, typically called on the last online CPU.
Reuse the same entry point and boot args struct as CPU_SUSPEND.
Signed-off-by: default avatarDavid Brazdil <dbrazdil@google.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20201202184122.26046-24-dbrazdil@google.com
parent abf16336
...@@ -151,7 +151,7 @@ SYM_CODE_START(kvm_hyp_cpu_entry) ...@@ -151,7 +151,7 @@ SYM_CODE_START(kvm_hyp_cpu_entry)
SYM_CODE_END(kvm_hyp_cpu_entry) SYM_CODE_END(kvm_hyp_cpu_entry)
/* /*
* PSCI CPU_SUSPEND entry point * PSCI CPU_SUSPEND / SYSTEM_SUSPEND entry point
* *
* x0: struct kvm_nvhe_init_params PA * x0: struct kvm_nvhe_init_params PA
*/ */
......
...@@ -201,6 +201,30 @@ static int psci_cpu_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt) ...@@ -201,6 +201,30 @@ static int psci_cpu_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt)
__hyp_pa(init_params)); __hyp_pa(init_params));
} }
static int psci_system_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt)
{
DECLARE_REG(unsigned long, pc, host_ctxt, 1);
DECLARE_REG(unsigned long, r0, host_ctxt, 2);
struct psci_boot_args *boot_args;
struct kvm_nvhe_init_params *init_params;
boot_args = this_cpu_ptr(hyp_symbol_addr(suspend_args));
init_params = this_cpu_ptr(hyp_symbol_addr(kvm_init_params));
/*
* No need to acquire a lock before writing to boot_args because a core
* can only suspend itself. Racy CPU_ON calls use a separate struct.
*/
boot_args->pc = pc;
boot_args->r0 = r0;
/* Will only return on error. */
return psci_call(func_id,
__hyp_pa(hyp_symbol_addr(kvm_hyp_cpu_resume)),
__hyp_pa(init_params), 0);
}
asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on) asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on)
{ {
struct psci_boot_args *boot_args; struct psci_boot_args *boot_args;
...@@ -265,6 +289,8 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ ...@@ -265,6 +289,8 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_
case PSCI_1_0_FN_SET_SUSPEND_MODE: case PSCI_1_0_FN_SET_SUSPEND_MODE:
case PSCI_1_1_FN64_SYSTEM_RESET2: case PSCI_1_1_FN64_SYSTEM_RESET2:
return psci_forward(host_ctxt); return psci_forward(host_ctxt);
case PSCI_1_0_FN64_SYSTEM_SUSPEND:
return psci_system_suspend(func_id, host_ctxt);
default: default:
return psci_0_2_handler(func_id, host_ctxt); return psci_0_2_handler(func_id, host_ctxt);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment