[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 |