From: Greg Kroah-Hartman Date: Tue, 23 Jul 2013 17:06:49 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.10.3~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c2ac55c6932a52aaa93c77388e6ad43634cf91bd;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: iommu-amd-only-unmap-large-pages-from-the-first-pte.patch --- 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 index 00000000000..0ecbaff7591 --- /dev/null +++ b/queue-3.4/iommu-amd-only-unmap-large-pages-from-the-first-pte.patch @@ -0,0 +1,52 @@ +From 60d0ca3cfd199b6612bbbbf4999a3470dad38bb1 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Fri, 21 Jun 2013 14:33:19 -0600 +Subject: iommu/amd: Only unmap large pages from the first pte + +From: Alex Williamson + +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 +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-3.4/series b/queue-3.4/series index 77da3ca3b11..e4728ba9c7f 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -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