|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.3] VT-d/ATS: correct and clean up dev_invalidate_iotlb()
commit c3b1d10be6ebe4ff53d961c4507381f0aefb7f2a
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Mon Jul 28 15:02:25 2014 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Jul 28 15:02:25 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>
master commit: fd33987ba27607c3cc7da258cf1d86d21beeb735
master date: 2014-06-30 15:57:40 +0200
---
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#stable-4.3
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |