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:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user