ANDROID: KVM: arm64: Allow handling illegal aborts from pKVM modules

Introduce a new handler allowing to notify pKVM modules when pKVM
detects an illegal access from the host.

Bug: 244543039
Bug: 245034629
Change-Id: I62133a8d967d91437e5216b307e449f8c83dfab6
Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
Quentin Perret
2022-12-07 13:45:12 +00:00
parent 5c8793e6f5
commit 84cfedad9f
4 changed files with 13 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ struct pkvm_module_ops {
int (*register_host_perm_fault_handler)(int (*cb)(struct kvm_cpu_context *ctxt, u64 esr, u64 addr));
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 *));
};
struct pkvm_module_section {

View File

@@ -4,6 +4,7 @@
#define HCALL_UNHANDLED -1
int __pkvm_register_host_smc_handler(bool (*cb)(struct kvm_cpu_context *));
int __pkvm_register_illegal_abt_notifier(void (*cb)(struct kvm_cpu_context *));
#ifdef CONFIG_MODULES
int __pkvm_init_module(void *module_init);

View File

@@ -710,12 +710,22 @@ static int host_stage2_idmap(u64 addr)
return host_stage2_idmap_locked(range.start, range.end - range.start, prot, false);
}
static void (*illegal_abt_notifier)(struct kvm_cpu_context *host_ctxt);
int __pkvm_register_illegal_abt_notifier(void (*cb)(struct kvm_cpu_context *))
{
return cmpxchg(&illegal_abt_notifier, NULL, cb) ? -EBUSY : 0;
}
static void host_inject_abort(struct kvm_cpu_context *host_ctxt)
{
u64 spsr = read_sysreg_el2(SYS_SPSR);
u64 esr = read_sysreg_el2(SYS_ESR);
u64 ventry, ec;
if (READ_ONCE(illegal_abt_notifier))
illegal_abt_notifier(host_ctxt);
/* Repaint the ESR to report a same-level fault if taken from EL1 */
if ((spsr & PSR_MODE_MASK) != PSR_MODE_EL0t) {
ec = ESR_ELx_EC(esr);

View File

@@ -64,6 +64,7 @@ const struct pkvm_module_ops module_ops = {
.register_host_perm_fault_handler = hyp_register_host_perm_fault_handler,
.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,
};
int __pkvm_init_module(void *module_init)