ANDROID: KVM: arm64: Allow SMC handling from pKVM modules

Introduce a new default SMC handler for the host that can be set from
modules.

Bug: 244543039
Bug: 245034629
Change-Id: I8481bfb1926a3cb433b15de5c1a99e3550710689
Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
Quentin Perret
2022-12-07 13:25:36 +00:00
parent 602558500f
commit 08d23cafc5
4 changed files with 14 additions and 6 deletions

View File

@@ -20,6 +20,7 @@ struct pkvm_module_ops {
void (*flush_dcache_to_poc)(void *addr, size_t size);
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 *));
};
struct pkvm_module_section {

View File

@@ -3,6 +3,8 @@
#define HCALL_HANDLED 0
#define HCALL_UNHANDLED -1
int __pkvm_register_host_smc_handler(bool (*cb)(struct kvm_cpu_context *));
#ifdef CONFIG_MODULES
int __pkvm_init_module(void *module_init);
int __pkvm_register_hcall(unsigned long hfn_hyp_va);

View File

@@ -40,6 +40,13 @@ DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
void __kvm_hyp_host_forward_smc(struct kvm_cpu_context *host_ctxt);
static bool (*default_host_smc_handler)(struct kvm_cpu_context *host_ctxt);
int __pkvm_register_host_smc_handler(bool (*cb)(struct kvm_cpu_context *))
{
return cmpxchg(&default_host_smc_handler, NULL, cb) ? -EBUSY : 0;
}
static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
{
struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu);
@@ -1283,11 +1290,6 @@ inval:
cpu_reg(host_ctxt, 0) = SMCCC_RET_NOT_SUPPORTED;
}
static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt)
{
__kvm_hyp_host_forward_smc(host_ctxt);
}
static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
{
bool handled;
@@ -1295,8 +1297,10 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
handled = kvm_host_psci_handler(host_ctxt);
if (!handled)
handled = kvm_host_ffa_handler(host_ctxt);
if (!handled && READ_ONCE(default_host_smc_handler))
handled = default_host_smc_handler(host_ctxt);
if (!handled)
default_host_smc_handler(host_ctxt);
__kvm_hyp_host_forward_smc(host_ctxt);
/* SMC was trapped, move ELR past the current PC. */
kvm_skip_host_instr();

View File

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