pviommu: Add release_device and iova_to_phys
Add release_device and iova_to_phys pviommu functions.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
diff --git a/drivers/iommu/pkvm-pviommu.c b/drivers/iommu/pkvm-pviommu.c
index 3aeff60..76e8204b 100644
--- a/drivers/iommu/pkvm-pviommu.c
+++ b/drivers/iommu/pkvm-pviommu.c
@@ -74,6 +74,16 @@ static size_t pviommu_unmap_pages(struct iommu_domain *domain, unsigned long iov
static phys_addr_t pviommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
{
+ int ret;
+ struct pviommu_domain *pv_domain = container_of(domain, struct pviommu_domain, domain);
+ struct pviommu *pv = pv_domain->pv;
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_hvc(ARM_SMCCC_VENDOR_HYP_KVM_IOMMU_IOVA_TO_PHYS_FUNC_ID,
+ pv->id, pv_domain->id, iova, &res);
+ ret = res.a0;
+ if (ret < 0)
+ pr_err("iova_to_phys failed for %llx ret %d\n", iova, ret);
return 0;
}
@@ -145,6 +155,30 @@ static int pviommu_attach_dev(struct iommu_domain *domain, struct device *dev)
return 0;
}
+static void pviommu_detach_dev(struct pviommu_master *master)
+{
+ int ret = 0, i;
+ struct device *dev = master->dev;
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct pviommu *pv = master->iommu;
+ struct pviommu_domain *pv_domain = master->domain;
+ struct arm_smccc_res res;
+ u32 sid;
+
+ if (!fwspec)
+ return;
+
+ for (i = 0; i < fwspec->num_ids; i++) {
+ sid = fwspec->ids[i];
+ arm_smccc_1_1_hvc(ARM_SMCCC_VENDOR_HYP_KVM_IOMMU_DETACH_DEV_FUNC_ID,
+ pv->id, sid, 0, pv_domain->id, &res);
+ ret = res.a0;
+ if (ret)
+ dev_err(dev, "Failed to detach_dev with sid %d to IOMMU, err %d\n",
+ sid, ret);
+ }
+}
+
static struct iommu_domain *pviommu_domain_alloc(unsigned int type)
{
struct pviommu_domain *pv_domain;
@@ -201,6 +235,9 @@ static struct iommu_device *pviommu_probe_device(struct device *dev)
static void pviommu_release_device(struct device *dev)
{
+ struct pviommu_master *master = dev_iommu_priv_get(dev);
+
+ pviommu_detach_dev(master);
}
static int pviommu_of_xlate(struct device *dev, struct of_phandle_args *args)