|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |