]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.25 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 16 Oct 2008 17:41:55 +0000 (10:41 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 16 Oct 2008 17:41:55 +0000 (10:41 -0700)
queue-2.6.25/b43legacy-fix-failure-in-rate-adjustment-mechanism.patch [new file with mode: 0644]
queue-2.6.25/cifs-make-sure-we-have-the-right-resume-info-before-calling-cifsfindnext.patch [new file with mode: 0644]
queue-2.6.25/sched_rt.c-resch-needed-in-rt_rq_enqueue-for-the-root-rt_rq.patch [new file with mode: 0644]
queue-2.6.25/series [new file with mode: 0644]
queue-2.6.25/tty-termios-locking-sort-out-real_tty-confusions-and-lock-reads.patch [new file with mode: 0644]
queue-2.6.25/x86-early_ioremap-fix-fencepost-error.patch [new file with mode: 0644]
queue-2.6.25/x86-improve-up-kernel-when-cpu-hotplug-and-smp-is-enabled.patch [new file with mode: 0644]
queue-2.6.25/x86-reserve-first_device_vector-in-used_vectors-bitmap.patch [new file with mode: 0644]

diff --git a/queue-2.6.25/b43legacy-fix-failure-in-rate-adjustment-mechanism.patch b/queue-2.6.25/b43legacy-fix-failure-in-rate-adjustment-mechanism.patch
new file mode 100644 (file)
index 0000000..d6bcc02
--- /dev/null
@@ -0,0 +1,36 @@
+From jejb@kernel.org  Wed Oct 15 14:41:06 2008
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sat, 11 Oct 2008 16:55:21 GMT
+Subject: b43legacy: Fix failure in rate-adjustment mechanism
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810111655.m9BGtL1M013741@hera.kernel.org>
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit c6a2afdacccd56cc0be8e9a7977f0ed1509069f6 upstream
+Date: Sat, 6 Sep 2008 16:51:22 -0500
+Subject: b43legacy: Fix failure in rate-adjustment mechanism
+
+A coding error present since b43legacy was incorporated into the
+kernel has prevented the driver from using the rate-setting mechanism
+of mac80211. The driver has been forced to remain at a 1 Mb/s rate.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/b43legacy/xmit.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/b43legacy/xmit.c
++++ b/drivers/net/wireless/b43legacy/xmit.c
+@@ -624,7 +624,7 @@ void b43legacy_handle_hwtxstatus(struct 
+       tmp = hw->count;
+       status.frame_count = (tmp >> 4);
+       status.rts_count = (tmp & 0x0F);
+-      tmp = hw->flags;
++      tmp = hw->flags << 1;
+       status.supp_reason = ((tmp & 0x1C) >> 2);
+       status.pm_indicated = !!(tmp & 0x80);
+       status.intermediate = !!(tmp & 0x40);
diff --git a/queue-2.6.25/cifs-make-sure-we-have-the-right-resume-info-before-calling-cifsfindnext.patch b/queue-2.6.25/cifs-make-sure-we-have-the-right-resume-info-before-calling-cifsfindnext.patch
new file mode 100644 (file)
index 0000000..7e8ed96
--- /dev/null
@@ -0,0 +1,215 @@
+From jejb@kernel.org  Wed Oct 15 14:35:35 2008
+From: Steve French <sfrench@us.ibm.com>
+Date: Sat, 11 Oct 2008 16:55:11 GMT
+Subject: CIFS: make sure we have the right resume info before calling CIFSFindNext
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810111655.m9BGtBTL013214@hera.kernel.org>
+
+From: Steve French <sfrench@us.ibm.com>
+
+commit 0752f1522a9120f731232919f7ad904e9e22b8ce upstream
+
+When we do a seekdir() or equivalent, we usually end up doing a
+FindFirst call and then call FindNext until we get to the offset that we
+want. The problem is that when we call FindNext, the code usually
+doesn't have the proper info (mostly, the filename of the entry from the
+last search) to resume the search.
+
+Add a "last_entry" field to the cifs_search_info that points to the last
+entry in the search. We calculate this pointer by using the
+LastNameOffset field from the search parms that are returned. We then
+use that info to do a cifs_save_resume_key before we call CIFSFindNext.
+
+This patch allows CIFS to reliably pass the "telldir" connectathon test.
+
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/cifs/cifsglob.h |    1 
+ fs/cifs/cifssmb.c  |    4 +
+ fs/cifs/readdir.c  |  128 ++++++++++++++++++++++++++---------------------------
+ 3 files changed, 70 insertions(+), 63 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -315,6 +315,7 @@ struct cifs_search_info {
+       __u32 resume_key;
+       char *ntwrk_buf_start;
+       char *srch_entries_start;
++      char *last_entry;
+       char *presume_name;
+       unsigned int resume_name_len;
+       unsigned endOfSearch:1;
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -3598,6 +3598,8 @@ findFirstRetry:
+                                       le16_to_cpu(parms->SearchCount);
+                       psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
+                               psrch_inf->entries_in_buffer;
++                      psrch_inf->last_entry = psrch_inf->srch_entries_start +
++                                      le16_to_cpu(parms->LastNameOffset);
+                       *pnetfid = parms->SearchHandle;
+               } else {
+                       cifs_buf_release(pSMB);
+@@ -3712,6 +3714,8 @@ int CIFSFindNext(const int xid, struct c
+                                               le16_to_cpu(parms->SearchCount);
+                       psrch_inf->index_of_last_entry +=
+                               psrch_inf->entries_in_buffer;
++                      psrch_inf->last_entry = psrch_inf->srch_entries_start +
++                                      le16_to_cpu(parms->LastNameOffset);
+ /*  cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
+           psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -633,6 +633,70 @@ static int is_dir_changed(struct file *f
+ }
++static int cifs_save_resume_key(const char *current_entry,
++      struct cifsFileInfo *cifsFile)
++{
++      int rc = 0;
++      unsigned int len = 0;
++      __u16 level;
++      char *filename;
++
++      if ((cifsFile == NULL) || (current_entry == NULL))
++              return -EINVAL;
++
++      level = cifsFile->srch_inf.info_level;
++
++      if (level == SMB_FIND_FILE_UNIX) {
++              FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
++
++              filename = &pFindData->FileName[0];
++              if (cifsFile->srch_inf.unicode) {
++                      len = cifs_unicode_bytelen(filename);
++              } else {
++                      /* BB should we make this strnlen of PATH_MAX? */
++                      len = strnlen(filename, PATH_MAX);
++              }
++              cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
++      } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
++              FILE_DIRECTORY_INFO *pFindData =
++                      (FILE_DIRECTORY_INFO *)current_entry;
++              filename = &pFindData->FileName[0];
++              len = le32_to_cpu(pFindData->FileNameLength);
++              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++      } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
++              FILE_FULL_DIRECTORY_INFO *pFindData =
++                      (FILE_FULL_DIRECTORY_INFO *)current_entry;
++              filename = &pFindData->FileName[0];
++              len = le32_to_cpu(pFindData->FileNameLength);
++              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++      } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
++              SEARCH_ID_FULL_DIR_INFO *pFindData =
++                      (SEARCH_ID_FULL_DIR_INFO *)current_entry;
++              filename = &pFindData->FileName[0];
++              len = le32_to_cpu(pFindData->FileNameLength);
++              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++      } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
++              FILE_BOTH_DIRECTORY_INFO *pFindData =
++                      (FILE_BOTH_DIRECTORY_INFO *)current_entry;
++              filename = &pFindData->FileName[0];
++              len = le32_to_cpu(pFindData->FileNameLength);
++              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++      } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
++              FIND_FILE_STANDARD_INFO *pFindData =
++                      (FIND_FILE_STANDARD_INFO *)current_entry;
++              filename = &pFindData->FileName[0];
++              /* one byte length, no name conversion */
++              len = (unsigned int)pFindData->FileNameLength;
++              cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
++      } else {
++              cFYI(1, ("Unknown findfirst level %d", level));
++              return -EINVAL;
++      }
++      cifsFile->srch_inf.resume_name_len = len;
++      cifsFile->srch_inf.presume_name = filename;
++      return rc;
++}
++
+ /* find the corresponding entry in the search */
+ /* Note that the SMB server returns search entries for . and .. which
+    complicates logic here if we choose to parse for them and we do not
+@@ -694,6 +758,7 @@ static int find_cifs_entry(const int xid
+       while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
+             (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) {
+               cFYI(1, ("calling findnext2"));
++              cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+               rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
+                                 &cifsFile->srch_inf);
+               if (rc)
+@@ -910,69 +975,6 @@ static int cifs_filldir(char *pfindEntry
+       return rc;
+ }
+-static int cifs_save_resume_key(const char *current_entry,
+-      struct cifsFileInfo *cifsFile)
+-{
+-      int rc = 0;
+-      unsigned int len = 0;
+-      __u16 level;
+-      char *filename;
+-
+-      if ((cifsFile == NULL) || (current_entry == NULL))
+-              return -EINVAL;
+-
+-      level = cifsFile->srch_inf.info_level;
+-
+-      if (level == SMB_FIND_FILE_UNIX) {
+-              FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
+-
+-              filename = &pFindData->FileName[0];
+-              if (cifsFile->srch_inf.unicode) {
+-                      len = cifs_unicode_bytelen(filename);
+-              } else {
+-                      /* BB should we make this strnlen of PATH_MAX? */
+-                      len = strnlen(filename, PATH_MAX);
+-              }
+-              cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
+-      } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
+-              FILE_DIRECTORY_INFO *pFindData =
+-                      (FILE_DIRECTORY_INFO *)current_entry;
+-              filename = &pFindData->FileName[0];
+-              len = le32_to_cpu(pFindData->FileNameLength);
+-              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+-      } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
+-              FILE_FULL_DIRECTORY_INFO *pFindData =
+-                      (FILE_FULL_DIRECTORY_INFO *)current_entry;
+-              filename = &pFindData->FileName[0];
+-              len = le32_to_cpu(pFindData->FileNameLength);
+-              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+-      } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
+-              SEARCH_ID_FULL_DIR_INFO *pFindData =
+-                      (SEARCH_ID_FULL_DIR_INFO *)current_entry;
+-              filename = &pFindData->FileName[0];
+-              len = le32_to_cpu(pFindData->FileNameLength);
+-              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+-      } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
+-              FILE_BOTH_DIRECTORY_INFO *pFindData =
+-                      (FILE_BOTH_DIRECTORY_INFO *)current_entry;
+-              filename = &pFindData->FileName[0];
+-              len = le32_to_cpu(pFindData->FileNameLength);
+-              cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+-      } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
+-              FIND_FILE_STANDARD_INFO *pFindData =
+-                      (FIND_FILE_STANDARD_INFO *)current_entry;
+-              filename = &pFindData->FileName[0];
+-              /* one byte length, no name conversion */
+-              len = (unsigned int)pFindData->FileNameLength;
+-              cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
+-      } else {
+-              cFYI(1, ("Unknown findfirst level %d", level));
+-              return -EINVAL;
+-      }
+-      cifsFile->srch_inf.resume_name_len = len;
+-      cifsFile->srch_inf.presume_name = filename;
+-      return rc;
+-}
+ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
+ {
diff --git a/queue-2.6.25/sched_rt.c-resch-needed-in-rt_rq_enqueue-for-the-root-rt_rq.patch b/queue-2.6.25/sched_rt.c-resch-needed-in-rt_rq_enqueue-for-the-root-rt_rq.patch
new file mode 100644 (file)
index 0000000..c702a65
--- /dev/null
@@ -0,0 +1,66 @@
+From jejb@kernel.org  Wed Oct 15 14:19:33 2008
+From: Dario Faggioli <raistlin@linux.it>
+Date: Fri, 10 Oct 2008 20:15:02 GMT
+Subject: sched_rt.c: resch needed in rt_rq_enqueue() for the root rt_rq
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810102015.m9AKF27B014753@hera.kernel.org>
+
+From: Dario Faggioli <raistlin@linux.it>
+
+commit f6121f4f8708195e88cbdf8dd8d171b226b3f858 upstream
+
+While working on the new version of the code for SCHED_SPORADIC I
+noticed something strange in the present throttling mechanism. More
+specifically in the throttling timer handler in sched_rt.c
+(do_sched_rt_period_timer()) and in rt_rq_enqueue().
+
+The problem is that, when unthrottling a runqueue, rt_rq_enqueue() only
+asks for rescheduling if the runqueue has a sched_entity associated to
+it (i.e., rt_rq->rt_se != NULL).
+Now, if the runqueue is the root rq (which has a rt_se = NULL)
+rescheduling does not take place, and it is delayed to some undefined
+instant in the future.
+
+This imply some random bandwidth usage by the RT tasks under throttling.
+For instance, setting rt_runtime_us/rt_period_us = 950ms/1000ms an RT
+task will get less than 95%. In our tests we got something varying
+between 70% to 95%.
+Using smaller time values, e.g., 95ms/100ms, things are even worse, and
+I can see values also going down to 20-25%!!
+
+The tests we performed are simply running 'yes' as a SCHED_FIFO task,
+and checking the CPU usage with top, but we can investigate thoroughly
+if you think it is needed.
+
+Things go much better, for us, with the attached patch... Don't know if
+it is the best approach, but it solved the issue for us.
+
+Signed-off-by: Dario Faggioli <raistlin@linux.it>
+Signed-off-by: Michael Trimarchi <trimarchimichael@yahoo.it>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/sched_rt.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/kernel/sched_rt.c
++++ b/kernel/sched_rt.c
+@@ -91,12 +91,12 @@ static void dequeue_rt_entity(struct sch
+ static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
+ {
++      struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
+       struct sched_rt_entity *rt_se = rt_rq->rt_se;
+-      if (rt_se && !on_rt_rq(rt_se) && rt_rq->rt_nr_running) {
+-              struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
+-
+-              enqueue_rt_entity(rt_se);
++      if (rt_rq->rt_nr_running) {
++              if (rt_se && !on_rt_rq(rt_se))
++                      enqueue_rt_entity(rt_se);
+               if (rt_rq->highest_prio < curr->prio)
+                       resched_task(curr);
+       }
diff --git a/queue-2.6.25/series b/queue-2.6.25/series
new file mode 100644 (file)
index 0000000..bb0f6eb
--- /dev/null
@@ -0,0 +1,7 @@
+x86-reserve-first_device_vector-in-used_vectors-bitmap.patch
+x86-improve-up-kernel-when-cpu-hotplug-and-smp-is-enabled.patch
+x86-early_ioremap-fix-fencepost-error.patch
+tty-termios-locking-sort-out-real_tty-confusions-and-lock-reads.patch
+sched_rt.c-resch-needed-in-rt_rq_enqueue-for-the-root-rt_rq.patch
+cifs-make-sure-we-have-the-right-resume-info-before-calling-cifsfindnext.patch
+b43legacy-fix-failure-in-rate-adjustment-mechanism.patch
diff --git a/queue-2.6.25/tty-termios-locking-sort-out-real_tty-confusions-and-lock-reads.patch b/queue-2.6.25/tty-termios-locking-sort-out-real_tty-confusions-and-lock-reads.patch
new file mode 100644 (file)
index 0000000..7814750
--- /dev/null
@@ -0,0 +1,33 @@
+From 8f520021837d45c47d0ab57e7271f8d88bf7f3a4 Mon Sep 17 00:00:00 2001
+From: Alan Cox <alan@redhat.com>
+Date: Mon, 13 Oct 2008 10:38:46 +0100
+Subject: tty: Termios locking - sort out real_tty confusions and lock reads
+
+From: Alan Cox <alan@redhat.com>
+
+commit 8f520021837d45c47d0ab57e7271f8d88bf7f3a4 upstream
+
+(only the tty_io.c portion of this commit)
+
+This moves us towards sanity and should mean our termios locking is now
+complete and comprehensive.
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_io.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -3373,7 +3373,7 @@ int tty_ioctl(struct inode *inode, struc
+       case TIOCSTI:
+               return tiocsti(tty, p);
+       case TIOCGWINSZ:
+-              return tiocgwinsz(tty, p);
++              return tiocgwinsz(real_tty, p);
+       case TIOCSWINSZ:
+               return tiocswinsz(tty, real_tty, p);
+       case TIOCCONS:
diff --git a/queue-2.6.25/x86-early_ioremap-fix-fencepost-error.patch b/queue-2.6.25/x86-early_ioremap-fix-fencepost-error.patch
new file mode 100644 (file)
index 0000000..905c3f1
--- /dev/null
@@ -0,0 +1,46 @@
+From jejb@kernel.org  Wed Oct 15 14:42:49 2008
+From: Alan Cox <alan@redhat.com>
+Date: Sun, 12 Oct 2008 19:40:08 GMT
+Subject: x86, early_ioremap: fix fencepost error
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810121940.m9CJe8k3024539@hera.kernel.org>
+
+From: Alan Cox <alan@redhat.com>
+
+commit c613ec1a7ff3714da11c7c48a13bab03beb5c376 upstream
+
+The x86 implementation of early_ioremap has an off by one error. If we get
+an object which ends on the first byte of a page we undermap by one page and
+this causes a crash on boot with the ASUS P5QL whose DMI table happens to fit
+this alignment.
+
+The size computation is currently
+
+       last_addr = phys_addr + size - 1;
+       npages = (PAGE_ALIGN(last_addr) - phys_addr)
+
+(Consider a request for 1 byte at alignment 0...)
+
+Closes #11693
+
+Debugging work by Ian Campbell/Felix Geyer
+
+Signed-off-by: Alan Cox <alan@rehat.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/mm/ioremap.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -438,7 +438,7 @@ void __init *early_ioremap(unsigned long
+        */
+       offset = phys_addr & ~PAGE_MASK;
+       phys_addr &= PAGE_MASK;
+-      size = PAGE_ALIGN(last_addr) - phys_addr;
++      size = PAGE_ALIGN(last_addr + 1) - phys_addr;
+       /*
+        * Mappings have to fit in the FIX_BTMAP area.
diff --git a/queue-2.6.25/x86-improve-up-kernel-when-cpu-hotplug-and-smp-is-enabled.patch b/queue-2.6.25/x86-improve-up-kernel-when-cpu-hotplug-and-smp-is-enabled.patch
new file mode 100644 (file)
index 0000000..1c1cce4
--- /dev/null
@@ -0,0 +1,36 @@
+From jejb@kernel.org  Wed Oct 15 14:45:08 2008
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Mon, 13 Oct 2008 17:15:23 GMT
+Subject: x86: improve UP kernel when CPU-hotplug and SMP is enabled
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810131715.m9DHFNoT025122@hera.kernel.org>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 649c6653fa94ec8f3ea32b19c97b790ec4e8e4ac upstream
+
+num_possible_cpus() can be > 1 when disabled CPUs have been accounted.
+
+Disabled CPUs are not in the cpu_present_map, so we can use
+num_present_cpus() as a safe indicator to switch to UP alternatives.
+
+Reported-by: Chuck Ebbert <cebbert@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/alternative.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -457,7 +457,7 @@ void __init alternative_instructions(voi
+                                           _text, _etext);
+               /* Only switch to UP mode if we don't immediately boot others */
+-              if (num_possible_cpus() == 1 || setup_max_cpus <= 1)
++              if (num_present_cpus() == 1 || setup_max_cpus <= 1)
+                       alternatives_smp_switch(0);
+       }
+ #endif
diff --git a/queue-2.6.25/x86-reserve-first_device_vector-in-used_vectors-bitmap.patch b/queue-2.6.25/x86-reserve-first_device_vector-in-used_vectors-bitmap.patch
new file mode 100644 (file)
index 0000000..1c1e483
--- /dev/null
@@ -0,0 +1,43 @@
+From a272a28f520c58a84853e098b4ee565486ca5062 Mon Sep 17 00:00:00 2001
+From: Stefan Bader <stefan.bader@canonical.com>
+Date: Sat, 27 Sep 2008 11:07:30 -0400
+Subject: x86: Reserve FIRST_DEVICE_VECTOR in used_vectors bitmap.
+
+From: Stefan Bader <stefan.bader@canonical.com>
+
+Not in upstream above 2.6.27 due to change in the way this code works
+(has been fixed differently there.)
+
+Someone from the community found out, that after repeatedly unloading
+and loading a device driver that uses MSI IRQs, the system eventually
+assigned the vector initially reserved for IRQ0 to the device driver.
+
+The reason for this is, that although IRQ0 is tied to the
+FIRST_DEVICE_VECTOR when declaring the irq_vector table, the
+corresponding bit in the used_vectors map is not set. So, if vectors are
+released and assigned often enough, the vector will get assigned to
+another interrupt. This happens more often with MSI interrupts as those
+are exclusively using a vector.
+
+Fix this by setting the bit for the FIRST_DEVICE_VECTOR in the bitmap.
+
+Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
+Acked-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/io_apic_32.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/x86/kernel/io_apic_32.c
++++ b/arch/x86/kernel/io_apic_32.c
+@@ -2305,6 +2305,9 @@ void __init setup_IO_APIC(void)
+       for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++)
+               set_bit(i, used_vectors);
++      /* Mark FIRST_DEVICE_VECTOR which is assigned to IRQ0 as used. */
++      set_bit(FIRST_DEVICE_VECTOR, used_vectors);
++
+       enable_IO_APIC();
+       if (acpi_ioapic)