]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
start up a .30 queue
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 3 Sep 2009 20:43:17 +0000 (13:43 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 3 Sep 2009 20:43:17 +0000 (13:43 -0700)
19 files changed:
queue-2.6.30/alsa-hda-fix-macbookpro-3-1-4-1-quirk-with-alc889a.patch [new file with mode: 0644]
queue-2.6.30/clone-fix-race-between-copy_process-and-de_thread.patch [new file with mode: 0644]
queue-2.6.30/ehea-fix-napi-list-corruption-on-ifconfig-down.patch [new file with mode: 0644]
queue-2.6.30/ima-hashing-large-files-bug-fix.patch [new file with mode: 0644]
queue-2.6.30/kernel_read-redefine-offset-type.patch [new file with mode: 0644]
queue-2.6.30/mac80211-fix-panic-when-splicing-unprepared-tids.patch [new file with mode: 0644]
queue-2.6.30/make-bitmask-and-operators-return-a-result-code.patch [new file with mode: 0644]
queue-2.6.30/mm-build_zonelists-move-clear-node_load-to-__build_all_zonelists.patch [new file with mode: 0644]
queue-2.6.30/mm-fix-hugetlb-bug-due-to-user_shm_unlock-call.patch [new file with mode: 0644]
queue-2.6.30/poll-select-initialize-triggered-field-of-struct-poll_wqueues.patch [new file with mode: 0644]
queue-2.6.30/re-introduce-page-mapping-check-in-mark_buffer_dirty.patch [new file with mode: 0644]
queue-2.6.30/rt2x00-fix-memory-corruption-in-rf-cache-add-a-sanity-check.patch [new file with mode: 0644]
queue-2.6.30/series [new file with mode: 0644]
queue-2.6.30/sound-pcm_lib-fix-unsorted-list-constraint-handling.patch [new file with mode: 0644]
queue-2.6.30/sunrpc-fix-rpc_task_force_reencode.patch [new file with mode: 0644]
queue-2.6.30/tracing-fix-too-large-stack-usage-in-do_one_initcall.patch [new file with mode: 0644]
queue-2.6.30/wmi-fix-kernel-panic-when-stack-protection-enabled.patch [new file with mode: 0644]
queue-2.6.30/x86-don-t-call-send_ipi_mask-with-an-empty-mask.patch [new file with mode: 0644]
queue-2.6.30/x86-don-t-send-an-ipi-to-the-empty-set-of-cpu-s.patch [new file with mode: 0644]

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 (file)
index 0000000..1ab19fc
--- /dev/null
@@ -0,0 +1,102 @@
+From a3f730af7e33cea10ea66f05b2565fde1f9512df Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 31 Aug 2009 08:15:26 +0200
+Subject: ALSA: hda - Fix MacBookPro 3,1/4,1 quirk with ALC889A
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..3cf67f4
--- /dev/null
@@ -0,0 +1,145 @@
+From 4ab6c08336535f8c8e42cf45d7adeda882eff06e Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Wed, 26 Aug 2009 14:29:24 -0700
+Subject: clone(): fix race between copy_process() and de_thread()
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+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 <sys/types.h>
+       #include <sys/wait.h>
+       #include <unistd.h>
+       #include <stdio.h>
+       #include <errno.h>
+       #include <pthread.h>
+
+       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 <h-shimamoto@ct.jp.nec.com>
+Tested-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Roland McGrath <roland@redhat.com>
+Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.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@suse.de>
+
+---
+ 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(&current->signal->count);
+-              atomic_inc(&current->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(&current->signal->count);
++              atomic_inc(&current->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 (file)
index 0000000..9c2c3d0
--- /dev/null
@@ -0,0 +1,44 @@
+From 357eb46d8f275b4e8484541234ea3ba06065e258 Mon Sep 17 00:00:00 2001
+From: Hannes Hering <hering2@de.ibm.com>
+Date: Tue, 4 Aug 2009 11:48:39 -0700
+Subject: ehea: Fix napi list corruption on ifconfig down
+
+From: Hannes Hering <hering2@de.ibm.com>
+
+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 <hering2@de.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 <asm/io.h>
+ #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 (file)
index 0000000..360b2f4
--- /dev/null
@@ -0,0 +1,45 @@
+From 16bfa38b1936212428cb38fbfbbb8f6c62b8d81f Mon Sep 17 00:00:00 2001
+From: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Date: Fri, 21 Aug 2009 14:32:49 -0400
+Subject: ima: hashing large files bug fix
+
+From: Mimi Zohar <zohar@linux.vnet.ibm.com>
+
+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 <zohar@us.ibm.com>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..b0666e5
--- /dev/null
@@ -0,0 +1,46 @@
+From 6777d773a463ac045d333b989d4e44660f8d92ad Mon Sep 17 00:00:00 2001
+From: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Date: Fri, 21 Aug 2009 14:32:48 -0400
+Subject: kernel_read: redefine offset type
+
+From: Mimi Zohar <zohar@linux.vnet.ibm.com>
+
+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 <zohar@us.ibm.com>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..a9b1977
--- /dev/null
@@ -0,0 +1,94 @@
+From 416fbdff2137e8d8cc8f23f517bee3a26b11526f Mon Sep 17 00:00:00 2001
+From: Luis R. Rodriguez <lrodriguez@atheros.com>
+Date: Tue, 11 Aug 2009 13:10:33 -0700
+Subject: mac80211: fix panic when splicing unprepared TIDs
+
+From: Luis R. Rodriguez <lrodriguez@atheros.com>
+
+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: [<f8806c70>] 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: <bleh>
+
+Pid: 0, comm: swapper Not tainted (2.6.31-rc5-wl #2) Dell DV051
+EIP: 0060:[<f8806c70>] 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: <bleh2>
+Call Trace:
+ [<f8806edb>] ? ieee80211_stop_tx_ba_cb+0xab/0x150 [mac80211]
+ [<f8802f1e>] ? ieee80211_tasklet_handler+0xce/0x110 [mac80211]
+ [<c04862ff>] ? net_rx_action+0xef/0x1d0
+ [<c0149378>] ? tasklet_action+0x58/0xc0
+ [<c014a0f2>] ? __do_softirq+0xc2/0x190
+ [<c018eb48>] ? handle_IRQ_event+0x58/0x140
+ [<c01205fe>] ? ack_apic_level+0x7e/0x270
+ [<c014a1fd>] ? do_softirq+0x3d/0x40
+ [<c014a345>] ? irq_exit+0x65/0x90
+ [<c010a6af>] ? do_IRQ+0x4f/0xc0
+ [<c014a35d>] ? irq_exit+0x7d/0x90
+ [<c011d547>] ? smp_apic_timer_interrupt+0x57/0x90
+ [<c01094a9>] ? common_interrupt+0x29/0x30
+ [<c010fd9e>] ? mwait_idle+0xbe/0x100
+ [<c0107e42>] ? cpu_idle+0x52/0x90
+ [<c054b1a5>] ? rest_init+0x55/0x60
+ [<c077492d>] ? start_kernel+0x315/0x37d
+ [<c07743ce>] ? unknown_bootoption+0x0/0x1f9
+ [<c0774099>] ? i386_start_kernel+0x79/0x81
+Code: <bleh3>
+EIP: [<f8806c70>] ieee80211_agg_splice_packets+0x40/0xc0 [mac80211] SS:ESP 0068:c076be38
+CR2: 0000000000000030
+
+Testedy-by: Jack Lau <jackelectronics@hotmail.com>
+Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..f9f5009
--- /dev/null
@@ -0,0 +1,187 @@
+From f4b0373b26567cafd421d91101852ed7a34e9e94 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 21 Aug 2009 09:26:15 -0700
+Subject: Make bitmask 'and' operators return a result code
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+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 <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..a9d5459
--- /dev/null
@@ -0,0 +1,65 @@
+From 7f9cfb31030737a7fc9a1cbca3fd01bec184c849 Mon Sep 17 00:00:00 2001
+From: Bo Liu <bo-liu@hotmail.com>
+Date: Tue, 18 Aug 2009 14:11:19 -0700
+Subject: mm: build_zonelists(): move clear node_load[] to __build_all_zonelists()
+
+From: Bo Liu <bo-liu@hotmail.com>
+
+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 <bo-liu@hotmail.com>
+Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Christoph Lameter <cl@linux-foundation.org>
+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@suse.de>
+
+---
+ 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 (file)
index 0000000..9edadcd
--- /dev/null
@@ -0,0 +1,153 @@
+From 353d5c30c666580347515da609dd74a2b8e9b828 Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hugh.dickins@tiscali.co.uk>
+Date: Mon, 24 Aug 2009 16:30:28 +0100
+Subject: mm: fix hugetlb bug due to user_shm_unlock call
+
+From: Hugh Dickins <hugh.dickins@tiscali.co.uk>
+
+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 <shuber2@gmail.com>
+Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk>
+Tested-by: Stefan Huber <shuber2@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 <asm/tlbflush.h>
+ 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 (file)
index 0000000..2f42ec0
--- /dev/null
@@ -0,0 +1,44 @@
+From b2add73dbf93fd50f00564d7abc3e2b9aa9dd20c Mon Sep 17 00:00:00 2001
+From: Guillaume Knispel <gknispel@proformatique.com>
+Date: Sat, 15 Aug 2009 19:30:24 +0200
+Subject: poll/select: initialize triggered field of struct poll_wqueues
+
+From: Guillaume Knispel <gknispel@proformatique.com>
+
+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 <gknispel@proformatique.com>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..e3b47aa
--- /dev/null
@@ -0,0 +1,61 @@
+From 8e9d78edea3ce5c0036f85b93091483f2f15443a Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 21 Aug 2009 17:40:08 -0700
+Subject: Re-introduce page mapping check in mark_buffer_dirty()
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+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 <devzero@web.de>
+Cc: Jeff Mahoney <jeffm@suse.com>
+Cc: Nick Piggin <npiggin@suse.de>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..a41aae4
--- /dev/null
@@ -0,0 +1,44 @@
+From 6b26dead3ce97d016b57724b01974d5ca5c84bd5 Mon Sep 17 00:00:00 2001
+From: Pavel Roskin <proski@gnu.org>
+Date: Tue, 4 Aug 2009 17:48:16 -0400
+Subject: rt2x00: fix memory corruption in rf cache, add a sanity check
+
+From: Pavel Roskin <proski@gnu.org>
+
+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 <proski@gnu.org>
+Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..2c49c1b
--- /dev/null
@@ -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 (file)
index 0000000..620f4b5
--- /dev/null
@@ -0,0 +1,86 @@
+From b1ddaf681e362ed453182ddee1699d7487069a16 Mon Sep 17 00:00:00 2001
+From: Clemens Ladisch <clemens@ladisch.de>
+Date: Tue, 25 Aug 2009 08:15:41 +0200
+Subject: sound: pcm_lib: fix unsorted list constraint handling
+
+From: Clemens Ladisch <clemens@ladisch.de>
+
+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 <adkadk@gmail.com>
+Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..a875f18
--- /dev/null
@@ -0,0 +1,34 @@
+From 2574cc9f4ffc6c681c9177111357efe5b76f0e36 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 28 Aug 2009 11:12:12 -0400
+Subject: SUNRPC: Fix rpc_task_force_reencode
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+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 <Trond.Myklebust@netapp.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..c8f93af
--- /dev/null
@@ -0,0 +1,183 @@
+From 4a683bf94b8a10e2bb0da07aec3ac0a55e5de61f Mon Sep 17 00:00:00 2001
+From: Ingo Molnar <mingo@elte.hu>
+Date: Fri, 21 Aug 2009 12:53:36 +0200
+Subject: tracing: Fix too large stack usage in do_one_initcall()
+
+From: Ingo Molnar <mingo@elte.hu>
+
+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: [<b1008321>] 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:[<b1008321>] 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]  [<b1004867>] ? kernel_thread_helper+0x7/0x10
+[    5.878004] BUG: unable to handle kernel NULL pointer dereference at 00000a0c
+[    5.878004] IP: [<b1008321>] 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 <a.p.zijlstra@chello.nl>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Steven Rostedt <srostedt@redhat.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Jens Axboe <jens.axboe@oracle.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+LKML-Reference: <new-submission>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..d2a3b9d
--- /dev/null
@@ -0,0 +1,82 @@
+From f3d83e2415445e5b157bef404d38674e9e8de169 Mon Sep 17 00:00:00 2001
+From: Costantino Leandro <lcostantino@gmail.com>
+Date: Wed, 26 Aug 2009 14:29:28 -0700
+Subject: wmi: fix kernel panic when stack protection enabled.
+
+From: Costantino Leandro <lcostantino@gmail.com>
+
+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:
+           [<c04a6c40>] ? panic+0x45/0xd9
+          [<c012925d>] ? __stack_chk_fail+0x1c/0x40
+          [<fa7b182c>] ? wmi_query_block+0x15a/0x162 [wmi]
+          [<fa7b182c>] ? wmi_query_block+0x15a/0x162 [wmi]
+          [<fa7e7000>] ? acer_wmi_init+0x00/0x61a [acer_wmi]
+          [<fa7e7135>] ? acer_wmi_init+0x135/0x61a [acer_wmi]
+          [<c0101159>] ? do_one_initcall+0x50+0x126
+
+Addresses http://bugzilla.kernel.org/show_bug.cgi?id=13514
+
+Signed-off-by: Costantino Leandro <lcostantino@gmail.com>
+Signed-off-by: Carlos Corbacho <carlos@strangeworlds.co.uk>
+Cc: Len Brown <len.brown@intel.com>
+Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
+Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
+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@suse.de>
+
+---
+ 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 (file)
index 0000000..4e844e9
--- /dev/null
@@ -0,0 +1,81 @@
+From b04e6373d694e977c95ae0ae000e2c1e2cf92d73 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+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 <torvalds@linux-foundation.org>
+
+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 <thomas.bjornell@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..49dd859
--- /dev/null
@@ -0,0 +1,53 @@
+From 83d349f35e1ae72268c5104dbf9ab2ae635425d4 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+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 <torvalds@linux-foundation.org>
+
+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 <wylda@volny.cz>
+Reported-and-tested-by: Thomas Björnell <thomas.bjornell@gmail.com>
+Reported-and-tested-by: Martin Rogge <marogge@onlinehome.de>
+Cc: Mike Travis <travis@sgi.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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);