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:
parent
c0faf0f3e7
commit
5b2287bddc
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user