ANDROID: KVM: arm64: iommu: Host stage-2 idmap callbacks

Add IOMMU callbacks for host stage-2 idmap changes.
'host_stage2_idmap_prepare' is called first and is expected to apply
the changes on the driver level, eg. update driver-specific page table
information. If successful, the generic code invokes
'host_stage2_idmap_apply' on each currently powered IOMMU device
associated with the driver to apply the changes.
[@smostafa]
Port to new IOMMU layer.

Bug: 357781595
Bug: 384432312
Change-Id: Ifcc063896f6e8967c332dbaa5b7e7f2ba138abbf
Signed-off-by: David Brazdil <dbrazdil@google.com>
(cherry picked from commit 4395ddff4bc5ba21935e53861b86e7063447bf85)
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
David Brazdil
2022-02-14 22:30:37 +00:00
committed by Mostafa Saleh
parent e0abda8b77
commit a09f1819c5
3 changed files with 22 additions and 3 deletions
+4
View File
@@ -3,6 +3,7 @@
#define __ARM64_KVM_NVHE_IOMMU_H__
#include <asm/kvm_host.h>
#include <asm/kvm_pgtable.h>
#include <kvm/iommu.h>
@@ -32,6 +33,9 @@ void kvm_iommu_reclaim_pages(void *p, u8 order);
#define kvm_iommu_donate_page_nc() kvm_iommu_donate_pages(0, IOMMU_PAGE_NOCACHE)
#define kvm_iommu_reclaim_page(p) kvm_iommu_reclaim_pages(p, 0)
void kvm_iommu_host_stage2_idmap(phys_addr_t start, phys_addr_t end,
enum kvm_pgtable_prot prot);
struct kvm_iommu_ops {
int (*init)(void);
int (*alloc_domain)(struct kvm_hyp_iommu_domain *domain, int type);
+5
View File
@@ -432,3 +432,8 @@ int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu)
return pkvm_init_power_domain(&iommu->power_domain, &iommu_power_ops);
}
void kvm_iommu_host_stage2_idmap(phys_addr_t start, phys_addr_t end,
enum kvm_pgtable_prot prot)
{
}
+13 -3
View File
@@ -432,7 +432,7 @@ int host_stage2_unmap_reg_locked(phys_addr_t start, u64 size)
if (ret)
return ret;
/* XXX: unmap from IOMMU once available */
kvm_iommu_host_stage2_idmap(start, start + size, 0);
return 0;
}
@@ -551,8 +551,15 @@ static bool range_is_memory(u64 start, u64 end)
static inline int __host_stage2_idmap(u64 start, u64 end,
enum kvm_pgtable_prot prot)
{
return kvm_pgtable_stage2_map(&host_mmu.pgt, start, end - start, start,
prot, &host_s2_pool, 0);
int ret;
ret = kvm_pgtable_stage2_map(&host_mmu.pgt, start, end - start, start,
prot, &host_s2_pool, 0);
if (ret)
return ret;
kvm_iommu_host_stage2_idmap(start, end, prot);
return 0;
}
/*
@@ -664,6 +671,9 @@ static int __host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_i
else
__host_update_page_state(addr, size, PKVM_NOPAGE | nopage_state);
prot = owner_id == PKVM_ID_HOST ? PKVM_HOST_MEM_PROT : 0;
kvm_iommu_host_stage2_idmap(addr, addr + size, prot);
return 0;
}