ANDROID: KVM: arm64: iommu: Return map error code

The driver already returns the error code which is ignored by the
hypercall, so return the error code in X0.
And don't return -ENOMEM as that is communicated by requests.

Bug: 401132481
Change-Id: I9479028f3c49c11aa3071bc24222027c5b4c1a85
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Mostafa Saleh
2025-03-14 11:09:56 +00:00
parent 99ce28bfce
commit 97b35a4c10
4 changed files with 21 additions and 13 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
u32 endpoint_id, u32 pasid);
size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
unsigned long iova, phys_addr_t paddr, size_t pgsize,
size_t pgcount, int prot);
size_t pgcount, int prot, unsigned long *mapped);
size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
size_t pgsize, size_t pgcount);
phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova);
+5 -3
View File
@@ -1744,7 +1744,8 @@ static void handle___pkvm_host_iommu_detach_dev(struct kvm_cpu_context *host_ctx
static void handle___pkvm_host_iommu_map_pages(struct kvm_cpu_context *host_ctxt)
{
unsigned long ret;
int ret;
unsigned long mapped;
DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
DECLARE_REG(unsigned long, iova, host_ctxt, 2);
DECLARE_REG(phys_addr_t, paddr, host_ctxt, 3);
@@ -1753,8 +1754,9 @@ static void handle___pkvm_host_iommu_map_pages(struct kvm_cpu_context *host_ctxt
DECLARE_REG(unsigned int, prot, host_ctxt, 6);
ret = kvm_iommu_map_pages(domain, iova, paddr,
pgsize, pgcount, prot);
hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
pgsize, pgcount, prot, &mapped);
cpu_reg(host_ctxt, 0) = ret;
hyp_reqs_smccc_encode(mapped, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
}
static void handle___pkvm_host_iommu_unmap_pages(struct kvm_cpu_context *host_ctxt)
+12 -6
View File
@@ -464,29 +464,32 @@ out_unlock:
size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
unsigned long iova, phys_addr_t paddr, size_t pgsize,
size_t pgcount, int prot)
size_t pgcount, int prot, unsigned long *mapped)
{
size_t size;
int ret;
size_t total_mapped = 0;
struct kvm_hyp_iommu_domain *domain;
*mapped = 0;
if (prot & ~IOMMU_PROT_MASK)
return 0;
return -EOPNOTSUPP;
if (__builtin_mul_overflow(pgsize, pgcount, &size) ||
iova + size < iova || paddr + size < paddr)
return 0;
return -E2BIG;
domain = handle_to_domain(domain_id);
if (!domain || domain_get(domain))
return 0;
return -ENOENT;
ret = __pkvm_use_dma(paddr, size, __get_vcpu());
if (ret)
goto out_put_domain;
kvm_iommu_ops->map_pages(domain, iova, paddr, pgsize, pgcount, prot, &total_mapped);
ret = kvm_iommu_ops->map_pages(domain, iova, paddr, pgsize, pgcount,
prot, &total_mapped);
pgcount -= total_mapped / pgsize;
/*
@@ -497,9 +500,12 @@ size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
if (pgcount)
__pkvm_unuse_dma(paddr + total_mapped, pgcount * pgsize, __get_vcpu());
*mapped = total_mapped;
out_put_domain:
domain_put(domain);
return total_mapped;
/* Mask -ENOMEM, as it's passed as a request. */
return ret == -ENOMEM ? 0 : ret;
}
static inline void kvm_iommu_iotlb_sync(struct kvm_hyp_iommu_domain *domain,
+3 -3
View File
@@ -282,9 +282,9 @@ static bool pkvm_guest_iommu_map(struct pkvm_hyp_vcpu *hyp_vcpu, u64 *exit_code)
break;
}
mapped = kvm_iommu_map_pages(domain, iova, paddr,
PAGE_SIZE, min(size, kvm_granule_size(level)) / PAGE_SIZE,
__smccc_prot_linux(prot));
kvm_iommu_map_pages(domain, iova, paddr,
PAGE_SIZE, min(size, kvm_granule_size(level)) / PAGE_SIZE,
__smccc_prot_linux(prot), &mapped);
WARN_ON(__pkvm_unuse_dma(paddr, kvm_granule_size(level), hyp_vcpu));
if (!mapped) {
if (!__need_req(vcpu)) {