]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Sep 2013 23:08:45 +0000 (16:08 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Sep 2013 23:08:45 +0000 (16:08 -0700)
added patches:
intel-iommu-fix-leaks-in-pagetable-freeing.patch
media-v4l2-added-missing-mutex.h-include-to-v4l2-ctrls.h.patch
mips-ath79-fix-ar933x-watchdog-clock.patch

queue-3.4/intel-iommu-fix-leaks-in-pagetable-freeing.patch [new file with mode: 0644]
queue-3.4/media-v4l2-added-missing-mutex.h-include-to-v4l2-ctrls.h.patch [new file with mode: 0644]
queue-3.4/mips-ath79-fix-ar933x-watchdog-clock.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/intel-iommu-fix-leaks-in-pagetable-freeing.patch b/queue-3.4/intel-iommu-fix-leaks-in-pagetable-freeing.patch
new file mode 100644 (file)
index 0000000..f0ac069
--- /dev/null
@@ -0,0 +1,122 @@
+From 3269ee0bd6686baf86630300d528500ac5b516d7 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Sat, 15 Jun 2013 10:27:19 -0600
+Subject: intel-iommu: Fix leaks in pagetable freeing
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+commit 3269ee0bd6686baf86630300d528500ac5b516d7 upstream.
+
+At best the current code only seems to free the leaf pagetables and
+the root.  If you're unlucky enough to have a large gap (like any
+QEMU guest with more than 3G of memory), only the first chunk of leaf
+pagetables are freed (plus the root).  This is a massive memory leak.
+This patch re-writes the pagetable freeing function to use a
+recursive algorithm and manages to not only free all the pagetables,
+but does it without any apparent performance loss versus the current
+broken version.
+
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Joerg Roedel <joro@8bytes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c |   74 +++++++++++++++++++++-----------------------
+ 1 file changed, 36 insertions(+), 38 deletions(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -886,56 +886,54 @@ static int dma_pte_clear_range(struct dm
+       return order;
+ }
++static void dma_pte_free_level(struct dmar_domain *domain, int level,
++                             struct dma_pte *pte, unsigned long pfn,
++                             unsigned long start_pfn, unsigned long last_pfn)
++{
++      pfn = max(start_pfn, pfn);
++      pte = &pte[pfn_level_offset(pfn, level)];
++
++      do {
++              unsigned long level_pfn;
++              struct dma_pte *level_pte;
++
++              if (!dma_pte_present(pte) || dma_pte_superpage(pte))
++                      goto next;
++
++              level_pfn = pfn & level_mask(level - 1);
++              level_pte = phys_to_virt(dma_pte_addr(pte));
++
++              if (level > 2)
++                      dma_pte_free_level(domain, level - 1, level_pte,
++                                         level_pfn, start_pfn, last_pfn);
++
++              /* If range covers entire pagetable, free it */
++              if (!(start_pfn > level_pfn ||
++                    last_pfn < level_pfn + level_size(level))) {
++                      dma_clear_pte(pte);
++                      domain_flush_cache(domain, pte, sizeof(*pte));
++                      free_pgtable_page(level_pte);
++              }
++next:
++              pfn += level_size(level);
++      } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
++}
++
+ /* free page table pages. last level pte should already be cleared */
+ static void dma_pte_free_pagetable(struct dmar_domain *domain,
+                                  unsigned long start_pfn,
+                                  unsigned long last_pfn)
+ {
+       int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
+-      struct dma_pte *first_pte, *pte;
+-      int total = agaw_to_level(domain->agaw);
+-      int level;
+-      unsigned long tmp;
+-      int large_page = 2;
+       BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
+       BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
+       BUG_ON(start_pfn > last_pfn);
+       /* We don't need lock here; nobody else touches the iova range */
+-      level = 2;
+-      while (level <= total) {
+-              tmp = align_to_level(start_pfn, level);
+-
+-              /* If we can't even clear one PTE at this level, we're done */
+-              if (tmp + level_size(level) - 1 > last_pfn)
+-                      return;
+-
+-              do {
+-                      large_page = level;
+-                      first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page);
+-                      if (large_page > level)
+-                              level = large_page + 1;
+-                      if (!pte) {
+-                              tmp = align_to_level(tmp + 1, level + 1);
+-                              continue;
+-                      }
+-                      do {
+-                              if (dma_pte_present(pte)) {
+-                                      free_pgtable_page(phys_to_virt(dma_pte_addr(pte)));
+-                                      dma_clear_pte(pte);
+-                              }
+-                              pte++;
+-                              tmp += level_size(level);
+-                      } while (!first_pte_in_page(pte) &&
+-                               tmp + level_size(level) - 1 <= last_pfn);
+-
+-                      domain_flush_cache(domain, first_pte,
+-                                         (void *)pte - (void *)first_pte);
+-                      
+-              } while (tmp && tmp + level_size(level) - 1 <= last_pfn);
+-              level++;
+-      }
++      dma_pte_free_level(domain, agaw_to_level(domain->agaw),
++                         domain->pgd, 0, start_pfn, last_pfn);
++
+       /* free pgd */
+       if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
+               free_pgtable_page(domain->pgd);
diff --git a/queue-3.4/media-v4l2-added-missing-mutex.h-include-to-v4l2-ctrls.h.patch b/queue-3.4/media-v4l2-added-missing-mutex.h-include-to-v4l2-ctrls.h.patch
new file mode 100644 (file)
index 0000000..a4b45c0
--- /dev/null
@@ -0,0 +1,38 @@
+From a19dec6ea94c036af68c31930c1c92681f55af41 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Fri, 28 Jun 2013 05:44:22 -0300
+Subject: media: v4l2: added missing mutex.h include to v4l2-ctrls.h
+
+From: Andrzej Hajda <a.hajda@samsung.com>
+
+commit a19dec6ea94c036af68c31930c1c92681f55af41 upstream.
+
+This patch fixes following error:
+include/media/v4l2-ctrls.h:193:15: error: field ‘_lock’ has incomplete type
+include/media/v4l2-ctrls.h: In function ‘v4l2_ctrl_lock’:
+include/media/v4l2-ctrls.h:570:2: error: implicit declaration of
+       function ‘mutex_lock’ [-Werror=implicit-function-declaration]
+include/media/v4l2-ctrls.h: In function ‘v4l2_ctrl_unlock’:
+include/media/v4l2-ctrls.h:579:2: error: implicit declaration of
+       function ‘mutex_unlock’ [-Werror=implicit-function-declaration]
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/media/v4l2-ctrls.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/media/v4l2-ctrls.h
++++ b/include/media/v4l2-ctrls.h
+@@ -22,6 +22,7 @@
+ #define _V4L2_CTRLS_H
+ #include <linux/list.h>
++#include <linux/mutex.h>
+ #include <linux/videodev2.h>
+ /* forward references */
diff --git a/queue-3.4/mips-ath79-fix-ar933x-watchdog-clock.patch b/queue-3.4/mips-ath79-fix-ar933x-watchdog-clock.patch
new file mode 100644 (file)
index 0000000..67f2da6
--- /dev/null
@@ -0,0 +1,45 @@
+From a1191927ace7e6f827132aa9e062779eb3f11fa5 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Wed, 28 Aug 2013 10:41:42 +0200
+Subject: MIPS: ath79: Fix ar933x watchdog clock
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit a1191927ace7e6f827132aa9e062779eb3f11fa5 upstream.
+
+The watchdog device on the AR933x is connected to
+the AHB clock, however the current code uses the
+reference clock. Due to the wrong rate, the watchdog
+driver can't calculate correct register values for
+a given timeout value and the watchdog unexpectedly
+restarts the system.
+
+The code uses the wrong value since the initial
+commit 04225e1d227c8e68d685936ecf42ac175fec0e54
+(MIPS: ath79: add AR933X specific clock init)
+
+The patch fixes the code to use the correct clock
+rate to avoid the problem.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/5777/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/ath79/clock.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/ath79/clock.c
++++ b/arch/mips/ath79/clock.c
+@@ -159,7 +159,7 @@ static void __init ar933x_clocks_init(vo
+               ath79_ahb_clk.rate = freq / t;
+       }
+-      ath79_wdt_clk.rate = ath79_ref_clk.rate;
++      ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+       ath79_uart_clk.rate = ath79_ref_clk.rate;
+ }
index 5dbd78cb6d0c6ea50f8bf0952eb5d9e2c584089e..915232dddee61268f3f61f072d1e5c900faf5089 100644 (file)
@@ -26,3 +26,6 @@ hid-ntrig-validate-feature-report-details.patch
 hid-battery-don-t-do-dma-from-stack.patch
 hid-check-for-null-field-when-setting-values.patch
 hid-usbhid-quirk-for-n-trig-duosense-touch-screen.patch
+media-v4l2-added-missing-mutex.h-include-to-v4l2-ctrls.h.patch
+mips-ath79-fix-ar933x-watchdog-clock.patch
+intel-iommu-fix-leaks-in-pagetable-freeing.patch