ANDROID: KVM: arm64: Add a permission fault handler

In preparation for allowing to restrict host permissions at stage-2 for
certain pages, introduce some infrastructure allowing a pKVM module to
register a permission fault handler.

Bug: 244543039
Bug: 244373730
Change-Id: I8035c64969cc0ebb01c8936b1974b3bc103ba84f
Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
Quentin Perret 2022-10-25 16:06:39 +00:00
parent c0faf0f3e7
commit 5b2287bddc
4 changed files with 21 additions and 0 deletions

View File

@ -16,6 +16,7 @@ struct pkvm_module_ops {
void *(*fixmap_map)(phys_addr_t phys);
void (*fixmap_unmap)(void);
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));
};
struct pkvm_module_section {

View File

@ -92,6 +92,7 @@ int kvm_host_prepare_stage2(void *pgt_pool_base);
int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd);
void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
int hyp_register_host_perm_fault_handler(int (*cb)(struct kvm_cpu_context *ctxt, u64 esr, u64 addr));
int hyp_pin_shared_mem(void *from, void *to);
void hyp_unpin_shared_mem(void *from, void *to);
void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc);

View File

@ -717,6 +717,21 @@ static bool is_dabt(u64 esr)
return ESR_ELx_EC(esr) == ESR_ELx_EC_DABT_LOW;
}
static int (*perm_fault_handler)(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr);
int hyp_register_host_perm_fault_handler(int (*cb)(struct kvm_cpu_context *ctxt, u64 esr, u64 addr))
{
return cmpxchg(&perm_fault_handler, NULL, cb) ? -EBUSY : 0;
}
static int handle_host_perm_fault(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr)
{
int (*cb)(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr);
cb = READ_ONCE(perm_fault_handler);
return cb ? cb(host_ctxt, esr, addr) : -EPERM;
}
void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
{
struct kvm_vcpu_fault_info fault;
@ -742,6 +757,9 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
host_unlock_component();
if ((esr & ESR_ELx_FSC_TYPE) == FSC_PERM)
ret = handle_host_perm_fault(host_ctxt, esr, addr);
if (ret == -EPERM)
host_inject_abort(host_ctxt);
else

View File

@ -22,6 +22,7 @@ const struct pkvm_module_ops module_ops = {
.fixmap_map = hyp_fixmap_map,
.fixmap_unmap = hyp_fixmap_unmap,
.flush_dcache_to_poc = __kvm_flush_dcache_to_poc,
.register_host_perm_fault_handler = hyp_register_host_perm_fault_handler,
};
int __pkvm_init_module(void *module_init)