|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] VT-d/ATS: correct and clean up dev_invalidate_iotlb()
Jan Beulich wrote on 2014-06-24:
> 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>
Acked-by: Yang Zhang <yang.z.zhang@xxxxxxxxx>
> ---
> Note that despite not having ATS capable hardware and hence not being
> able to actually test the changes, I'm still certain changed the code
> gets closer to what the spec mandates than the original one.
>
> --- 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 *i
> 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 *i
> /* 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;
> }
>
Best regards,
Yang
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |