mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
ANDROID: KVM: arm64: Notify pKVM modules of PSCI events
Introduce a notifier allowing a pKVM module to be notified for major
PSCI events: {CPU,SYSTEM}_SUSPEND, as well as on the resume path.
Bug: 244543039
Bug: 245034629
Change-Id: Ia82923445214925fc77e321457c8eab31f9d42e8
Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
@@ -8,6 +8,12 @@
|
||||
|
||||
typedef void (*dyn_hcall_t)(struct kvm_cpu_context *);
|
||||
|
||||
enum pkvm_psci_notification {
|
||||
PKVM_PSCI_CPU_SUSPEND,
|
||||
PKVM_PSCI_SYSTEM_SUSPEND,
|
||||
PKVM_PSCI_CPU_ENTRY,
|
||||
};
|
||||
|
||||
struct pkvm_module_ops {
|
||||
int (*create_private_mapping)(phys_addr_t phys, size_t size,
|
||||
enum kvm_pgtable_prot prot,
|
||||
@@ -22,6 +28,7 @@ struct pkvm_module_ops {
|
||||
int (*protect_host_page)(u64 pfn, enum kvm_pgtable_prot prot);
|
||||
int (*register_host_smc_handler)(bool (*cb)(struct kvm_cpu_context *));
|
||||
int (*register_illegal_abt_notifier)(void (*cb)(struct kvm_cpu_context *));
|
||||
int (*register_psci_notifier)(void (*cb)(enum pkvm_psci_notification, struct kvm_cpu_context *));
|
||||
};
|
||||
|
||||
struct pkvm_module_section {
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
int __pkvm_register_host_smc_handler(bool (*cb)(struct kvm_cpu_context *));
|
||||
int __pkvm_register_illegal_abt_notifier(void (*cb)(struct kvm_cpu_context *));
|
||||
|
||||
enum pkvm_psci_notification;
|
||||
int __pkvm_register_psci_notifier(void (*cb)(enum pkvm_psci_notification, struct kvm_cpu_context *));
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
int __pkvm_init_module(void *module_init);
|
||||
int __pkvm_register_hcall(unsigned long hfn_hyp_va);
|
||||
|
||||
@@ -65,6 +65,7 @@ const struct pkvm_module_ops module_ops = {
|
||||
.protect_host_page = hyp_protect_host_page,
|
||||
.register_host_smc_handler = __pkvm_register_host_smc_handler,
|
||||
.register_illegal_abt_notifier = __pkvm_register_illegal_abt_notifier,
|
||||
.register_psci_notifier = __pkvm_register_psci_notifier,
|
||||
};
|
||||
|
||||
int __pkvm_init_module(void *module_init)
|
||||
|
||||
@@ -24,6 +24,18 @@ void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
|
||||
/* Config options set by the host. */
|
||||
struct kvm_host_psci_config __ro_after_init kvm_host_psci_config;
|
||||
|
||||
static void (*pkvm_psci_notifier)(enum pkvm_psci_notification, struct kvm_cpu_context *);
|
||||
static void pkvm_psci_notify(enum pkvm_psci_notification notif, struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
if (READ_ONCE(pkvm_psci_notifier))
|
||||
pkvm_psci_notifier(notif, host_ctxt);
|
||||
}
|
||||
|
||||
int __pkvm_register_psci_notifier(void (*cb)(enum pkvm_psci_notification, struct kvm_cpu_context *))
|
||||
{
|
||||
return cmpxchg(&pkvm_psci_notifier, NULL, cb) ? -EBUSY : 0;
|
||||
}
|
||||
|
||||
#define INVALID_CPU_ID UINT_MAX
|
||||
|
||||
struct psci_boot_args {
|
||||
@@ -169,6 +181,8 @@ static int psci_cpu_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt)
|
||||
boot_args->pc = pc;
|
||||
boot_args->r0 = r0;
|
||||
|
||||
pkvm_psci_notify(PKVM_PSCI_CPU_SUSPEND, host_ctxt);
|
||||
|
||||
/*
|
||||
* Will either return if shallow sleep state, or wake up into the entry
|
||||
* point if it is a deep sleep state.
|
||||
@@ -196,6 +210,8 @@ static int psci_system_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt)
|
||||
boot_args->pc = pc;
|
||||
boot_args->r0 = r0;
|
||||
|
||||
pkvm_psci_notify(PKVM_PSCI_SYSTEM_SUSPEND, host_ctxt);
|
||||
|
||||
/* Will only return on error. */
|
||||
return psci_call(func_id,
|
||||
__hyp_pa(&kvm_hyp_cpu_resume),
|
||||
@@ -220,6 +236,8 @@ asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on)
|
||||
if (is_cpu_on)
|
||||
release_boot_args(boot_args);
|
||||
|
||||
pkvm_psci_notify(PKVM_PSCI_CPU_ENTRY, host_ctxt);
|
||||
|
||||
__host_enter(host_ctxt);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user