]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2013 17:06:49 +0000 (10:06 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2013 17:06:49 +0000 (10:06 -0700)
added patches:
iommu-amd-only-unmap-large-pages-from-the-first-pte.patch

queue-3.4/iommu-amd-only-unmap-large-pages-from-the-first-pte.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/iommu-amd-only-unmap-large-pages-from-the-first-pte.patch b/queue-3.4/iommu-amd-only-unmap-large-pages-from-the-first-pte.patch
new file mode 100644 (file)
index 0000000..0ecbaff
--- /dev/null
@@ -0,0 +1,52 @@
+From 60d0ca3cfd199b6612bbbbf4999a3470dad38bb1 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Fri, 21 Jun 2013 14:33:19 -0600
+Subject: iommu/amd: Only unmap large pages from the first pte
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+commit 60d0ca3cfd199b6612bbbbf4999a3470dad38bb1 upstream.
+
+If we use a large mapping, the expectation is that only unmaps from
+the first pte in the superpage are supported.  Unmaps from offsets
+into the superpage should fail (ie. return zero sized unmap).  In the
+current code, unmapping from an offset clears the size of the full
+mapping starting from an offset.  For instance, if we map a 16k
+physically contiguous range at IOVA 0x0 with a large page, then
+attempt to unmap 4k at offset 12k, 4 ptes are cleared (12k - 28k) and
+the unmap returns 16k unmapped.  This potentially incorrectly clears
+valid mappings and confuses drivers like VFIO that use the unmap size
+to release pinned pages.
+
+Fix by refusing to unmap from offsets into the page.
+
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Joerg Roedel <joro@8bytes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/amd_iommu.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/iommu/amd_iommu.c
++++ b/drivers/iommu/amd_iommu.c
+@@ -1309,6 +1309,10 @@ static unsigned long iommu_unmap_page(st
+                       /* Large PTE found which maps this address */
+                       unmap_size = PTE_PAGE_SIZE(*pte);
++
++                      /* Only unmap from the first pte in the page */
++                      if ((unmap_size - 1) & bus_addr)
++                              break;
+                       count      = PAGE_SIZE_PTE_COUNT(unmap_size);
+                       for (i = 0; i < count; i++)
+                               pte[i] = 0ULL;
+@@ -1318,7 +1322,7 @@ static unsigned long iommu_unmap_page(st
+               unmapped += unmap_size;
+       }
+-      BUG_ON(!is_power_of_2(unmapped));
++      BUG_ON(unmapped && !is_power_of_2(unmapped));
+       return unmapped;
+ }
index 77da3ca3b11ed9d0650de551a4b44190c1a0d71f..e4728ba9c7f434c9e223c3385b37c6ccd1ce8dae 100644 (file)
@@ -9,3 +9,4 @@ scsi-zfcp-fix-adapter-re-open-recovery-while-link-to-san-is-down.patch
 scsi-mpt2sas-fix-firmware-failure-with-wrong-task-attribute.patch
 tracing-use-current_uid-for-critical-time-tracing.patch
 sunrpc-pipefs-mount-notification-optimization-for-dying-clients.patch
+iommu-amd-only-unmap-large-pages-from-the-first-pte.patch