]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 7 Mar 2012 18:31:02 +0000 (10:31 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 7 Mar 2012 18:31:02 +0000 (10:31 -0800)
added patches:
ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch
kprobes-return-proper-error-code-from-register_kprobe.patch
mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch
mm-thp-fix-bug-on-mm-nr_ptes.patch

queue-3.0/ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch [new file with mode: 0644]
queue-3.0/kprobes-return-proper-error-code-from-register_kprobe.patch [new file with mode: 0644]
queue-3.0/mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch [new file with mode: 0644]
queue-3.0/mm-thp-fix-bug-on-mm-nr_ptes.patch [new file with mode: 0644]
queue-3.0/series

diff --git a/queue-3.0/ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch b/queue-3.0/ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch
new file mode 100644 (file)
index 0000000..b77fda0
--- /dev/null
@@ -0,0 +1,113 @@
+From 9bbb8168ed3d8b946f9c1901a63a675012de88f2 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Wed, 15 Feb 2012 19:31:20 +0100
+Subject: ath9k_hw: prevent writes to const data on AR9160
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 9bbb8168ed3d8b946f9c1901a63a675012de88f2 upstream.
+
+Duplicate the data for iniAddac early on, to avoid having to do redundant
+memcpy calls later. While we're at it, make AR5416 < v2.2 use the same
+codepath. Fixes a reported crash on x86.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Reported-by: Magnus Määttä <magnus.maatta@logica.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ar5008_phy.c |   25 +------------------------
+ drivers/net/wireless/ath/ath9k/ar9002_hw.c  |   19 +++++++++++++++++++
+ drivers/net/wireless/ath/ath9k/hw.h         |    1 -
+ 3 files changed, 20 insertions(+), 25 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -489,8 +489,6 @@ static int ar5008_hw_rf_alloc_ext_banks(
+       ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
+-      ATH_ALLOC_BANK(ah->addac5416_21,
+-                     ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
+       ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
+       return 0;
+@@ -519,7 +517,6 @@ static void ar5008_hw_rf_free_ext_banks(
+       ATH_FREE_BANK(ah->analogBank6Data);
+       ATH_FREE_BANK(ah->analogBank6TPCData);
+       ATH_FREE_BANK(ah->analogBank7Data);
+-      ATH_FREE_BANK(ah->addac5416_21);
+       ATH_FREE_BANK(ah->bank6Temp);
+ #undef ATH_FREE_BANK
+@@ -799,27 +796,7 @@ static int ar5008_hw_process_ini(struct
+       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+       ah->eep_ops->set_addac(ah, chan);
+-      if (AR_SREV_5416_22_OR_LATER(ah)) {
+-              REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
+-      } else {
+-              struct ar5416IniArray temp;
+-              u32 addacSize =
+-                      sizeof(u32) * ah->iniAddac.ia_rows *
+-                      ah->iniAddac.ia_columns;
+-
+-              /* For AR5416 2.0/2.1 */
+-              memcpy(ah->addac5416_21,
+-                     ah->iniAddac.ia_array, addacSize);
+-
+-              /* override CLKDRV value at [row, column] = [31, 1] */
+-              (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
+-
+-              temp.ia_array = ah->addac5416_21;
+-              temp.ia_columns = ah->iniAddac.ia_columns;
+-              temp.ia_rows = ah->iniAddac.ia_rows;
+-              REG_WRITE_ARRAY(&temp, 1, regWrites);
+-      }
+-
++      REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
+       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+       ENABLE_REGWRITE_BUFFER(ah);
+--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+@@ -179,6 +179,25 @@ static void ar9002_hw_init_mode_regs(str
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
+                              ARRAY_SIZE(ar5416Addac), 2);
+       }
++
++      /* iniAddac needs to be modified for these chips */
++      if (AR_SREV_9160(ah) || !AR_SREV_5416_22_OR_LATER(ah)) {
++              struct ar5416IniArray *addac = &ah->iniAddac;
++              u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns;
++              u32 *data;
++
++              data = kmalloc(size, GFP_KERNEL);
++              if (!data)
++                      return;
++
++              memcpy(data, addac->ia_array, size);
++              addac->ia_array = data;
++
++              if (!AR_SREV_5416_22_OR_LATER(ah)) {
++                      /* override CLKDRV value */
++                      INI_RA(addac, 31,1) = 0;
++              }
++      }
+ }
+ /* Support for Japan ch.14 (2484) spread */
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -763,7 +763,6 @@ struct ath_hw {
+       u32 *analogBank6Data;
+       u32 *analogBank6TPCData;
+       u32 *analogBank7Data;
+-      u32 *addac5416_21;
+       u32 *bank6Temp;
+       u8 txpower_limit;
diff --git a/queue-3.0/kprobes-return-proper-error-code-from-register_kprobe.patch b/queue-3.0/kprobes-return-proper-error-code-from-register_kprobe.patch
new file mode 100644 (file)
index 0000000..cda8b54
--- /dev/null
@@ -0,0 +1,76 @@
+From f986a499ef6f317d906e6f6f281be966e1237a10 Mon Sep 17 00:00:00 2001
+From: Prashanth Nageshappa <prashanth@linux.vnet.ibm.com>
+Date: Mon, 5 Mar 2012 14:59:12 -0800
+Subject: kprobes: return proper error code from register_kprobe()
+
+From: Prashanth Nageshappa <prashanth@linux.vnet.ibm.com>
+
+commit f986a499ef6f317d906e6f6f281be966e1237a10 upstream.
+
+register_kprobe() aborts if the address of the new request falls in a
+prohibited area (such as ftrace pouch, __kprobes annotated functions,
+non-kernel text addresses, jump label text).  We however don't return the
+right error on this abort, resulting in a silent failure - incorrect
+adding/reporting of kprobes ('perf probe do_fork+18' or 'perf probe
+mcount' for instance).
+
+In V2 we are incorporating Masami Hiramatsu's  feedback.
+
+This patch fixes it by returning -EINVAL upon failure.
+
+While we are here, rename the label used for exit to be more appropriate.
+
+Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+Signed-off-by: Prashanth K Nageshappa <prashanth@linux.vnet.ibm.com>
+Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+Cc: Jason Baron <jbaron@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/kprobes.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1324,8 +1324,10 @@ int __kprobes register_kprobe(struct kpr
+       if (!kernel_text_address((unsigned long) p->addr) ||
+           in_kprobes_functions((unsigned long) p->addr) ||
+           ftrace_text_reserved(p->addr, p->addr) ||
+-          jump_label_text_reserved(p->addr, p->addr))
+-              goto fail_with_jump_label;
++          jump_label_text_reserved(p->addr, p->addr)) {
++              ret = -EINVAL;
++              goto cannot_probe;
++      }
+       /* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
+       p->flags &= KPROBE_FLAG_DISABLED;
+@@ -1340,7 +1342,7 @@ int __kprobes register_kprobe(struct kpr
+                * its code to prohibit unexpected unloading.
+                */
+               if (unlikely(!try_module_get(probed_mod)))
+-                      goto fail_with_jump_label;
++                      goto cannot_probe;
+               /*
+                * If the module freed .init.text, we couldn't insert
+@@ -1349,7 +1351,7 @@ int __kprobes register_kprobe(struct kpr
+               if (within_module_init((unsigned long)p->addr, probed_mod) &&
+                   probed_mod->state != MODULE_STATE_COMING) {
+                       module_put(probed_mod);
+-                      goto fail_with_jump_label;
++                      goto cannot_probe;
+               }
+       }
+       preempt_enable();
+@@ -1396,7 +1398,7 @@ out:
+       return ret;
+-fail_with_jump_label:
++cannot_probe:
+       preempt_enable();
+       jump_label_unlock();
+       return -EINVAL;
diff --git a/queue-3.0/mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch b/queue-3.0/mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch
new file mode 100644 (file)
index 0000000..4185715
--- /dev/null
@@ -0,0 +1,39 @@
+From 8617b093d0031837a7be9b32bc674580cfb5f6b5 Mon Sep 17 00:00:00 2001
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Date: Mon, 20 Feb 2012 10:05:31 +0530
+Subject: mac80211: zero initialize count field in ieee80211_tx_rate
+
+From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+
+commit 8617b093d0031837a7be9b32bc674580cfb5f6b5 upstream.
+
+rate control algorithms concludes the rate as invalid
+with rate[i].idx < -1 , while they do also check for rate[i].count is
+non-zero. it would be safer to zero initialize the 'count' field.
+recently we had a ath9k rate control crash where the ath9k rate control
+in ath_tx_status assumed to check only for rate[i].count being non-zero
+in one instance and ended up in using invalid rate index for
+'connection monitoring NULL func frames' which eventually lead to the crash.
+thanks to Pavel Roskin for fixing it and finding the root cause.
+https://bugzilla.redhat.com/show_bug.cgi?id=768639
+
+Cc: Pavel Roskin <proski@gnu.org>
+Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/rate.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac80211/rate.c
++++ b/net/mac80211/rate.c
+@@ -314,7 +314,7 @@ void rate_control_get_rate(struct ieee80
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               info->control.rates[i].idx = -1;
+               info->control.rates[i].flags = 0;
+-              info->control.rates[i].count = 1;
++              info->control.rates[i].count = 0;
+       }
+       if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
diff --git a/queue-3.0/mm-thp-fix-bug-on-mm-nr_ptes.patch b/queue-3.0/mm-thp-fix-bug-on-mm-nr_ptes.patch
new file mode 100644 (file)
index 0000000..840cc73
--- /dev/null
@@ -0,0 +1,97 @@
+From 1c641e84719429bbfe62a95ed3545ee7fe24408f Mon Sep 17 00:00:00 2001
+From: Andrea Arcangeli <aarcange@redhat.com>
+Date: Mon, 5 Mar 2012 14:59:20 -0800
+Subject: mm: thp: fix BUG on mm->nr_ptes
+
+From: Andrea Arcangeli <aarcange@redhat.com>
+
+commit 1c641e84719429bbfe62a95ed3545ee7fe24408f upstream.
+
+Dave Jones reports a few Fedora users hitting the BUG_ON(mm->nr_ptes...)
+in exit_mmap() recently.
+
+Quoting Hugh's discovery and explanation of the SMP race condition:
+
+  "mm->nr_ptes had unusual locking: down_read mmap_sem plus
+   page_table_lock when incrementing, down_write mmap_sem (or mm_users
+   0) when decrementing; whereas THP is careful to increment and
+   decrement it under page_table_lock.
+
+   Now most of those paths in THP also hold mmap_sem for read or write
+   (with appropriate checks on mm_users), but two do not: when
+   split_huge_page() is called by hwpoison_user_mappings(), and when
+   called by add_to_swap().
+
+   It's conceivable that the latter case is responsible for the
+   exit_mmap() BUG_ON mm->nr_ptes that has been reported on Fedora."
+
+The simplest way to fix it without having to alter the locking is to make
+split_huge_page() a noop in nr_ptes terms, so by counting the preallocated
+pagetables that exists for every mapped hugepage.  It was an arbitrary
+choice not to count them and either way is not wrong or right, because
+they are not used but they're still allocated.
+
+Reported-by: Dave Jones <davej@redhat.com>
+Reported-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Josh Boyer <jwboyer@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/huge_memory.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -641,6 +641,7 @@ static int __do_huge_pmd_anonymous_page(
+               set_pmd_at(mm, haddr, pmd, entry);
+               prepare_pmd_huge_pte(pgtable, mm);
+               add_mm_counter(mm, MM_ANONPAGES, HPAGE_PMD_NR);
++              mm->nr_ptes++;
+               spin_unlock(&mm->page_table_lock);
+       }
+@@ -759,6 +760,7 @@ int copy_huge_pmd(struct mm_struct *dst_
+       pmd = pmd_mkold(pmd_wrprotect(pmd));
+       set_pmd_at(dst_mm, addr, dst_pmd, pmd);
+       prepare_pmd_huge_pte(pgtable, dst_mm);
++      dst_mm->nr_ptes++;
+       ret = 0;
+ out_unlock:
+@@ -857,7 +859,6 @@ static int do_huge_pmd_wp_page_fallback(
+       }
+       kfree(pages);
+-      mm->nr_ptes++;
+       smp_wmb(); /* make pte visible before pmd */
+       pmd_populate(mm, pmd, pgtable);
+       page_remove_rmap(page);
+@@ -1016,6 +1017,7 @@ int zap_huge_pmd(struct mmu_gather *tlb,
+                       VM_BUG_ON(page_mapcount(page) < 0);
+                       add_mm_counter(tlb->mm, MM_ANONPAGES, -HPAGE_PMD_NR);
+                       VM_BUG_ON(!PageHead(page));
++                      tlb->mm->nr_ptes--;
+                       spin_unlock(&tlb->mm->page_table_lock);
+                       tlb_remove_page(tlb, page);
+                       pte_free(tlb->mm, pgtable);
+@@ -1310,7 +1312,6 @@ static int __split_huge_page_map(struct
+                       pte_unmap(pte);
+               }
+-              mm->nr_ptes++;
+               smp_wmb(); /* make pte visible before pmd */
+               /*
+                * Up to this point the pmd is present and huge and
+@@ -1925,7 +1926,6 @@ static void collapse_huge_page(struct mm
+       set_pmd_at(mm, address, pmd, _pmd);
+       update_mmu_cache(vma, address, entry);
+       prepare_pmd_huge_pte(pgtable, mm);
+-      mm->nr_ptes--;
+       spin_unlock(&mm->page_table_lock);
+ #ifndef CONFIG_NUMA
index 178e1dbc0a09b31db7f7d4b72bb5830daf378444..cd82196af411ac6d7e23c66104e69afe3b7a9b5c 100644 (file)
@@ -24,3 +24,7 @@ mmc-sdhci-esdhc-imx-fix-for-mmc-cards-on-i.mx5.patch
 mm-memcg-correct-unregistring-of-events-attached-to-the-same-eventfd.patch
 nommu-don-t-need-to-clear-vm_mm-when-deleting-a-vma.patch
 cifs-fix-dentry-refcount-leak-when-opening-a-fifo-on-lookup.patch
+mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch
+ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch
+kprobes-return-proper-error-code-from-register_kprobe.patch
+mm-thp-fix-bug-on-mm-nr_ptes.patch