[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] xen/arm: smmu: Set s2cr to type fault when the devices are deassigned



commit fc151829bac48f05a307bfd5ad450b3c0ae2a808
Author:     Rahul Singh <rahul.singh@xxxxxxx>
AuthorDate: Thu Aug 11 16:42:04 2022 +0100
Commit:     Julien Grall <jgrall@xxxxxxxxxx>
CommitDate: Wed Aug 24 09:46:59 2022 +0100

    xen/arm: smmu: Set s2cr to type fault when the devices are deassigned
    
    When devices are deassigned/assigned, SMMU global fault is observed
    because SMEs are freed in detach function and not allocated again when
    the device is assigned back to the guest.
    
    Don't free the SMEs when devices are deassigned, set the s2cr to type
    fault. This way the SMMU will generate a fault if a DMA access is done
    by a device not assigned to a guest.
    
    Remove the arm_smmu_master_free_smes() as this is not needed anymore,
    arm_smmu_write_s2cr() will be used to set the s2cr to type fault.
    
    Fixes: 0435784cc75d ("xen/arm: smmuv1: Intelligent SMR allocation")
    Signed-off-by: Rahul Singh <rahul.singh@xxxxxxx>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
    Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx>
---
 xen/drivers/passthrough/arm/smmu.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/xen/drivers/passthrough/arm/smmu.c 
b/xen/drivers/passthrough/arm/smmu.c
index 69511683b4..0a514821b3 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -1598,21 +1598,6 @@ out_err:
        return ret;
 }
 
-static void arm_smmu_master_free_smes(struct arm_smmu_master_cfg *cfg)
-{
-    struct arm_smmu_device *smmu = cfg->smmu;
-       int i, idx;
-       struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg);
-
-       spin_lock(&smmu->stream_map_lock);
-       for_each_cfg_sme(cfg, i, idx, fwspec->num_ids) {
-               if (arm_smmu_free_sme(smmu, idx))
-                       arm_smmu_write_sme(smmu, idx);
-               cfg->smendx[i] = INVALID_SMENDX;
-       }
-       spin_unlock(&smmu->stream_map_lock);
-}
-
 static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
                                      struct arm_smmu_master_cfg *cfg)
 {
@@ -1635,6 +1620,21 @@ static int arm_smmu_domain_add_master(struct 
arm_smmu_domain *smmu_domain,
        return 0;
 }
 
+static void arm_smmu_domain_remove_master(
+                               const struct arm_smmu_domain *smmu_domain,
+                               struct arm_smmu_master_cfg *cfg)
+{
+       uint32_t i, idx;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
+       struct arm_smmu_s2cr *s2cr = smmu->s2crs;
+       const struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg);
+
+       for_each_cfg_sme(cfg, i, idx, fwspec->num_ids) {
+               s2cr[idx] = s2cr_init_val;
+               arm_smmu_write_s2cr(smmu, idx);
+       }
+}
+
 static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
        int ret;
@@ -1684,10 +1684,11 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
 
 static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device 
*dev)
 {
+       struct arm_smmu_domain *smmu_domain = domain->priv;
        struct arm_smmu_master_cfg *cfg = find_smmu_master_cfg(dev);
 
        if (cfg)
-               arm_smmu_master_free_smes(cfg);
+               arm_smmu_domain_remove_master(smmu_domain, cfg);
 
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.