ANDROID: KVM: arm64: iommu: Add hyp_pool for guest pvIOMMU

Hyp pool would be used to cache guest allocations for the IOMMU, so
when they are freed they can be used again.

Also add a memcache for teardown of the pool.

Bug: 357781595
Bug: 348382247
Bug: 236685427
Change-Id: I43b0e097017efef4147ee5e94c7a77b4a251acb8
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Mostafa Saleh
2023-11-16 15:32:34 +00:00
committed by Carlos Llamas
parent 9dabecc2a2
commit f91d34f087
7 changed files with 21 additions and 5 deletions
+1
View File
@@ -295,6 +295,7 @@ struct kvm_protected_vm {
pkvm_handle_t handle;
struct kvm_hyp_memcache stage2_teardown_mc;
struct rb_root_cached pinned_pages;
struct kvm_hyp_memcache teardown_iommu_mc;
gpa_t pvmfw_load_addr;
bool enabled;
};
@@ -103,7 +103,7 @@ int reclaim_hyp_pool(struct hyp_pool *pool, struct kvm_hyp_memcache *host_mc,
int nr_pages);
void destroy_hyp_vm_pgt(struct pkvm_hyp_vm *vm);
void drain_hyp_pool(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc);
void drain_hyp_pool(struct hyp_pool *pool, struct kvm_hyp_memcache *mc);
int module_change_host_page_prot(u64 pfn, enum kvm_pgtable_prot prot, u64 nr_pages, bool update_iommu);
+1
View File
@@ -67,6 +67,7 @@ struct pkvm_hyp_vm {
/* pvIOMMUs attached. */
struct list_head pviommus;
struct hyp_pool iommu_pool;
/* Primary vCPU pending entry to the pvmfw */
struct pkvm_hyp_vcpu *pvmfw_entry_vcpu;
@@ -98,6 +98,11 @@ int pkvm_pviommu_add_vsid(struct kvm *host_kvm, int pviommu,
int pkvm_pviommu_finalise(struct pkvm_hyp_vm *hyp_vm)
{
int i;
int ret;
ret = hyp_pool_init_empty(&hyp_vm->iommu_pool, 64);
if (ret)
return ret;
hyp_spin_lock(&host_pviommu_lock);
INIT_LIST_HEAD(&hyp_vm->pviommus);
+2 -2
View File
@@ -2362,9 +2362,9 @@ void destroy_hyp_vm_pgt(struct pkvm_hyp_vm *vm)
guest_unlock_component(vm);
}
void drain_hyp_pool(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
void drain_hyp_pool(struct hyp_pool *pool, struct kvm_hyp_memcache *mc)
{
WARN_ON(reclaim_hyp_pool(&vm->pool, mc, INT_MAX) != -ENOMEM);
WARN_ON(reclaim_hyp_pool(pool, mc, INT_MAX) != -ENOMEM);
}
int __pkvm_host_reclaim_page(struct pkvm_hyp_vm *vm, u64 pfn, u64 ipa, u8 order)
+9 -2
View File
@@ -373,7 +373,7 @@ int __pkvm_reclaim_dying_guest_page(pkvm_handle_t handle, u64 pfn, u64 gfn, u8 o
if (ret)
goto unlock;
drain_hyp_pool(hyp_vm, &hyp_vm->host_kvm->arch.pkvm.stage2_teardown_mc);
drain_hyp_pool(&hyp_vm->pool, &hyp_vm->host_kvm->arch.pkvm.stage2_teardown_mc);
unlock:
hyp_read_unlock(&vm_table_lock);
@@ -1011,6 +1011,13 @@ int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
pkvm_pviommu_teardown(hyp_vm);
/*
* At this point all page tables are destroyed and should be pushed to the pool
* the only place that might still have memory is the mc, which would be drained
* from host as it hasn't been donated yet.
*/
drain_hyp_pool(&hyp_vm->iommu_pool, &host_kvm->arch.pkvm.teardown_iommu_mc);
/*
* At this point, the VM has been detached from the VM table and
* has a refcount of 0 so we're free to tear it down without
@@ -1019,7 +1026,7 @@ int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
mc = &host_kvm->arch.pkvm.stage2_teardown_mc;
destroy_hyp_vm_pgt(hyp_vm);
drain_hyp_pool(hyp_vm, mc);
drain_hyp_pool(&hyp_vm->pool, mc);
unpin_host_vcpus(hyp_vm->vcpus, hyp_vm->kvm.created_vcpus);
/* Push the metadata pages to the teardown memcache */
+2
View File
@@ -425,6 +425,8 @@ out_free:
&host_kvm->stat.protected_hyp_mem);
free_hyp_memcache(&host_kvm->arch.pkvm.stage2_teardown_mc);
kvm_iommu_guest_free_mc(&host_kvm->arch.pkvm.teardown_iommu_mc);
kvm_for_each_vcpu(idx, host_vcpu, host_kvm) {
struct kvm_hyp_req *hyp_reqs = host_vcpu->arch.hyp_reqs;