From: Greg Kroah-Hartman Date: Wed, 7 Mar 2012 18:27:37 +0000 (-0800) Subject: 3.2-stable patches X-Git-Tag: v3.0.24~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae86335f34cc03280cbe4cb95669045085a3bd8a;p=thirdparty%2Fkernel%2Fstable-queue.git 3.2-stable patches added patches: ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch iwlwifi-fix-key-removal.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 --- diff --git a/queue-3.2/ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch b/queue-3.2/ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch new file mode 100644 index 00000000000..7c561afc329 --- /dev/null +++ b/queue-3.2/ath9k_hw-prevent-writes-to-const-data-on-ar9160.patch @@ -0,0 +1,113 @@ +From 9bbb8168ed3d8b946f9c1901a63a675012de88f2 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +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 + +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 +Reported-by: Magnus Määttä +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -805,27 +802,7 @@ static int ar5008_hw_process_ini(struct + if (ah->eep_ops->set_addac) + 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 +@@ -180,6 +180,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 +@@ -772,7 +772,6 @@ struct ath_hw { + u32 *analogBank6Data; + u32 *analogBank6TPCData; + u32 *analogBank7Data; +- u32 *addac5416_21; + u32 *bank6Temp; + + u8 txpower_limit; diff --git a/queue-3.2/iwlwifi-fix-key-removal.patch b/queue-3.2/iwlwifi-fix-key-removal.patch new file mode 100644 index 00000000000..8da943ea914 --- /dev/null +++ b/queue-3.2/iwlwifi-fix-key-removal.patch @@ -0,0 +1,56 @@ +From 5dcbf480473f6c3f06ad2426b7517038a2a18911 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 17 Feb 2012 09:47:14 -0800 +Subject: iwlwifi: fix key removal + +From: Johannes Berg + +commit 5dcbf480473f6c3f06ad2426b7517038a2a18911 upstream. + +When trying to remove a key, we always send key +flags just setting the key type, not including +the multicast flag and the key ID. As a result, +whenever any key was removed, the unicast key 0 +would be removed, causing a complete connection +loss after the second rekey (the first doesn't +cause a key removal). Fix the key removal code +to include the key ID and multicast flag, thus +removing the correct key. + +Reported-by: Alexander Schnaidt +Tested-by: Alexander Schnaidt +Signed-off-by: Johannes Berg +Signed-off-by: Wey-Yi Guy +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +@@ -1211,6 +1211,7 @@ int iwl_remove_dynamic_key(struct iwl_pr + unsigned long flags; + struct iwl_addsta_cmd sta_cmd; + u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); ++ __le16 key_flags; + + /* if station isn't there, neither is the key */ + if (sta_id == IWL_INVALID_STATION) +@@ -1236,7 +1237,14 @@ int iwl_remove_dynamic_key(struct iwl_pr + IWL_ERR(priv, "offset %d not used in uCode key table.\n", + keyconf->hw_key_idx); + +- sta_cmd.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; ++ key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); ++ key_flags |= STA_KEY_FLG_MAP_KEY_MSK | STA_KEY_FLG_NO_ENC | ++ STA_KEY_FLG_INVALID; ++ ++ if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) ++ key_flags |= STA_KEY_MULTICAST_MSK; ++ ++ sta_cmd.key.key_flags = key_flags; + sta_cmd.key.key_offset = WEP_INVALID_OFFSET; + sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; + sta_cmd.mode = STA_CONTROL_MODIFY_MSK; diff --git a/queue-3.2/kprobes-return-proper-error-code-from-register_kprobe.patch b/queue-3.2/kprobes-return-proper-error-code-from-register_kprobe.patch new file mode 100644 index 00000000000..d00c2129578 --- /dev/null +++ b/queue-3.2/kprobes-return-proper-error-code-from-register_kprobe.patch @@ -0,0 +1,76 @@ +From f986a499ef6f317d906e6f6f281be966e1237a10 Mon Sep 17 00:00:00 2001 +From: Prashanth Nageshappa +Date: Mon, 5 Mar 2012 14:59:12 -0800 +Subject: kprobes: return proper error code from register_kprobe() + +From: Prashanth Nageshappa + +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 +Signed-off-by: Prashanth K Nageshappa +Acked-by: Masami Hiramatsu +Cc: Jason Baron +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/kprobes.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1334,8 +1334,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; +@@ -1352,7 +1354,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 +@@ -1361,7 +1363,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; + } + /* ret will be updated by following code */ + } +@@ -1409,7 +1411,7 @@ out: + + return ret; + +-fail_with_jump_label: ++cannot_probe: + preempt_enable(); + jump_label_unlock(); + return ret; diff --git a/queue-3.2/mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch b/queue-3.2/mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch new file mode 100644 index 00000000000..378c8723fd0 --- /dev/null +++ b/queue-3.2/mac80211-zero-initialize-count-field-in-ieee80211_tx_rate.patch @@ -0,0 +1,39 @@ +From 8617b093d0031837a7be9b32bc674580cfb5f6b5 Mon Sep 17 00:00:00 2001 +From: Mohammed Shafi Shajakhan +Date: Mon, 20 Feb 2012 10:05:31 +0530 +Subject: mac80211: zero initialize count field in ieee80211_tx_rate + +From: Mohammed Shafi Shajakhan + +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 +Signed-off-by: Mohammed Shafi Shajakhan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/rate.c ++++ b/net/mac80211/rate.c +@@ -344,7 +344,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.2/mm-thp-fix-bug-on-mm-nr_ptes.patch b/queue-3.2/mm-thp-fix-bug-on-mm-nr_ptes.patch new file mode 100644 index 00000000000..1302d452766 --- /dev/null +++ b/queue-3.2/mm-thp-fix-bug-on-mm-nr_ptes.patch @@ -0,0 +1,97 @@ +From 1c641e84719429bbfe62a95ed3545ee7fe24408f Mon Sep 17 00:00:00 2001 +From: Andrea Arcangeli +Date: Mon, 5 Mar 2012 14:59:20 -0800 +Subject: mm: thp: fix BUG on mm->nr_ptes + +From: Andrea Arcangeli + +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 +Reported-by: Hugh Dickins +Signed-off-by: Andrea Arcangeli +Acked-by: Hugh Dickins +Cc: David Rientjes +Cc: Josh Boyer +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/huge_memory.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -642,6 +642,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); + } + +@@ -760,6 +761,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: +@@ -858,7 +860,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); +@@ -1017,6 +1018,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); +@@ -1356,7 +1358,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 +@@ -1969,7 +1970,6 @@ static void collapse_huge_page(struct mm + set_pmd_at(mm, address, pmd, _pmd); + update_mmu_cache(vma, address, _pmd); + prepare_pmd_huge_pte(pgtable, mm); +- mm->nr_ptes--; + spin_unlock(&mm->page_table_lock); + + #ifndef CONFIG_NUMA diff --git a/queue-3.2/series b/queue-3.2/series index d52b567dd70..50de1e82069 100644 --- a/queue-3.2/series +++ b/queue-3.2/series @@ -30,3 +30,8 @@ aio-wake-up-waiters-when-freeing-unused-kiocbs.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 +iwlwifi-fix-key-removal.patch