]> xenbits.xensource.com Git - xen.git/commitdiff
xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
authorJulien Grall <julien.grall@linaro.org>
Tue, 28 Apr 2015 14:32:33 +0000 (15:32 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 8 May 2015 14:41:59 +0000 (15:41 +0100)
Currently, when the device is deassigned from a domain, we directly reassign
to DOM0.

As the device may not have been correctly reset, this may lead to corruption or
expose some part of DOM0 memory. Also, we may have no way to reset some
platform devices.

If Xen reassigns the device to "nobody", it may receive some global/context
fault because the transaction has failed (indeed the context has been
marked invalid). Unfortunately there is no simple way to quiesce a buggy
hardware. I think we could live with that for a first version of platform
device passthrough.

DOM0 will have to issue an hypercall to assign the device to itself if it
wants to use it.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/drivers/passthrough/arm/smmu.c
xen/drivers/passthrough/device_tree.c

index 8a9b58b9786c578125e92e8f8846c4c834cbfbc4..65de50bebe4c4439379500c92425199546b3f5bd 100644 (file)
@@ -2692,7 +2692,7 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
        int ret = 0;
 
        /* Don't allow remapping on other domain than hwdom */
-       if (t != hardware_domain)
+       if (t && t != hardware_domain)
                return -EPERM;
 
        if (t == s)
@@ -2702,6 +2702,12 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
        if (ret)
                return ret;
 
+       if (t) {
+               ret = arm_smmu_assign_dev(t, devfn, dev);
+               if (ret)
+                       return ret;
+       }
+
        return 0;
 }
 
index 05ab2743059323dce16e4fa7761fdfaa8316b0c1..0ec4103c37fc8d05b26c70a2e34b68b6c1056c95 100644 (file)
@@ -80,15 +80,12 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
 
     spin_lock(&dtdevs_lock);
 
-    rc = hd->platform_ops->reassign_device(d, hardware_domain,
-                                           0, dt_to_dev(dev));
+    rc = hd->platform_ops->reassign_device(d, NULL, 0, dt_to_dev(dev));
     if ( rc )
         goto fail;
 
-    list_del(&dev->domain_list);
-
-    dt_device_set_used_by(dev, hardware_domain->domain_id);
-    list_add(&dev->domain_list, &domain_hvm_iommu(hardware_domain)->dt_devices);
+    list_del_init(&dev->domain_list);
+    dt_device_set_used_by(dev, DOMID_IO);
 
 fail:
     spin_unlock(&dtdevs_lock);