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

Re: [Xen-devel] [PATCH v3 2/2] VT-d: Fix vt-d flush timeout issue.



> On 15.12.15 at 9:44pm, <JBeulich@xxxxxxxx> wrote:
> >>> On 15.12.15 at 14:31, <quan.xu@xxxxxxxxx> wrote:
> > Copy from pci_hide_device(), which is actually add device to dom_xen
> > and add pdev->domain_list to dom_xen->arch.pdev_list.
> >
> > Quite similar, a second one only with proper justification, I can
> > reassign Device form _domain to dom_xen directly. The below is the how
> > to deal With device_tlb ( is it acceptable? ). It is working to hide device.
> 
> Looks reasonable, but ...
> 
> > +void device_tlb_invalidate_timeout(struct iommu *iommu, u16 did,
> > +                                   u16 seg, u8 bus, u8 devfn) {
> > +    struct domain *d;
> > +    struct pci_dev *pdev;
> > +    struct hvm_iommu *hd;
> > +    int rc;
> > +
> > +    d = rcu_lock_domain_by_id(iommu->domid_map[did]);
> > +    ASSERT(d);
> > +    for_each_pdev(d, pdev)
> > +        if ( (pdev->seg == seg) &&
> > +             (pdev->bus == bus) &&
> > +             (pdev->devfn == devfn) )
> > +        {
> > +            if ( pdev->domain )
> > +            {
> > +                hd = domain_hvm_iommu(d);
> > +                rc =  hd->platform_ops->reassign_device(d,
> > +                      dom_xen, devfn, pdev);
> 
> ... doesn't this have the potential of generating further flushes? You 
> clearly need
> to be certain not to recurse here.


Jan, The following code is for how to hide a device. I think it is feasible 
with proper justification.
Have a look first. Thanks.




--- a/xen/drivers/passthrough/vtd/qinval.c
+++ b/xen/drivers/passthrough/vtd/qinval.c
+void device_tlb_invalidate_timeout(struct iommu *iommu, u16 did,
+                                   u16 seg, u8 bus, u8 devfn)
+{
+    struct domain *d;
+    struct pci_dev *pdev;
+
+    d = rcu_lock_domain_by_id(iommu->domid_map[did]);
+    ASSERT(d);
+    for_each_pdev(d, pdev)
+        if ( (pdev->seg == seg) &&
+             (pdev->bus == bus) &&
+             (pdev->devfn == devfn) )
+        {
+            if ( iommu_hide_device(pdev) )
+            {
+                printk(XENLOG_ERR
+                       "IOMMU hide device %04x:%02x:%02x error.",
+                       seg, bus, devfn);
+                break;
+            }
+
+            break;
+        }
+
+    if ( !is_hardware_domain(d) )
+        domain_crash(d);
+    rcu_unlock_domain(d);
+}

--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
 int iommu_remove_device(struct pci_dev *pdev);
+int iommu_hide_device(struct pci_dev *pdev);


--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -1318,6 +1318,25 @@ int iommu_remove_device(struct pci_dev *pdev)
     return hd->platform_ops->remove_device(pdev->devfn, pci_to_dev(pdev));
 }

+int iommu_hide_device(struct pci_dev *pdev)
+{
+    if ( !pdev || !pdev->domain )
+        return -EINVAL;
+
+    spin_lock(&pcidevs_lock);
+    pdev->domain = dom_xen;
+    list_add(&pdev->domain_list, &dom_xen->arch.pdev_list);
+    spin_unlock(&pcidevs_lock);
+
+    return 0;
+}
+

--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1890,6 +1890,9 @@ static int intel_iommu_add_device(u8 devfn, struct 
pci_dev *pdev)
     if ( !pdev->domain )
         return -EINVAL;

+    if ( pdev->domain == dom_xen )
+        return -EACCES;
+
     ret = domain_context_mapping(pdev->domain, devfn, pdev);
     if ( ret )
     {
@@ -2301,6 +2304,9 @@ static int intel_iommu_assign_device(
     if ( list_empty(&acpi_drhd_units) )
         return -ENODEV;

+    if ( pdev->domain == dom_xen )
+        return -EACCES;
+
     seg = pdev->seg;
     bus = pdev->bus;




Quan

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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