[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] VT-d/ATS: correct and clean up dev_invalidate_iotlb()
commit fd33987ba27607c3cc7da258cf1d86d21beeb735 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Mon Jun 30 15:57:40 2014 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Mon Jun 30 15:57:40 2014 +0200 VT-d/ATS: correct and clean up dev_invalidate_iotlb() While this was intended to only do cleanup (replace the two bogus "ret |= " constructs, and a simple formatting correction), this now also - fixes the bit manipulations for size_order > 0 a) correct an off-by-one in the use of size_order for shifting (till now double the requested size got invalidated) b) in fact setting bit 12 and up if necessary (without which too small a region might have got invalidated) c) making them capable of dealing with regions of 4Gb size and up - corrects the return value handling, such that a later iteration's success won't clear an earlier iteration's error indication - uses PCI_BDF2() instead of open coding it - bail immediately on bad passed in invalidation type, rather than repeatedly printing the same message for each ATS-capable device, at once also no longer hiding that failure from the caller Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Acked-by: Yang Zhang <yang.z.zhang@xxxxxxxxx> --- xen/drivers/passthrough/vtd/x86/ats.c | 33 ++++++++++++++++++++------------- 1 files changed, 20 insertions(+), 13 deletions(-) diff --git a/xen/drivers/passthrough/vtd/x86/ats.c b/xen/drivers/passthrough/vtd/x86/ats.c index ea57d7d..6b0632b 100644 --- a/xen/drivers/passthrough/vtd/x86/ats.c +++ b/xen/drivers/passthrough/vtd/x86/ats.c @@ -110,21 +110,23 @@ int dev_invalidate_iotlb(struct iommu *iommu, u16 did, u64 addr, unsigned int size_order, u64 type) { struct pci_ats_dev *pdev; - int sbit, ret = 0; - u16 sid; + int ret = 0; if ( !ecap_dev_iotlb(iommu->ecap) ) return ret; list_for_each_entry( pdev, &ats_devices, list ) { - sid = (pdev->bus << 8) | pdev->devfn; + u16 sid = PCI_BDF2(pdev->bus, pdev->devfn); + bool_t sbit; + int rc = 0; /* Only invalidate devices that belong to this IOMMU */ if ( pdev->iommu != iommu ) continue; - switch ( type ) { + switch ( type ) + { case DMA_TLB_DSI_FLUSH: if ( !device_in_domain(iommu, pdev, did) ) break; @@ -133,32 +135,37 @@ int dev_invalidate_iotlb(struct iommu *iommu, u16 did, /* invalidate all translations: sbit=1,bit_63=0,bit[62:12]=1 */ sbit = 1; addr = (~0 << PAGE_SHIFT_4K) & 0x7FFFFFFFFFFFFFFF; - ret |= qinval_device_iotlb(iommu, pdev->ats_queue_depth, - sid, sbit, addr); + rc = qinval_device_iotlb(iommu, pdev->ats_queue_depth, + sid, sbit, addr); break; case DMA_TLB_PSI_FLUSH: if ( !device_in_domain(iommu, pdev, did) ) break; - addr &= ~0 << (PAGE_SHIFT + size_order); - /* if size <= 4K, set sbit = 0, else set sbit = 1 */ sbit = size_order ? 1 : 0; /* clear lower bits */ - addr &= (~0 << (PAGE_SHIFT + size_order)); + addr &= ~0 << PAGE_SHIFT_4K; /* if sbit == 1, zero out size_order bit and set lower bits to 1 */ if ( sbit ) - addr &= (~0 & ~(1 << (PAGE_SHIFT + size_order))); + { + addr &= ~((u64)PAGE_SIZE_4K << (size_order - 1)); + addr |= (((u64)1 << (size_order - 1)) - 1) << PAGE_SHIFT_4K; + } - ret |= qinval_device_iotlb(iommu, pdev->ats_queue_depth, - sid, sbit, addr); + rc = qinval_device_iotlb(iommu, pdev->ats_queue_depth, + sid, sbit, addr); break; default: dprintk(XENLOG_WARNING VTDPREFIX, "invalid vt-d flush type\n"); - break; + return -EOPNOTSUPP; } + + if ( !ret ) + ret = rc; } + return ret; } -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |