From: Greg Kroah-Hartman Date: Thu, 3 Sep 2009 20:43:17 +0000 (-0700) Subject: start up a .30 queue X-Git-Tag: v2.6.27.32~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a2dbe0dfb8610383556c5d839ffa58b3366b7d1;p=thirdparty%2Fkernel%2Fstable-queue.git start up a .30 queue --- diff --git a/queue-2.6.30/alsa-hda-fix-macbookpro-3-1-4-1-quirk-with-alc889a.patch b/queue-2.6.30/alsa-hda-fix-macbookpro-3-1-4-1-quirk-with-alc889a.patch new file mode 100644 index 00000000000..1ab19fcb98e --- /dev/null +++ b/queue-2.6.30/alsa-hda-fix-macbookpro-3-1-4-1-quirk-with-alc889a.patch @@ -0,0 +1,102 @@ +From a3f730af7e33cea10ea66f05b2565fde1f9512df Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 31 Aug 2009 08:15:26 +0200 +Subject: ALSA: hda - Fix MacBookPro 3,1/4,1 quirk with ALC889A + +From: Takashi Iwai + +commit a3f730af7e33cea10ea66f05b2565fde1f9512df upstream. + +This patch fixes the wrong headphone output routing for MacBookPro 3,1/4,1 +quirk with ALC889A codec, which caused the silent headphone output. +Also, this gives the individual Headphone and Speaker volume controls. + +Reference: kernel bug#14078 + http://bugzilla.kernel.org/show_bug.cgi?id=14078 + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 34 ++++++++++++++++++++-------------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6186,9 +6186,9 @@ static struct hda_verb alc885_mbp_ch2_in + }; + + /* +- * 6ch mode ++ * 4ch mode + */ +-static struct hda_verb alc885_mbp_ch6_init[] = { ++static struct hda_verb alc885_mbp_ch4_init[] = { + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, +@@ -6197,9 +6197,9 @@ static struct hda_verb alc885_mbp_ch6_in + { } /* end */ + }; + +-static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { ++static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { + { 2, alc885_mbp_ch2_init }, +- { 6, alc885_mbp_ch6_init }, ++ { 4, alc885_mbp_ch4_init }, + }; + + +@@ -6232,10 +6232,11 @@ static struct snd_kcontrol_new alc882_ba + }; + + static struct snd_kcontrol_new alc885_mbp3_mixer[] = { +- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), +- HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), +- HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), +- HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT), ++ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), ++ HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), ++ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), ++ HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), ++ HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), +@@ -6481,14 +6482,18 @@ static struct hda_verb alc885_mbp3_init_ + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, ++ /* HP mixer */ ++ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, ++ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, ++ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + /* Front Pin: output 0 (0x0c) */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, +- /* HP Pin: output 0 (0x0d) */ ++ /* HP Pin: output 0 (0x0e) */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, +- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, +- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, ++ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, ++ {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + /* Mic (rear) pin: input vref at 80% */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, +@@ -6885,10 +6890,11 @@ static struct alc_config_preset alc882_p + .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, + .init_verbs = { alc885_mbp3_init_verbs, + alc880_gpio1_init_verbs }, +- .num_dacs = ARRAY_SIZE(alc882_dac_nids), ++ .num_dacs = 2, + .dac_nids = alc882_dac_nids, +- .channel_mode = alc885_mbp_6ch_modes, +- .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), ++ .hp_nid = 0x04, ++ .channel_mode = alc885_mbp_4ch_modes, ++ .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), + .input_mux = &alc882_capture_source, + .dig_out_nid = ALC882_DIGOUT_NID, + .dig_in_nid = ALC882_DIGIN_NID, diff --git a/queue-2.6.30/clone-fix-race-between-copy_process-and-de_thread.patch b/queue-2.6.30/clone-fix-race-between-copy_process-and-de_thread.patch new file mode 100644 index 00000000000..3cf67f49f9c --- /dev/null +++ b/queue-2.6.30/clone-fix-race-between-copy_process-and-de_thread.patch @@ -0,0 +1,145 @@ +From 4ab6c08336535f8c8e42cf45d7adeda882eff06e Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Wed, 26 Aug 2009 14:29:24 -0700 +Subject: clone(): fix race between copy_process() and de_thread() + +From: Oleg Nesterov + +commit 4ab6c08336535f8c8e42cf45d7adeda882eff06e upstream. + +Spotted by Hiroshi Shimamoto who also provided the test-case below. + +copy_process() uses signal->count as a reference counter, but it is not. +This test case + + #include + #include + #include + #include + #include + #include + + void *null_thread(void *p) + { + for (;;) + sleep(1); + + return NULL; + } + + void *exec_thread(void *p) + { + execl("/bin/true", "/bin/true", NULL); + + return null_thread(p); + } + + int main(int argc, char **argv) + { + for (;;) { + pid_t pid; + int ret, status; + + pid = fork(); + if (pid < 0) + break; + + if (!pid) { + pthread_t tid; + + pthread_create(&tid, NULL, exec_thread, NULL); + for (;;) + pthread_create(&tid, NULL, null_thread, NULL); + } + + do { + ret = waitpid(pid, &status, 0); + } while (ret == -1 && errno == EINTR); + } + + return 0; + } + +quickly creates an unkillable task. + +If copy_process(CLONE_THREAD) races with de_thread() +copy_signal()->atomic(signal->count) breaks the signal->notify_count +logic, and the execing thread can hang forever in kernel space. + +Change copy_process() to increment count/live only when we know for sure +we can't fail. In this case the forked thread will take care of its +reference to signal correctly. + +If copy_process() fails, check CLONE_THREAD flag. If it it set - do +nothing, the counters were not changed and current belongs to the same +thread group. If it is not set, ->signal must be released in any case +(and ->count must be == 1), the forked child is the only thread in the +thread group. + +We need more cleanups here, in particular signal->count should not be used +by de_thread/__exit_signal at all. This patch only fixes the bug. + +Reported-by: Hiroshi Shimamoto +Tested-by: Hiroshi Shimamoto +Signed-off-by: Oleg Nesterov +Acked-by: Roland McGrath +Cc: KAMEZAWA Hiroyuki +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/fork.c | 20 +++++--------------- + 1 file changed, 5 insertions(+), 15 deletions(-) + +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -816,11 +816,8 @@ static int copy_signal(unsigned long clo + { + struct signal_struct *sig; + +- if (clone_flags & CLONE_THREAD) { +- atomic_inc(¤t->signal->count); +- atomic_inc(¤t->signal->live); ++ if (clone_flags & CLONE_THREAD) + return 0; +- } + + sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); + tsk->signal = sig; +@@ -878,16 +875,6 @@ void __cleanup_signal(struct signal_stru + kmem_cache_free(signal_cachep, sig); + } + +-static void cleanup_signal(struct task_struct *tsk) +-{ +- struct signal_struct *sig = tsk->signal; +- +- atomic_dec(&sig->live); +- +- if (atomic_dec_and_test(&sig->count)) +- __cleanup_signal(sig); +-} +- + static void copy_flags(unsigned long clone_flags, struct task_struct *p) + { + unsigned long new_flags = p->flags; +@@ -1237,6 +1224,8 @@ static struct task_struct *copy_process( + } + + if (clone_flags & CLONE_THREAD) { ++ atomic_inc(¤t->signal->count); ++ atomic_inc(¤t->signal->live); + p->group_leader = current->group_leader; + list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); + } +@@ -1281,7 +1270,8 @@ bad_fork_cleanup_mm: + if (p->mm) + mmput(p->mm); + bad_fork_cleanup_signal: +- cleanup_signal(p); ++ if (!(clone_flags & CLONE_THREAD)) ++ __cleanup_signal(p->signal); + bad_fork_cleanup_sighand: + __cleanup_sighand(p->sighand); + bad_fork_cleanup_fs: diff --git a/queue-2.6.30/ehea-fix-napi-list-corruption-on-ifconfig-down.patch b/queue-2.6.30/ehea-fix-napi-list-corruption-on-ifconfig-down.patch new file mode 100644 index 00000000000..9c2c3d0c9cd --- /dev/null +++ b/queue-2.6.30/ehea-fix-napi-list-corruption-on-ifconfig-down.patch @@ -0,0 +1,44 @@ +From 357eb46d8f275b4e8484541234ea3ba06065e258 Mon Sep 17 00:00:00 2001 +From: Hannes Hering +Date: Tue, 4 Aug 2009 11:48:39 -0700 +Subject: ehea: Fix napi list corruption on ifconfig down + +From: Hannes Hering + +commit 357eb46d8f275b4e8484541234ea3ba06065e258 upstream. + +This patch fixes the napi list handling when an ehea interface is shut +down to avoid corruption of the napi list. + +Signed-off-by: Hannes Hering +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ehea/ehea.h | 2 +- + drivers/net/ehea/ehea_main.c | 3 +++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ehea/ehea.h ++++ b/drivers/net/ehea/ehea.h +@@ -40,7 +40,7 @@ + #include + + #define DRV_NAME "ehea" +-#define DRV_VERSION "EHEA_0101" ++#define DRV_VERSION "EHEA_0102" + + /* eHEA capability flags */ + #define DLPAR_PORT_ADD_REM 1 +--- a/drivers/net/ehea/ehea_main.c ++++ b/drivers/net/ehea/ehea_main.c +@@ -1545,6 +1545,9 @@ static int ehea_clean_portres(struct ehe + { + int ret, i; + ++ if (pr->qp) ++ netif_napi_del(&pr->napi); ++ + ret = ehea_destroy_qp(pr->qp); + + if (!ret) { diff --git a/queue-2.6.30/ima-hashing-large-files-bug-fix.patch b/queue-2.6.30/ima-hashing-large-files-bug-fix.patch new file mode 100644 index 00000000000..360b2f4cf12 --- /dev/null +++ b/queue-2.6.30/ima-hashing-large-files-bug-fix.patch @@ -0,0 +1,45 @@ +From 16bfa38b1936212428cb38fbfbbb8f6c62b8d81f Mon Sep 17 00:00:00 2001 +From: Mimi Zohar +Date: Fri, 21 Aug 2009 14:32:49 -0400 +Subject: ima: hashing large files bug fix + +From: Mimi Zohar + +commit 16bfa38b1936212428cb38fbfbbb8f6c62b8d81f upstream. + +Hashing files larger than INT_MAX causes process to loop. +Dependent on redefining kernel_read() offset type to loff_t. + +(http://bugzilla.kernel.org/show_bug.cgi?id=13909) + +Signed-off-by: Mimi Zohar +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/integrity/ima/ima_crypto.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/security/integrity/ima/ima_crypto.c ++++ b/security/integrity/ima/ima_crypto.c +@@ -45,9 +45,9 @@ int ima_calc_hash(struct file *file, cha + { + struct hash_desc desc; + struct scatterlist sg[1]; +- loff_t i_size; ++ loff_t i_size, offset = 0; + char *rbuf; +- int rc, offset = 0; ++ int rc; + + rc = init_desc(&desc); + if (rc != 0) +@@ -67,6 +67,8 @@ int ima_calc_hash(struct file *file, cha + rc = rbuf_len; + break; + } ++ if (rbuf_len == 0) ++ break; + offset += rbuf_len; + sg_init_one(sg, rbuf, rbuf_len); + diff --git a/queue-2.6.30/kernel_read-redefine-offset-type.patch b/queue-2.6.30/kernel_read-redefine-offset-type.patch new file mode 100644 index 00000000000..b0666e591d6 --- /dev/null +++ b/queue-2.6.30/kernel_read-redefine-offset-type.patch @@ -0,0 +1,46 @@ +From 6777d773a463ac045d333b989d4e44660f8d92ad Mon Sep 17 00:00:00 2001 +From: Mimi Zohar +Date: Fri, 21 Aug 2009 14:32:48 -0400 +Subject: kernel_read: redefine offset type + +From: Mimi Zohar + +commit 6777d773a463ac045d333b989d4e44660f8d92ad upstream. + +vfs_read() offset is defined as loff_t, but kernel_read() +offset is only defined as unsigned long. Redefine +kernel_read() offset as loff_t. + +Signed-off-by: Mimi Zohar +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exec.c | 4 ++-- + include/linux/fs.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -677,8 +677,8 @@ exit: + } + EXPORT_SYMBOL(open_exec); + +-int kernel_read(struct file *file, unsigned long offset, +- char *addr, unsigned long count) ++int kernel_read(struct file *file, loff_t offset, ++ char *addr, unsigned long count) + { + mm_segment_t old_fs; + loff_t pos = offset; +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -2121,7 +2121,7 @@ extern struct file *do_filp_open(int dfd + int open_flag, int mode, int acc_mode); + extern int may_open(struct path *, int, int); + +-extern int kernel_read(struct file *, unsigned long, char *, unsigned long); ++extern int kernel_read(struct file *, loff_t, char *, unsigned long); + extern struct file * open_exec(const char *); + + /* fs/dcache.c -- generic fs support functions */ diff --git a/queue-2.6.30/mac80211-fix-panic-when-splicing-unprepared-tids.patch b/queue-2.6.30/mac80211-fix-panic-when-splicing-unprepared-tids.patch new file mode 100644 index 00000000000..a9b1977dff4 --- /dev/null +++ b/queue-2.6.30/mac80211-fix-panic-when-splicing-unprepared-tids.patch @@ -0,0 +1,94 @@ +From 416fbdff2137e8d8cc8f23f517bee3a26b11526f Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Tue, 11 Aug 2009 13:10:33 -0700 +Subject: mac80211: fix panic when splicing unprepared TIDs + +From: Luis R. Rodriguez + +commit 416fbdff2137e8d8cc8f23f517bee3a26b11526f upstream. + +We splice skbs from the pending queue for a TID +onto the local pending queue when tearing down a +block ack request. This is not necessary unless we +actually have received a request to start a block ack +request (rate control, for example). If we never received +that request we should not be splicing the tid pending +queue as it would be null, causing a panic. + +Not sure yet how exactly we allowed through a call when the +tid state does not have at least HT_ADDBA_REQUESTED_MSK set, +that will require some further review as it is not quite +obvious. + +For more information see the bug report: + +http://bugzilla.kernel.org/show_bug.cgi?id=13922 + +This fixes this oops: + +BUG: unable to handle kernel NULL pointer dereference at 00000030 +IP: [] ieee80211_agg_splice_packets+0x40/0xc0 [mac80211] +*pdpt = 0000000002d1e001 *pde = 0000000000000000 +Thread overran stack, or stack corrupted +Oops: 0000 [#1] SMP +last sysfs file: /sys/module/aes_generic/initstate +Modules linked in: + +Pid: 0, comm: swapper Not tainted (2.6.31-rc5-wl #2) Dell DV051 +EIP: 0060:[] EFLAGS: 00010292 CPU: 0 +EIP is at ieee80211_agg_splice_packets+0x40/0xc0 [mac80211] +EAX: 00000030 EBX: 0000004c ECX: 00000003 EDX: 00000000 +ESI: c1c98000 EDI: f745a1c0 EBP: c076be58 ESP: c076be38 + DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 +Process swapper (pid: 0, ti=c076a000 task=c0709160 task.ti=c076a000) +Stack: +Call Trace: + [] ? ieee80211_stop_tx_ba_cb+0xab/0x150 [mac80211] + [] ? ieee80211_tasklet_handler+0xce/0x110 [mac80211] + [] ? net_rx_action+0xef/0x1d0 + [] ? tasklet_action+0x58/0xc0 + [] ? __do_softirq+0xc2/0x190 + [] ? handle_IRQ_event+0x58/0x140 + [] ? ack_apic_level+0x7e/0x270 + [] ? do_softirq+0x3d/0x40 + [] ? irq_exit+0x65/0x90 + [] ? do_IRQ+0x4f/0xc0 + [] ? irq_exit+0x7d/0x90 + [] ? smp_apic_timer_interrupt+0x57/0x90 + [] ? common_interrupt+0x29/0x30 + [] ? mwait_idle+0xbe/0x100 + [] ? cpu_idle+0x52/0x90 + [] ? rest_init+0x55/0x60 + [] ? start_kernel+0x315/0x37d + [] ? unknown_bootoption+0x0/0x1f9 + [] ? i386_start_kernel+0x79/0x81 +Code: +EIP: [] ieee80211_agg_splice_packets+0x40/0xc0 [mac80211] SS:ESP 0068:c076be38 +CR2: 0000000000000030 + +Testedy-by: Jack Lau +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/agg-tx.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -376,6 +376,14 @@ static void ieee80211_agg_splice_packets + &local->hw, queue, + IEEE80211_QUEUE_STOP_REASON_AGGREGATION); + ++ if (!(sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK)) ++ return; ++ ++ if (WARN(!sta->ampdu_mlme.tid_tx[tid], ++ "TID %d gone but expected when splicing aggregates from" ++ "the pending queue\n", tid)) ++ return; ++ + if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) { + spin_lock_irqsave(&local->queue_stop_reason_lock, flags); + /* mark queue as pending, it is stopped already */ diff --git a/queue-2.6.30/make-bitmask-and-operators-return-a-result-code.patch b/queue-2.6.30/make-bitmask-and-operators-return-a-result-code.patch new file mode 100644 index 00000000000..f9f50091a9e --- /dev/null +++ b/queue-2.6.30/make-bitmask-and-operators-return-a-result-code.patch @@ -0,0 +1,187 @@ +From f4b0373b26567cafd421d91101852ed7a34e9e94 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 21 Aug 2009 09:26:15 -0700 +Subject: Make bitmask 'and' operators return a result code + +From: Linus Torvalds + +commit f4b0373b26567cafd421d91101852ed7a34e9e94 upstream. + +When 'and'ing two bitmasks (where 'andnot' is a variation on it), some +cases want to know whether the result is the empty set or not. In +particular, the TLB IPI sending code wants to do cpumask operations and +determine if there are any CPU's left in the final set. + +So this just makes the bitmask (and cpumask) functions return a boolean +for whether the result has any bits set. + +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/bitmap.h | 18 ++++++++---------- + include/linux/cpumask.h | 20 ++++++++++---------- + lib/bitmap.c | 12 ++++++++---- + 3 files changed, 26 insertions(+), 24 deletions(-) + +--- a/include/linux/bitmap.h ++++ b/include/linux/bitmap.h +@@ -94,13 +94,13 @@ extern void __bitmap_shift_right(unsigne + const unsigned long *src, int shift, int bits); + extern void __bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int shift, int bits); +-extern void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, ++extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); + extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); + extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +-extern void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, ++extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); + extern int __bitmap_intersects(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +@@ -171,13 +171,12 @@ static inline void bitmap_copy(unsigned + } + } + +-static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, ++static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) + { + if (small_const_nbits(nbits)) +- *dst = *src1 & *src2; +- else +- __bitmap_and(dst, src1, src2, nbits); ++ return (*dst = *src1 & *src2) != 0; ++ return __bitmap_and(dst, src1, src2, nbits); + } + + static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, +@@ -198,13 +197,12 @@ static inline void bitmap_xor(unsigned l + __bitmap_xor(dst, src1, src2, nbits); + } + +-static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1, ++static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) + { + if (small_const_nbits(nbits)) +- *dst = *src1 & ~(*src2); +- else +- __bitmap_andnot(dst, src1, src2, nbits); ++ return (*dst = *src1 & ~(*src2)) != 0; ++ return __bitmap_andnot(dst, src1, src2, nbits); + } + + static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, +--- a/include/linux/cpumask.h ++++ b/include/linux/cpumask.h +@@ -43,10 +43,10 @@ + * int cpu_isset(cpu, mask) true iff bit 'cpu' set in mask + * int cpu_test_and_set(cpu, mask) test and set bit 'cpu' in mask + * +- * void cpus_and(dst, src1, src2) dst = src1 & src2 [intersection] ++ * int cpus_and(dst, src1, src2) dst = src1 & src2 [intersection] + * void cpus_or(dst, src1, src2) dst = src1 | src2 [union] + * void cpus_xor(dst, src1, src2) dst = src1 ^ src2 +- * void cpus_andnot(dst, src1, src2) dst = src1 & ~src2 ++ * int cpus_andnot(dst, src1, src2) dst = src1 & ~src2 + * void cpus_complement(dst, src) dst = ~src + * + * int cpus_equal(mask1, mask2) Does mask1 == mask2? +@@ -179,10 +179,10 @@ static inline int __cpu_test_and_set(int + } + + #define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS) +-static inline void __cpus_and(cpumask_t *dstp, const cpumask_t *src1p, ++static inline int __cpus_and(cpumask_t *dstp, const cpumask_t *src1p, + const cpumask_t *src2p, int nbits) + { +- bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits); ++ return bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits); + } + + #define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS) +@@ -201,10 +201,10 @@ static inline void __cpus_xor(cpumask_t + + #define cpus_andnot(dst, src1, src2) \ + __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS) +-static inline void __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p, ++static inline int __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p, + const cpumask_t *src2p, int nbits) + { +- bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits); ++ return bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits); + } + + #define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS) +@@ -738,11 +738,11 @@ static inline void cpumask_clear(struct + * @src1p: the first input + * @src2p: the second input + */ +-static inline void cpumask_and(struct cpumask *dstp, ++static inline int cpumask_and(struct cpumask *dstp, + const struct cpumask *src1p, + const struct cpumask *src2p) + { +- bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p), ++ return bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p), + cpumask_bits(src2p), nr_cpumask_bits); + } + +@@ -779,11 +779,11 @@ static inline void cpumask_xor(struct cp + * @src1p: the first input + * @src2p: the second input + */ +-static inline void cpumask_andnot(struct cpumask *dstp, ++static inline int cpumask_andnot(struct cpumask *dstp, + const struct cpumask *src1p, + const struct cpumask *src2p) + { +- bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p), ++ return bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p), + cpumask_bits(src2p), nr_cpumask_bits); + } + +--- a/lib/bitmap.c ++++ b/lib/bitmap.c +@@ -179,14 +179,16 @@ void __bitmap_shift_left(unsigned long * + } + EXPORT_SYMBOL(__bitmap_shift_left); + +-void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, ++int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) + { + int k; + int nr = BITS_TO_LONGS(bits); ++ unsigned long result = 0; + + for (k = 0; k < nr; k++) +- dst[k] = bitmap1[k] & bitmap2[k]; ++ result |= (dst[k] = bitmap1[k] & bitmap2[k]); ++ return result != 0; + } + EXPORT_SYMBOL(__bitmap_and); + +@@ -212,14 +214,16 @@ void __bitmap_xor(unsigned long *dst, co + } + EXPORT_SYMBOL(__bitmap_xor); + +-void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, ++int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) + { + int k; + int nr = BITS_TO_LONGS(bits); ++ unsigned long result = 0; + + for (k = 0; k < nr; k++) +- dst[k] = bitmap1[k] & ~bitmap2[k]; ++ result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); ++ return result != 0; + } + EXPORT_SYMBOL(__bitmap_andnot); + diff --git a/queue-2.6.30/mm-build_zonelists-move-clear-node_load-to-__build_all_zonelists.patch b/queue-2.6.30/mm-build_zonelists-move-clear-node_load-to-__build_all_zonelists.patch new file mode 100644 index 00000000000..a9d545975e7 --- /dev/null +++ b/queue-2.6.30/mm-build_zonelists-move-clear-node_load-to-__build_all_zonelists.patch @@ -0,0 +1,65 @@ +From 7f9cfb31030737a7fc9a1cbca3fd01bec184c849 Mon Sep 17 00:00:00 2001 +From: Bo Liu +Date: Tue, 18 Aug 2009 14:11:19 -0700 +Subject: mm: build_zonelists(): move clear node_load[] to __build_all_zonelists() + +From: Bo Liu + +commit 7f9cfb31030737a7fc9a1cbca3fd01bec184c849 upstream. + +If node_load[] is cleared everytime build_zonelists() is +called,node_load[] will have no help to find the next node that should +appear in the given node's fallback list. + +Because of the bug, zonelist's node_order is not calculated as expected. +This bug affects on big machine, which has asynmetric node distance. + +[synmetric NUMA's node distance] + 0 1 2 +0 10 12 12 +1 12 10 12 +2 12 12 10 + +[asynmetric NUMA's node distance] + 0 1 2 +0 10 12 20 +1 12 10 14 +2 20 14 10 + +This (my bug) is very old but no one has reported this for a long time. +Maybe because the number of asynmetric NUMA is very small and they use +cpuset for customizing node memory allocation fallback. + +[akpm@linux-foundation.org: fix CONFIG_NUMA=n build] +Signed-off-by: Bo Liu +Reviewed-by: KAMEZAWA Hiroyuki +Cc: Mel Gorman +Cc: Christoph Lameter +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/page_alloc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -2342,7 +2342,6 @@ static void build_zonelists(pg_data_t *p + prev_node = local_node; + nodes_clear(used_mask); + +- memset(node_load, 0, sizeof(node_load)); + memset(node_order, 0, sizeof(node_order)); + j = 0; + +@@ -2451,6 +2450,9 @@ static int __build_all_zonelists(void *d + { + int nid; + ++#ifdef CONFIG_NUMA ++ memset(node_load, 0, sizeof(node_load)); ++#endif + for_each_online_node(nid) { + pg_data_t *pgdat = NODE_DATA(nid); + diff --git a/queue-2.6.30/mm-fix-hugetlb-bug-due-to-user_shm_unlock-call.patch b/queue-2.6.30/mm-fix-hugetlb-bug-due-to-user_shm_unlock-call.patch new file mode 100644 index 00000000000..9edadcd6707 --- /dev/null +++ b/queue-2.6.30/mm-fix-hugetlb-bug-due-to-user_shm_unlock-call.patch @@ -0,0 +1,153 @@ +From 353d5c30c666580347515da609dd74a2b8e9b828 Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Mon, 24 Aug 2009 16:30:28 +0100 +Subject: mm: fix hugetlb bug due to user_shm_unlock call + +From: Hugh Dickins + +commit 353d5c30c666580347515da609dd74a2b8e9b828 upstream. + +2.6.30's commit 8a0bdec194c21c8fdef840989d0d7b742bb5d4bc removed +user_shm_lock() calls in hugetlb_file_setup() but left the +user_shm_unlock call in shm_destroy(). + +In detail: +Assume that can_do_hugetlb_shm() returns true and hence user_shm_lock() +is not called in hugetlb_file_setup(). However, user_shm_unlock() is +called in any case in shm_destroy() and in the following +atomic_dec_and_lock(&up->__count) in free_uid() is executed and if +up->__count gets zero, also cleanup_user_struct() is scheduled. + +Note that sched_destroy_user() is empty if CONFIG_USER_SCHED is not set. +However, the ref counter up->__count gets unexpectedly non-positive and +the corresponding structs are freed even though there are live +references to them, resulting in a kernel oops after a lots of +shmget(SHM_HUGETLB)/shmctl(IPC_RMID) cycles and CONFIG_USER_SCHED set. + +Hugh changed Stefan's suggested patch: can_do_hugetlb_shm() at the +time of shm_destroy() may give a different answer from at the time +of hugetlb_file_setup(). And fixed newseg()'s no_id error path, +which has missed user_shm_unlock() ever since it came in 2.6.9. + +Reported-by: Stefan Huber +Signed-off-by: Hugh Dickins +Tested-by: Stefan Huber +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hugetlbfs/inode.c | 20 ++++++++++++-------- + include/linux/hugetlb.h | 6 ++++-- + ipc/shm.c | 8 +++++--- + 3 files changed, 21 insertions(+), 13 deletions(-) + +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -934,26 +934,28 @@ static int can_do_hugetlb_shm(void) + return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); + } + +-struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag) ++struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, ++ struct user_struct **user) + { + int error = -ENOMEM; +- int unlock_shm = 0; + struct file *file; + struct inode *inode; + struct dentry *dentry, *root; + struct qstr quick_string; +- struct user_struct *user = current_user(); + ++ *user = NULL; + if (!hugetlbfs_vfsmount) + return ERR_PTR(-ENOENT); + + if (!can_do_hugetlb_shm()) { +- if (user_shm_lock(size, user)) { +- unlock_shm = 1; ++ *user = current_user(); ++ if (user_shm_lock(size, *user)) { + WARN_ONCE(1, + "Using mlock ulimits for SHM_HUGETLB deprecated\n"); +- } else ++ } else { ++ *user = NULL; + return ERR_PTR(-EPERM); ++ } + } + + root = hugetlbfs_vfsmount->mnt_root; +@@ -994,8 +996,10 @@ out_inode: + out_dentry: + dput(dentry); + out_shm_unlock: +- if (unlock_shm) +- user_shm_unlock(size, user); ++ if (*user) { ++ user_shm_unlock(size, *user); ++ *user = NULL; ++ } + return ERR_PTR(error); + } + +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -10,6 +10,7 @@ + #include + + struct ctl_table; ++struct user_struct; + + static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) + { +@@ -139,7 +140,8 @@ static inline struct hugetlbfs_sb_info * + + extern const struct file_operations hugetlbfs_file_operations; + extern struct vm_operations_struct hugetlb_vm_ops; +-struct file *hugetlb_file_setup(const char *name, size_t, int); ++struct file *hugetlb_file_setup(const char *name, size_t size, int acct, ++ struct user_struct **user); + int hugetlb_get_quota(struct address_space *mapping, long delta); + void hugetlb_put_quota(struct address_space *mapping, long delta); + +@@ -161,7 +163,7 @@ static inline void set_file_hugepages(st + + #define is_file_hugepages(file) 0 + #define set_file_hugepages(file) BUG() +-#define hugetlb_file_setup(name,size,acctflag) ERR_PTR(-ENOSYS) ++#define hugetlb_file_setup(name,size,acct,user) ERR_PTR(-ENOSYS) + + #endif /* !CONFIG_HUGETLBFS */ + +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -174,7 +174,7 @@ static void shm_destroy(struct ipc_names + shm_unlock(shp); + if (!is_file_hugepages(shp->shm_file)) + shmem_lock(shp->shm_file, 0, shp->mlock_user); +- else ++ else if (shp->mlock_user) + user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size, + shp->mlock_user); + fput (shp->shm_file); +@@ -369,8 +369,8 @@ static int newseg(struct ipc_namespace * + /* hugetlb_file_setup applies strict accounting */ + if (shmflg & SHM_NORESERVE) + acctflag = VM_NORESERVE; +- file = hugetlb_file_setup(name, size, acctflag); +- shp->mlock_user = current_user(); ++ file = hugetlb_file_setup(name, size, acctflag, ++ &shp->mlock_user); + } else { + /* + * Do not allow no accounting for OVERCOMMIT_NEVER, even +@@ -411,6 +411,8 @@ static int newseg(struct ipc_namespace * + return error; + + no_id: ++ if (shp->mlock_user) /* shmflg & SHM_HUGETLB case */ ++ user_shm_unlock(size, shp->mlock_user); + fput(file); + no_file: + security_shm_free(shp); diff --git a/queue-2.6.30/poll-select-initialize-triggered-field-of-struct-poll_wqueues.patch b/queue-2.6.30/poll-select-initialize-triggered-field-of-struct-poll_wqueues.patch new file mode 100644 index 00000000000..2f42ec0ce78 --- /dev/null +++ b/queue-2.6.30/poll-select-initialize-triggered-field-of-struct-poll_wqueues.patch @@ -0,0 +1,44 @@ +From b2add73dbf93fd50f00564d7abc3e2b9aa9dd20c Mon Sep 17 00:00:00 2001 +From: Guillaume Knispel +Date: Sat, 15 Aug 2009 19:30:24 +0200 +Subject: poll/select: initialize triggered field of struct poll_wqueues + +From: Guillaume Knispel + +commit b2add73dbf93fd50f00564d7abc3e2b9aa9dd20c upstream. + +The triggered field of struct poll_wqueues introduced in commit +5f820f648c92a5ecc771a96b3c29aa6e90013bba ("poll: allow f_op->poll to +sleep"). + +It was first set to 1 in pollwake() (now __pollwake() ), tested and +later set to 0 in poll_schedule_timeout(), but not initialized before. + +As a result when the process needs to sleep, triggered was likely to be +non-zero even if pollwake() is not called before the first +poll_schedule_timeout(), meaning schedule_hrtimeout_range() would not be +called and an extra loop calling all ->poll() would be done. + +This patch initialize triggered to 0 in poll_initwait() so the ->poll() +are not called twice before the process goes to sleep when it needs to. + +Signed-off-by: Guillaume Knispel +Acked-by: Thomas Gleixner +Acked-by: Tejun Heo +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/select.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/select.c ++++ b/fs/select.c +@@ -110,6 +110,7 @@ void poll_initwait(struct poll_wqueues * + { + init_poll_funcptr(&pwq->pt, __pollwait); + pwq->polling_task = current; ++ pwq->triggered = 0; + pwq->error = 0; + pwq->table = NULL; + pwq->inline_index = 0; diff --git a/queue-2.6.30/re-introduce-page-mapping-check-in-mark_buffer_dirty.patch b/queue-2.6.30/re-introduce-page-mapping-check-in-mark_buffer_dirty.patch new file mode 100644 index 00000000000..e3b47aae8bb --- /dev/null +++ b/queue-2.6.30/re-introduce-page-mapping-check-in-mark_buffer_dirty.patch @@ -0,0 +1,61 @@ +From 8e9d78edea3ce5c0036f85b93091483f2f15443a Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 21 Aug 2009 17:40:08 -0700 +Subject: Re-introduce page mapping check in mark_buffer_dirty() + +From: Linus Torvalds + +commit 8e9d78edea3ce5c0036f85b93091483f2f15443a upstream. + +In commit a8e7d49aa7be728c4ae241a75a2a124cdcabc0c5 ("Fix race in +create_empty_buffers() vs __set_page_dirty_buffers()"), I removed a test +for a NULL page mapping unintentionally when some of the code inside +__set_page_dirty() was moved to the callers. + +That removal generally didn't matter, since a filesystem would serialize +truncation (which clears the page mapping) against writing (which marks +the buffer dirty), so locking at a higher level (either per-page or an +inode at a time) should mean that the buffer page would be stable. And +indeed, nothing bad seemed to happen. + +Except it turns out that apparently reiserfs does something odd when +under load and writing out the journal, and we have a number of bugzilla +entries that look similar: + + http://bugzilla.kernel.org/show_bug.cgi?id=13556 + http://bugzilla.kernel.org/show_bug.cgi?id=13756 + http://bugzilla.kernel.org/show_bug.cgi?id=13876 + +and it looks like reiserfs depended on that check (the common theme +seems to be "data=journal", and a journal writeback during a truncate). + +I suspect reiserfs should have some additional locking, but in the +meantime this should get us back to the pre-2.6.29 behavior. + +Pattern-pointed-out-by: Roland Kletzing +Cc: Jeff Mahoney +Cc: Nick Piggin +Cc: Al Viro +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/buffer.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -1165,8 +1165,11 @@ void mark_buffer_dirty(struct buffer_hea + + if (!test_set_buffer_dirty(bh)) { + struct page *page = bh->b_page; +- if (!TestSetPageDirty(page)) +- __set_page_dirty(page, page_mapping(page), 0); ++ if (!TestSetPageDirty(page)) { ++ struct address_space *mapping = page_mapping(page); ++ if (mapping) ++ __set_page_dirty(page, mapping, 0); ++ } + } + } + diff --git a/queue-2.6.30/rt2x00-fix-memory-corruption-in-rf-cache-add-a-sanity-check.patch b/queue-2.6.30/rt2x00-fix-memory-corruption-in-rf-cache-add-a-sanity-check.patch new file mode 100644 index 00000000000..a41aae43e84 --- /dev/null +++ b/queue-2.6.30/rt2x00-fix-memory-corruption-in-rf-cache-add-a-sanity-check.patch @@ -0,0 +1,44 @@ +From 6b26dead3ce97d016b57724b01974d5ca5c84bd5 Mon Sep 17 00:00:00 2001 +From: Pavel Roskin +Date: Tue, 4 Aug 2009 17:48:16 -0400 +Subject: rt2x00: fix memory corruption in rf cache, add a sanity check + +From: Pavel Roskin + +commit 6b26dead3ce97d016b57724b01974d5ca5c84bd5 upstream. + +Change rt2x00_rf_read() and rt2x00_rf_write() to subtract 1 from the rf +register number. This is needed because the rf registers are enumerated +starting with one. The size of the rf register cache is just enough to +hold all registers, so writing to the highest register was corrupting +memory. Add a check to make sure that the rf register number is valid. + +Signed-off-by: Pavel Roskin +Acked-by: Ivo van Doorn +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rt2x00/rt2x00.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -814,13 +814,15 @@ struct rt2x00_dev { + static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev, + const unsigned int word, u32 *data) + { +- *data = rt2x00dev->rf[word]; ++ BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32)); ++ *data = rt2x00dev->rf[word - 1]; + } + + static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev, + const unsigned int word, u32 data) + { +- rt2x00dev->rf[word] = data; ++ BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32)); ++ rt2x00dev->rf[word - 1] = data; + } + + /* diff --git a/queue-2.6.30/series b/queue-2.6.30/series new file mode 100644 index 00000000000..2c49c1b6a45 --- /dev/null +++ b/queue-2.6.30/series @@ -0,0 +1,18 @@ +ehea-fix-napi-list-corruption-on-ifconfig-down.patch +poll-select-initialize-triggered-field-of-struct-poll_wqueues.patch +make-bitmask-and-operators-return-a-result-code.patch +x86-don-t-send-an-ipi-to-the-empty-set-of-cpu-s.patch +x86-don-t-call-send_ipi_mask-with-an-empty-mask.patch +mm-build_zonelists-move-clear-node_load-to-__build_all_zonelists.patch +rt2x00-fix-memory-corruption-in-rf-cache-add-a-sanity-check.patch +mac80211-fix-panic-when-splicing-unprepared-tids.patch +re-introduce-page-mapping-check-in-mark_buffer_dirty.patch +mm-fix-hugetlb-bug-due-to-user_shm_unlock-call.patch +ima-hashing-large-files-bug-fix.patch +kernel_read-redefine-offset-type.patch +tracing-fix-too-large-stack-usage-in-do_one_initcall.patch +sound-pcm_lib-fix-unsorted-list-constraint-handling.patch +clone-fix-race-between-copy_process-and-de_thread.patch +wmi-fix-kernel-panic-when-stack-protection-enabled.patch +sunrpc-fix-rpc_task_force_reencode.patch +alsa-hda-fix-macbookpro-3-1-4-1-quirk-with-alc889a.patch diff --git a/queue-2.6.30/sound-pcm_lib-fix-unsorted-list-constraint-handling.patch b/queue-2.6.30/sound-pcm_lib-fix-unsorted-list-constraint-handling.patch new file mode 100644 index 00000000000..620f4b55ff8 --- /dev/null +++ b/queue-2.6.30/sound-pcm_lib-fix-unsorted-list-constraint-handling.patch @@ -0,0 +1,86 @@ +From b1ddaf681e362ed453182ddee1699d7487069a16 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Tue, 25 Aug 2009 08:15:41 +0200 +Subject: sound: pcm_lib: fix unsorted list constraint handling + +From: Clemens Ladisch + +commit b1ddaf681e362ed453182ddee1699d7487069a16 upstream. + +snd_interval_list() expected a sorted list but did not document this, so +there are drivers that give it an unsorted list. To fix this, change +the algorithm to work with any list. + +This fixes the "Slave PCM not usable" error with USB devices that have +multiple alternate settings with sample rates in decreasing order, such +as the Philips Askey VC010 WebCam. + +http://bugzilla.kernel.org/show_bug.cgi?id=14028 + +Reported-and-tested-by: Andrzej +Signed-off-by: Clemens Ladisch +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/pcm_lib.c | 39 ++++++++------------------------------- + 1 file changed, 8 insertions(+), 31 deletions(-) + +--- a/sound/core/pcm_lib.c ++++ b/sound/core/pcm_lib.c +@@ -876,47 +876,24 @@ static int snd_interval_ratden(struct sn + int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) + { + unsigned int k; +- int changed = 0; ++ struct snd_interval list_range; + + if (!count) { + i->empty = 1; + return -EINVAL; + } ++ snd_interval_any(&list_range); ++ list_range.min = UINT_MAX; ++ list_range.max = 0; + for (k = 0; k < count; k++) { + if (mask && !(mask & (1 << k))) + continue; +- if (i->min == list[k] && !i->openmin) +- goto _l1; +- if (i->min < list[k]) { +- i->min = list[k]; +- i->openmin = 0; +- changed = 1; +- goto _l1; +- } +- } +- i->empty = 1; +- return -EINVAL; +- _l1: +- for (k = count; k-- > 0;) { +- if (mask && !(mask & (1 << k))) ++ if (!snd_interval_test(i, list[k])) + continue; +- if (i->max == list[k] && !i->openmax) +- goto _l2; +- if (i->max > list[k]) { +- i->max = list[k]; +- i->openmax = 0; +- changed = 1; +- goto _l2; +- } ++ list_range.min = min(list_range.min, list[k]); ++ list_range.max = max(list_range.max, list[k]); + } +- i->empty = 1; +- return -EINVAL; +- _l2: +- if (snd_interval_checkempty(i)) { +- i->empty = 1; +- return -EINVAL; +- } +- return changed; ++ return snd_interval_refine(i, &list_range); + } + + EXPORT_SYMBOL(snd_interval_list); diff --git a/queue-2.6.30/sunrpc-fix-rpc_task_force_reencode.patch b/queue-2.6.30/sunrpc-fix-rpc_task_force_reencode.patch new file mode 100644 index 00000000000..a875f184369 --- /dev/null +++ b/queue-2.6.30/sunrpc-fix-rpc_task_force_reencode.patch @@ -0,0 +1,34 @@ +From 2574cc9f4ffc6c681c9177111357efe5b76f0e36 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 28 Aug 2009 11:12:12 -0400 +Subject: SUNRPC: Fix rpc_task_force_reencode + +From: Trond Myklebust + +commit 2574cc9f4ffc6c681c9177111357efe5b76f0e36 upstream. + +This patch fixes the bug that was reported in + http://bugzilla.kernel.org/show_bug.cgi?id=14053 + +If we're in the case where we need to force a reencode and then resend of +the RPC request, due to xprt_transmit failing with a networking error, then +we _must_ retransmit the entire request. + +Signed-off-by: Trond Myklebust +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/clnt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -876,6 +876,7 @@ static inline void + rpc_task_force_reencode(struct rpc_task *task) + { + task->tk_rqstp->rq_snd_buf.len = 0; ++ task->tk_rqstp->rq_bytes_sent = 0; + } + + static inline void diff --git a/queue-2.6.30/tracing-fix-too-large-stack-usage-in-do_one_initcall.patch b/queue-2.6.30/tracing-fix-too-large-stack-usage-in-do_one_initcall.patch new file mode 100644 index 00000000000..c8f93af2680 --- /dev/null +++ b/queue-2.6.30/tracing-fix-too-large-stack-usage-in-do_one_initcall.patch @@ -0,0 +1,183 @@ +From 4a683bf94b8a10e2bb0da07aec3ac0a55e5de61f Mon Sep 17 00:00:00 2001 +From: Ingo Molnar +Date: Fri, 21 Aug 2009 12:53:36 +0200 +Subject: tracing: Fix too large stack usage in do_one_initcall() + +From: Ingo Molnar + +commit 4a683bf94b8a10e2bb0da07aec3ac0a55e5de61f upstream. + +One of my testboxes triggered this nasty stack overflow crash +during SCSI probing: + +[ 5.874004] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA +[ 5.875004] device: 'sda': device_add +[ 5.878004] BUG: unable to handle kernel NULL pointer dereference at 00000a0c +[ 5.878004] IP: [] print_context_stack+0x81/0x110 +[ 5.878004] *pde = 00000000 +[ 5.878004] Thread overran stack, or stack corrupted +[ 5.878004] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC +[ 5.878004] last sysfs file: +[ 5.878004] +[ 5.878004] Pid: 1, comm: swapper Not tainted (2.6.31-rc6-tip-01272-g9919e28-dirty #5685) +[ 5.878004] EIP: 0060:[] EFLAGS: 00010083 CPU: 0 +[ 5.878004] EIP is at print_context_stack+0x81/0x110 +[ 5.878004] EAX: cf8a3000 EBX: cf8a3fe4 ECX: 00000049 EDX: 00000000 +[ 5.878004] ESI: b1cfce84 EDI: 00000000 EBP: cf8a3018 ESP: cf8a2ff4 +[ 5.878004] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 +[ 5.878004] Process swapper (pid: 1, ti=cf8a2000 task=cf8a8000 task.ti=cf8a3000) +[ 5.878004] Stack: +[ 5.878004] b1004867 fffff000 cf8a3ffc +[ 5.878004] Call Trace: +[ 5.878004] [] ? kernel_thread_helper+0x7/0x10 +[ 5.878004] BUG: unable to handle kernel NULL pointer dereference at 00000a0c +[ 5.878004] IP: [] print_context_stack+0x81/0x110 +[ 5.878004] *pde = 00000000 +[ 5.878004] Thread overran stack, or stack corrupted +[ 5.878004] Oops: 0000 [#2] PREEMPT SMP DEBUG_PAGEALLOC + +The oops did not reveal any more details about the real stack +that we have and the system got into an infinite loop of +recursive pagefaults. + +So i booted with CONFIG_STACK_TRACER=y and the 'stacktrace' boot +parameter. The box did not crash (timings/conditions probably +changed a tiny bit to trigger the catastrophic crash), but the +/debug/tracing/stack_trace file was rather revealing: + + Depth Size Location (72 entries) + ----- ---- -------- + 0) 3704 52 __change_page_attr+0xb8/0x290 + 1) 3652 24 __change_page_attr_set_clr+0x43/0x90 + 2) 3628 60 kernel_map_pages+0x108/0x120 + 3) 3568 40 prep_new_page+0x7d/0x130 + 4) 3528 84 get_page_from_freelist+0x106/0x420 + 5) 3444 116 __alloc_pages_nodemask+0xd7/0x550 + 6) 3328 36 allocate_slab+0xb1/0x100 + 7) 3292 36 new_slab+0x1c/0x160 + 8) 3256 36 __slab_alloc+0x133/0x2b0 + 9) 3220 4 kmem_cache_alloc+0x1bb/0x1d0 + 10) 3216 108 create_object+0x28/0x250 + 11) 3108 40 kmemleak_alloc+0x81/0xc0 + 12) 3068 24 kmem_cache_alloc+0x162/0x1d0 + 13) 3044 52 scsi_pool_alloc_command+0x29/0x70 + 14) 2992 20 scsi_host_alloc_command+0x22/0x70 + 15) 2972 24 __scsi_get_command+0x1b/0x90 + 16) 2948 28 scsi_get_command+0x35/0x90 + 17) 2920 24 scsi_setup_blk_pc_cmnd+0xd4/0x100 + 18) 2896 128 sd_prep_fn+0x332/0xa70 + 19) 2768 36 blk_peek_request+0xe7/0x1d0 + 20) 2732 56 scsi_request_fn+0x54/0x520 + 21) 2676 12 __generic_unplug_device+0x2b/0x40 + 22) 2664 24 blk_execute_rq_nowait+0x59/0x80 + 23) 2640 172 blk_execute_rq+0x6b/0xb0 + 24) 2468 32 scsi_execute+0xe0/0x140 + 25) 2436 64 scsi_execute_req+0x152/0x160 + 26) 2372 60 scsi_vpd_inquiry+0x6c/0x90 + 27) 2312 44 scsi_get_vpd_page+0x112/0x160 + 28) 2268 52 sd_revalidate_disk+0x1df/0x320 + 29) 2216 92 rescan_partitions+0x98/0x330 + 30) 2124 52 __blkdev_get+0x309/0x350 + 31) 2072 8 blkdev_get+0xf/0x20 + 32) 2064 44 register_disk+0xff/0x120 + 33) 2020 36 add_disk+0x6e/0xb0 + 34) 1984 44 sd_probe_async+0xfb/0x1d0 + 35) 1940 44 __async_schedule+0xf4/0x1b0 + 36) 1896 8 async_schedule+0x12/0x20 + 37) 1888 60 sd_probe+0x305/0x360 + 38) 1828 44 really_probe+0x63/0x170 + 39) 1784 36 driver_probe_device+0x5d/0x60 + 40) 1748 16 __device_attach+0x49/0x50 + 41) 1732 32 bus_for_each_drv+0x5b/0x80 + 42) 1700 24 device_attach+0x6b/0x70 + 43) 1676 16 bus_attach_device+0x47/0x60 + 44) 1660 76 device_add+0x33d/0x400 + 45) 1584 52 scsi_sysfs_add_sdev+0x6a/0x2c0 + 46) 1532 108 scsi_add_lun+0x44b/0x460 + 47) 1424 116 scsi_probe_and_add_lun+0x182/0x4e0 + 48) 1308 36 __scsi_add_device+0xd9/0xe0 + 49) 1272 44 ata_scsi_scan_host+0x10b/0x190 + 50) 1228 24 async_port_probe+0x96/0xd0 + 51) 1204 44 __async_schedule+0xf4/0x1b0 + 52) 1160 8 async_schedule+0x12/0x20 + 53) 1152 48 ata_host_register+0x171/0x1d0 + 54) 1104 60 ata_pci_sff_activate_host+0xf3/0x230 + 55) 1044 44 ata_pci_sff_init_one+0xea/0x100 + 56) 1000 48 amd_init_one+0xb2/0x190 + 57) 952 8 local_pci_probe+0x13/0x20 + 58) 944 32 pci_device_probe+0x68/0x90 + 59) 912 44 really_probe+0x63/0x170 + 60) 868 36 driver_probe_device+0x5d/0x60 + 61) 832 20 __driver_attach+0x89/0xa0 + 62) 812 32 bus_for_each_dev+0x5b/0x80 + 63) 780 12 driver_attach+0x1e/0x20 + 64) 768 72 bus_add_driver+0x14b/0x2d0 + 65) 696 36 driver_register+0x6e/0x150 + 66) 660 20 __pci_register_driver+0x53/0xc0 + 67) 640 8 amd_init+0x14/0x16 + 68) 632 572 do_one_initcall+0x2b/0x1d0 + 69) 60 12 do_basic_setup+0x56/0x6a + 70) 48 20 kernel_init+0x84/0xce + 71) 28 28 kernel_thread_helper+0x7/0x10 + +There's a lot of fat functions on that stack trace, but +the largest of all is do_one_initcall(). This is due to +the boot trace entry variables being on the stack. + +Fixing this is relatively easy, initcalls are fundamentally +serialized, so we can move the local variables to file scope. + +Note that this large stack footprint was present for a +couple of months already - what pushed my system over +the edge was the addition of kmemleak to the call-chain: + + 6) 3328 36 allocate_slab+0xb1/0x100 + 7) 3292 36 new_slab+0x1c/0x160 + 8) 3256 36 __slab_alloc+0x133/0x2b0 + 9) 3220 4 kmem_cache_alloc+0x1bb/0x1d0 + 10) 3216 108 create_object+0x28/0x250 + 11) 3108 40 kmemleak_alloc+0x81/0xc0 + 12) 3068 24 kmem_cache_alloc+0x162/0x1d0 + 13) 3044 52 scsi_pool_alloc_command+0x29/0x70 + +This pushes the total to ~3800 bytes, only a tiny bit +more was needed to corrupt the on-kernel-stack thread_info. + +The fix reduces the stack footprint from 572 bytes +to 28 bytes. + +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Frederic Weisbecker +Cc: Steven Rostedt +Cc: Catalin Marinas +Cc: Jens Axboe +Cc: Linus Torvalds +LKML-Reference: +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + init/main.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/init/main.c ++++ b/init/main.c +@@ -702,13 +702,14 @@ asmlinkage void __init start_kernel(void + int initcall_debug; + core_param(initcall_debug, initcall_debug, bool, 0644); + ++static char msgbuf[64]; ++static struct boot_trace_call call; ++static struct boot_trace_ret ret; ++ + int do_one_initcall(initcall_t fn) + { + int count = preempt_count(); + ktime_t calltime, delta, rettime; +- char msgbuf[64]; +- struct boot_trace_call call; +- struct boot_trace_ret ret; + + if (initcall_debug) { + call.caller = task_pid_nr(current); diff --git a/queue-2.6.30/wmi-fix-kernel-panic-when-stack-protection-enabled.patch b/queue-2.6.30/wmi-fix-kernel-panic-when-stack-protection-enabled.patch new file mode 100644 index 00000000000..d2a3b9d0009 --- /dev/null +++ b/queue-2.6.30/wmi-fix-kernel-panic-when-stack-protection-enabled.patch @@ -0,0 +1,82 @@ +From f3d83e2415445e5b157bef404d38674e9e8de169 Mon Sep 17 00:00:00 2001 +From: Costantino Leandro +Date: Wed, 26 Aug 2009 14:29:28 -0700 +Subject: wmi: fix kernel panic when stack protection enabled. + +From: Costantino Leandro + +commit f3d83e2415445e5b157bef404d38674e9e8de169 upstream. + +Summary: +Kernel panic arise when stack protection is enabled, since strncat will +add a null terminating byte '\0'; So in functions +like this one (wmi_query_block): + char wc[4]="WC"; + .... + strncat(method, block->object_id, 2); + ... +the length of wc should be n+1 (wc[5]) or stack protection +fault will arise. This is not noticeable when stack protection is +disabled,but , isn't good either. +Config used: [CONFIG_CC_STACKPROTECTOR_ALL=y, + CONFIG_CC_STACKPROTECTOR=y] + +Panic Trace +------------ + .... stack-protector: kernel stack corrupted in : fa7b182c + 2.6.30-rc8-obelisco-generic + call_trace: + [] ? panic+0x45/0xd9 + [] ? __stack_chk_fail+0x1c/0x40 + [] ? wmi_query_block+0x15a/0x162 [wmi] + [] ? wmi_query_block+0x15a/0x162 [wmi] + [] ? acer_wmi_init+0x00/0x61a [acer_wmi] + [] ? acer_wmi_init+0x135/0x61a [acer_wmi] + [] ? do_one_initcall+0x50+0x126 + +Addresses http://bugzilla.kernel.org/show_bug.cgi?id=13514 + +Signed-off-by: Costantino Leandro +Signed-off-by: Carlos Corbacho +Cc: Len Brown +Cc: Bjorn Helgaas +Cc: "Rafael J. Wysocki" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/wmi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/platform/x86/wmi.c ++++ b/drivers/platform/x86/wmi.c +@@ -270,7 +270,7 @@ u32 method_id, const struct acpi_buffer + acpi_status status; + struct acpi_object_list input; + union acpi_object params[3]; +- char method[4] = "WM"; ++ char method[5] = "WM"; + + if (!find_guid(guid_string, &wblock)) + return AE_ERROR; +@@ -328,8 +328,8 @@ struct acpi_buffer *out) + acpi_status status, wc_status = AE_ERROR; + struct acpi_object_list input, wc_input; + union acpi_object wc_params[1], wq_params[1]; +- char method[4]; +- char wc_method[4] = "WC"; ++ char method[5]; ++ char wc_method[5] = "WC"; + + if (!guid_string || !out) + return AE_BAD_PARAMETER; +@@ -410,7 +410,7 @@ const struct acpi_buffer *in) + acpi_handle handle; + struct acpi_object_list input; + union acpi_object params[2]; +- char method[4] = "WS"; ++ char method[5] = "WS"; + + if (!guid_string || !in) + return AE_BAD_DATA; diff --git a/queue-2.6.30/x86-don-t-call-send_ipi_mask-with-an-empty-mask.patch b/queue-2.6.30/x86-don-t-call-send_ipi_mask-with-an-empty-mask.patch new file mode 100644 index 00000000000..4e844e9588e --- /dev/null +++ b/queue-2.6.30/x86-don-t-call-send_ipi_mask-with-an-empty-mask.patch @@ -0,0 +1,81 @@ +From b04e6373d694e977c95ae0ae000e2c1e2cf92d73 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 21 Aug 2009 09:48:10 -0700 +Subject: x86: don't call '->send_IPI_mask()' with an empty mask +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Linus Torvalds + +commit b04e6373d694e977c95ae0ae000e2c1e2cf92d73 upstream. + +As noted in 83d349f35e1ae72268c5104dbf9ab2ae635425d4 ("x86: don't send +an IPI to the empty set of CPU's"), some APIC's will be very unhappy +with an empty destination mask. That commit added a WARN_ON() for that +case, and avoided the resulting problem, but didn't fix the underlying +reason for why those empty mask cases happened. + +This fixes that, by checking the result of 'cpumask_andnot()' of the +current CPU actually has any other CPU's left in the set of CPU's to be +sent a TLB flush, and not calling down to the IPI code if the mask is +empty. + +The reason this started happening at all is that we started passing just +the CPU mask pointers around in commit 4595f9620 ("x86: change +flush_tlb_others to take a const struct cpumask"), and when we did that, +the cpumask was no longer thread-local. + +Before that commit, flush_tlb_mm() used to create it's own copy of +'mm->cpu_vm_mask' and pass that copy down to the low-level flush +routines after having tested that it was not empty. But after changing +it to just pass down the CPU mask pointer, the lower level TLB flush +routines would now get a pointer to that 'mm->cpu_vm_mask', and that +could still change - and become empty - after the test due to other +CPU's having flushed their own TLB's. + +See + + http://bugzilla.kernel.org/show_bug.cgi?id=13933 + +for details. + +Tested-by: Thomas Björnell +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/tlb.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/arch/x86/mm/tlb.c ++++ b/arch/x86/mm/tlb.c +@@ -183,18 +183,17 @@ static void flush_tlb_others_ipi(const s + + f->flush_mm = mm; + f->flush_va = va; +- cpumask_andnot(to_cpumask(f->flush_cpumask), +- cpumask, cpumask_of(smp_processor_id())); ++ if (cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id()))) { ++ /* ++ * We have to send the IPI only to ++ * CPUs affected. ++ */ ++ apic->send_IPI_mask(to_cpumask(f->flush_cpumask), ++ INVALIDATE_TLB_VECTOR_START + sender); + +- /* +- * We have to send the IPI only to +- * CPUs affected. +- */ +- apic->send_IPI_mask(to_cpumask(f->flush_cpumask), +- INVALIDATE_TLB_VECTOR_START + sender); +- +- while (!cpumask_empty(to_cpumask(f->flush_cpumask))) +- cpu_relax(); ++ while (!cpumask_empty(to_cpumask(f->flush_cpumask))) ++ cpu_relax(); ++ } + + f->flush_mm = NULL; + f->flush_va = 0; diff --git a/queue-2.6.30/x86-don-t-send-an-ipi-to-the-empty-set-of-cpu-s.patch b/queue-2.6.30/x86-don-t-send-an-ipi-to-the-empty-set-of-cpu-s.patch new file mode 100644 index 00000000000..49dd8592df9 --- /dev/null +++ b/queue-2.6.30/x86-don-t-send-an-ipi-to-the-empty-set-of-cpu-s.patch @@ -0,0 +1,53 @@ +From 83d349f35e1ae72268c5104dbf9ab2ae635425d4 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 21 Aug 2009 09:23:57 -0700 +Subject: x86: don't send an IPI to the empty set of CPU's +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Linus Torvalds + +commit 83d349f35e1ae72268c5104dbf9ab2ae635425d4 upstream. + +The default_send_IPI_mask_logical() function uses the "flat" APIC mode +to send an IPI to a set of CPU's at once, but if that set happens to be +empty, some older local APIC's will apparently be rather unhappy. So +just warn if a caller gives us an empty mask, and ignore it. + +This fixes a regression in 2.6.30.x, due to commit 4595f9620 ("x86: +change flush_tlb_others to take a const struct cpumask"), documented +here: + + http://bugzilla.kernel.org/show_bug.cgi?id=13933 + +which causes a silent lock-up. It only seems to happen on PPro, P2, P3 +and Athlon XP cores. Most developers sadly (or not so sadly, if you're +a developer..) have more modern CPU's. Also, on x86-64 we don't use the +flat APIC mode, so it would never trigger there even if the APIC didn't +like sending an empty IPI mask. + +Reported-by: Pavel Vilim +Reported-and-tested-by: Thomas Björnell +Reported-and-tested-by: Martin Rogge +Cc: Mike Travis +Cc: Ingo Molnar +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/apic/ipi.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/kernel/apic/ipi.c ++++ b/arch/x86/kernel/apic/ipi.c +@@ -106,6 +106,9 @@ void default_send_IPI_mask_logical(const + unsigned long mask = cpumask_bits(cpumask)[0]; + unsigned long flags; + ++ if (WARN_ONCE(!mask, "empty IPI mask")) ++ return; ++ + local_irq_save(flags); + WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]); + __default_send_IPI_dest_field(mask, vector, apic->dest_logical);