]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.28 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 18 Feb 2009 17:58:41 +0000 (09:58 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 18 Feb 2009 17:58:41 +0000 (09:58 -0800)
queue-2.6.28/3c505-do-not-set-pcb-data.raw-beyond-its-size.patch [new file with mode: 0644]
queue-2.6.28/add-support-for-vt6415-pcie-pata-ide-host-controller.patch [new file with mode: 0644]
queue-2.6.28/bluetooth-fix-tx-error-path-in-btsdio-driver.patch [new file with mode: 0644]
queue-2.6.28/ext2-xip-refuse-to-change-xip-flag-during-remount-with-busy-inodes.patch [new file with mode: 0644]
queue-2.6.28/sched-sched_other-vs-sched_idle-isolation.patch [new file with mode: 0644]
queue-2.6.28/scsi-libiscsi-fix-iscsi-pool-leak.patch [new file with mode: 0644]
queue-2.6.28/series
queue-2.6.28/x86-cpa-make-sure-cpa-is-safe-to-call-in-lazy-mmu-mode.patch [new file with mode: 0644]
queue-2.6.28/x86-vm86-fix-preemption-bug.patch [new file with mode: 0644]

diff --git a/queue-2.6.28/3c505-do-not-set-pcb-data.raw-beyond-its-size.patch b/queue-2.6.28/3c505-do-not-set-pcb-data.raw-beyond-its-size.patch
new file mode 100644 (file)
index 0000000..a8b0da2
--- /dev/null
@@ -0,0 +1,60 @@
+From 501aa061bd68169a5b54c123641f8dfa9ad31545 Mon Sep 17 00:00:00 2001
+From: Roel Kluin <roel.kluin@gmail.com>
+Date: Thu, 12 Feb 2009 16:52:31 -0800
+Subject: 3c505: do not set pcb->data.raw beyond its size
+
+From: Roel Kluin <roel.kluin@gmail.com>
+
+commit 501aa061bd68169a5b54c123641f8dfa9ad31545 upstream.
+
+Ensure that we do not set pcb->data.raw beyond its size, print an error message
+and return false if we attempt to. A timout message was printed one too early.
+
+Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/3c505.c |   26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/3c505.c
++++ b/drivers/net/3c505.c
+@@ -493,21 +493,27 @@ static bool receive_pcb(struct net_devic
+       }
+       /* read the data */
+       spin_lock_irqsave(&adapter->lock, flags);
+-      i = 0;
+-      do {
+-              j = 0;
+-              while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000);
+-              pcb->data.raw[i++] = inb_command(dev->base_addr);
+-              if (i > MAX_PCB_DATA)
+-                      INVALID_PCB_MSG(i);
+-      } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000);
++      for (i = 0; i < MAX_PCB_DATA; i++) {
++              for (j = 0; j < 20000; j++) {
++                      stat = get_status(dev->base_addr);
++                      if (stat & ACRF)
++                              break;
++              }
++              pcb->data.raw[i] = inb_command(dev->base_addr);
++              if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000)
++                      break;
++      }
+       spin_unlock_irqrestore(&adapter->lock, flags);
++      if (i >= MAX_PCB_DATA) {
++              INVALID_PCB_MSG(i);
++              return false;
++      }
+       if (j >= 20000) {
+               TIMEOUT_MSG(__LINE__);
+               return false;
+       }
+-      /* woops, the last "data" byte was really the length! */
+-      total_length = pcb->data.raw[--i];
++      /* the last "data" byte was really the length! */
++      total_length = pcb->data.raw[i];
+       /* safety check total length vs data length */
+       if (total_length != (pcb->length + 2)) {
diff --git a/queue-2.6.28/add-support-for-vt6415-pcie-pata-ide-host-controller.patch b/queue-2.6.28/add-support-for-vt6415-pcie-pata-ide-host-controller.patch
new file mode 100644 (file)
index 0000000..fd123b8
--- /dev/null
@@ -0,0 +1,48 @@
+From 5955c7a2cfb6a35429adea5dc480002b15ca8cfc Mon Sep 17 00:00:00 2001
+From: Zlatko Calusic <zlatko.calusic@iskon.hr>
+Date: Wed, 18 Feb 2009 01:33:34 +0100
+Subject: Add support for VT6415 PCIE PATA IDE Host Controller
+
+From: Zlatko Calusic <zlatko.calusic@iskon.hr>
+
+commit 5955c7a2cfb6a35429adea5dc480002b15ca8cfc upstream.
+
+Signed-off-by: Zlatko Calusic <zlatko.calusic@iskon.hr>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/pata_via.c  |    4 +++-
+ include/linux/pci_ids.h |    1 +
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/ata/pata_via.c
++++ b/drivers/ata/pata_via.c
+@@ -110,7 +110,8 @@ static const struct via_isa_bridge {
+       { "vt8237s",    PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+       { "vt8251",     PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+       { "cx700",      PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
+-      { "vt6410",     PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
++      { "vt6410",     PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
++      { "vt6415",     PCI_DEVICE_ID_VIA_6415,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
+       { "vt8237a",    PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+       { "vt8237",     PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+       { "vt8235",     PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+@@ -593,6 +594,7 @@ static int via_reinit_one(struct pci_dev
+ #endif
+ static const struct pci_device_id via[] = {
++      { PCI_VDEVICE(VIA, 0x0415), },
+       { PCI_VDEVICE(VIA, 0x0571), },
+       { PCI_VDEVICE(VIA, 0x0581), },
+       { PCI_VDEVICE(VIA, 0x1571), },
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -1312,6 +1312,7 @@
+ #define PCI_DEVICE_ID_VIA_VT3351      0x0351
+ #define PCI_DEVICE_ID_VIA_VT3364      0x0364
+ #define PCI_DEVICE_ID_VIA_8371_0      0x0391
++#define PCI_DEVICE_ID_VIA_6415                0x0415
+ #define PCI_DEVICE_ID_VIA_8501_0      0x0501
+ #define PCI_DEVICE_ID_VIA_82C561      0x0561
+ #define PCI_DEVICE_ID_VIA_82C586_1    0x0571
diff --git a/queue-2.6.28/bluetooth-fix-tx-error-path-in-btsdio-driver.patch b/queue-2.6.28/bluetooth-fix-tx-error-path-in-btsdio-driver.patch
new file mode 100644 (file)
index 0000000..51a01fd
--- /dev/null
@@ -0,0 +1,30 @@
+From 7644d63d1348ec044ccd8f775fefe5eb7cbcac69 Mon Sep 17 00:00:00 2001
+From: Tomas Winkler <tomas.winkler@intel.com>
+Date: Sun, 30 Nov 2008 12:17:18 +0100
+Subject: Bluetooth: Fix TX error path in btsdio driver
+
+From: Tomas Winkler <tomas.winkler@intel.com>
+
+commit 7644d63d1348ec044ccd8f775fefe5eb7cbcac69 upstream.
+
+This patch fixes accumulating of the header in case packet was requeued
+in the error path.
+
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/bluetooth/btsdio.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/bluetooth/btsdio.c
++++ b/drivers/bluetooth/btsdio.c
+@@ -91,6 +91,7 @@ static int btsdio_tx_packet(struct btsdi
+       err = sdio_writesb(data->func, REG_TDAT, skb->data, skb->len);
+       if (err < 0) {
++              skb_pull(skb, 4);
+               sdio_writeb(data->func, 0x01, REG_PC_WRT, NULL);
+               return err;
+       }
diff --git a/queue-2.6.28/ext2-xip-refuse-to-change-xip-flag-during-remount-with-busy-inodes.patch b/queue-2.6.28/ext2-xip-refuse-to-change-xip-flag-during-remount-with-busy-inodes.patch
new file mode 100644 (file)
index 0000000..e2eb856
--- /dev/null
@@ -0,0 +1,70 @@
+From 0e4a9b59282914fe057ab17027f55123964bc2e2 Mon Sep 17 00:00:00 2001
+From: Carsten Otte <cotte@de.ibm.com>
+Date: Wed, 11 Feb 2009 13:04:37 -0800
+Subject: ext2/xip: refuse to change xip flag during remount with busy inodes
+
+From: Carsten Otte <cotte@de.ibm.com>
+
+commit 0e4a9b59282914fe057ab17027f55123964bc2e2 upstream.
+
+For a reason that I was unable to understand in three months of debugging,
+mount ext2 -o remount stopped working properly when remounting from
+regular operation to xip, or the other way around.  According to a git
+bisect search, the problem was introduced with the VM_MIXEDMAP/PTE_SPECIAL
+rework in the vm:
+
+commit 70688e4dd1647f0ceb502bbd5964fa344c5eb411
+Author: Nick Piggin <npiggin@suse.de>
+Date:   Mon Apr 28 02:13:02 2008 -0700
+
+    xip: support non-struct page backed memory
+
+In the failing scenario, the filesystem is mounted read only via root=
+kernel parameter on s390x.  During remount (in rc.sysinit), the inodes of
+the bash binary and its libraries are busy and cannot be invalidated (the
+bash which is running rc.sysinit resides on subject filesystem).
+Afterwards, another bash process (running ifup-eth) recurses into a
+subshell, runs dup_mm (via fork).  Some of the mappings in this bash
+process were created from inodes that could not be invalidated during
+remount.
+
+Both parent and child process crash some time later due to inconsistencies
+in their address spaces.  The issue seems to be timing sensitive, various
+attempts to recreate it have failed.
+
+This patch refuses to change the xip flag during remount in case some
+inodes cannot be invalidated.  This patch keeps users from running into
+that issue.
+
+[akpm@linux-foundation.org: cleanup]
+Signed-off-by: Carsten Otte <cotte@de.ibm.com>
+Cc: Nick Piggin <npiggin@suse.de>
+Cc: Jared Hulbert <jaredeh@gmail.com>
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.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>
+
+---
+ fs/ext2/super.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -1177,9 +1177,12 @@ static int ext2_remount (struct super_bl
+       es = sbi->s_es;
+       if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) !=
+           (old_mount_opt & EXT2_MOUNT_XIP)) &&
+-          invalidate_inodes(sb))
+-              ext2_warning(sb, __func__, "busy inodes while remounting "\
+-                           "xip remain in cache (no functional problem)");
++          invalidate_inodes(sb)) {
++              ext2_warning(sb, __func__, "refusing change of xip flag "
++                           "with busy inodes while remounting");
++              sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
++              sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
++      }
+       if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+               return 0;
+       if (*flags & MS_RDONLY) {
diff --git a/queue-2.6.28/sched-sched_other-vs-sched_idle-isolation.patch b/queue-2.6.28/sched-sched_other-vs-sched_idle-isolation.patch
new file mode 100644 (file)
index 0000000..57d2098
--- /dev/null
@@ -0,0 +1,87 @@
+From 6bc912b71b6f33b041cfde93ca3f019cbaa852bc Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Date: Thu, 15 Jan 2009 14:53:38 +0100
+Subject: sched: SCHED_OTHER vs SCHED_IDLE isolation
+
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+
+commit 6bc912b71b6f33b041cfde93ca3f019cbaa852bc upstream.
+
+Stronger SCHED_IDLE isolation:
+
+ - no SCHED_IDLE buddies
+ - never let SCHED_IDLE preempt on wakeup
+ - always preempt SCHED_IDLE on wakeup
+ - limit SLEEPER fairness for SCHED_IDLE.
+
+Signed-off-by: Mike Galbraith <efault@gmx.de>
+Signed-off-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_fair.c |   30 ++++++++++++++++++++++--------
+ 1 file changed, 22 insertions(+), 8 deletions(-)
+
+--- a/kernel/sched_fair.c
++++ b/kernel/sched_fair.c
+@@ -681,9 +681,13 @@ place_entity(struct cfs_rq *cfs_rq, stru
+                       unsigned long thresh = sysctl_sched_latency;
+                       /*
+-                       * convert the sleeper threshold into virtual time
++                       * Convert the sleeper threshold into virtual time.
++                       * SCHED_IDLE is a special sub-class.  We care about
++                       * fairness only relative to other SCHED_IDLE tasks,
++                       * all of which have the same weight.
+                        */
+-                      if (sched_feat(NORMALIZED_SLEEPER))
++                      if (sched_feat(NORMALIZED_SLEEPER) &&
++                                      task_of(se)->policy != SCHED_IDLE)
+                               thresh = calc_delta_fair(thresh, se);
+                       vruntime -= thresh;
+@@ -1328,14 +1332,18 @@ wakeup_preempt_entity(struct sched_entit
+ static void set_last_buddy(struct sched_entity *se)
+ {
+-      for_each_sched_entity(se)
+-              cfs_rq_of(se)->last = se;
++      if (likely(task_of(se)->policy != SCHED_IDLE)) {
++              for_each_sched_entity(se)
++                      cfs_rq_of(se)->last = se;
++      }
+ }
+ static void set_next_buddy(struct sched_entity *se)
+ {
+-      for_each_sched_entity(se)
+-              cfs_rq_of(se)->next = se;
++      if (likely(task_of(se)->policy != SCHED_IDLE)) {
++              for_each_sched_entity(se)
++                      cfs_rq_of(se)->next = se;
++      }
+ }
+ /*
+@@ -1382,12 +1390,18 @@ static void check_preempt_wakeup(struct 
+               return;
+       /*
+-       * Batch tasks do not preempt (their preemption is driven by
++       * Batch and idle tasks do not preempt (their preemption is driven by
+        * the tick):
+        */
+-      if (unlikely(p->policy == SCHED_BATCH))
++      if (unlikely(p->policy != SCHED_NORMAL))
+               return;
++      /* Idle tasks are by definition preempted by everybody. */
++      if (unlikely(curr->policy == SCHED_IDLE)) {
++              resched_task(curr);
++              return;
++      }
++
+       if (!sched_feat(WAKEUP_PREEMPT))
+               return;
diff --git a/queue-2.6.28/scsi-libiscsi-fix-iscsi-pool-leak.patch b/queue-2.6.28/scsi-libiscsi-fix-iscsi-pool-leak.patch
new file mode 100644 (file)
index 0000000..de3b596
--- /dev/null
@@ -0,0 +1,34 @@
+From 2f5899a39dcffb404c9a3d06ad438aff3e03bf04 Mon Sep 17 00:00:00 2001
+From: Mike Christie <michaelc@cs.wisc.edu>
+Date: Fri, 16 Jan 2009 12:36:51 -0600
+Subject: SCSI: libiscsi: fix iscsi pool leak
+
+From: Mike Christie <michaelc@cs.wisc.edu>
+
+commit 2f5899a39dcffb404c9a3d06ad438aff3e03bf04 upstream.
+
+I am not sure what happened. It looks like we have always leaked
+the q->queue that is allocated from the kfifo_init call. nab finally
+noticed that we were leaking and this patch fixes it by adding a
+kfree call to iscsi_pool_free. kfifo_free is not used per kfifo_init's
+instructions to use kfree.
+
+Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Cc: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/libiscsi.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -1899,6 +1899,7 @@ void iscsi_pool_free(struct iscsi_pool *
+               kfree(q->pool[i]);
+       if (q->pool)
+               kfree(q->pool);
++      kfree(q->queue);
+ }
+ EXPORT_SYMBOL_GPL(iscsi_pool_free);
index 99790116741abac7b3c97981b2e2576f084b82c8..bcc05471cab5ddeee7924a2a65926b3aa233d6d3 100644 (file)
@@ -4,3 +4,11 @@ watchdog-itco_wdt-fix-smi_en-regression-2.patch
 powerpc-vsx-fix-vsx-alignment-handler-for-regs-32-63.patch
 sata_nv-give-up-hardreset-on-nf2.patch
 fix-intel-iommu-write-buffer-flushing.patch
+scsi-libiscsi-fix-iscsi-pool-leak.patch
+x86-cpa-make-sure-cpa-is-safe-to-call-in-lazy-mmu-mode.patch
+sched-sched_other-vs-sched_idle-isolation.patch
+x86-vm86-fix-preemption-bug.patch
+add-support-for-vt6415-pcie-pata-ide-host-controller.patch
+ext2-xip-refuse-to-change-xip-flag-during-remount-with-busy-inodes.patch
+3c505-do-not-set-pcb-data.raw-beyond-its-size.patch
+bluetooth-fix-tx-error-path-in-btsdio-driver.patch
diff --git a/queue-2.6.28/x86-cpa-make-sure-cpa-is-safe-to-call-in-lazy-mmu-mode.patch b/queue-2.6.28/x86-cpa-make-sure-cpa-is-safe-to-call-in-lazy-mmu-mode.patch
new file mode 100644 (file)
index 0000000..2f566fa
--- /dev/null
@@ -0,0 +1,59 @@
+From 4f06b0436b2ddbd3b67b10e77098a6862787b3eb Mon Sep 17 00:00:00 2001
+From: Jeremy Fitzhardinge <jeremy@goop.org>
+Date: Wed, 11 Feb 2009 09:32:19 -0800
+Subject: x86/cpa: make sure cpa is safe to call in lazy mmu mode
+
+From: Jeremy Fitzhardinge <jeremy@goop.org>
+
+commit 4f06b0436b2ddbd3b67b10e77098a6862787b3eb upstream.
+
+Impact: fix race leading to crash under KVM and Xen
+
+The CPA code may be called while we're in lazy mmu update mode - for
+example, when using DEBUG_PAGE_ALLOC and doing a slab allocation
+in an interrupt handler which interrupted a lazy mmu update.  In this
+case, the in-memory pagetable state may be out of date due to pending
+queued updates.  We need to flush any pending updates before inspecting
+the page table.  Similarly, we must explicitly flush any modifications
+CPA may have made (which comes down to flushing queued operations when
+flushing the TLB).
+
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
+Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/mm/pageattr.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/x86/mm/pageattr.c
++++ b/arch/x86/mm/pageattr.c
+@@ -576,6 +576,13 @@ static int __change_page_attr(struct cpa
+       else
+               address = *cpa->vaddr;
++      /*
++       * If we're called with lazy mmu updates enabled, the
++       * in-memory pte state may be stale.  Flush pending updates to
++       * bring them up to date.
++       */
++      arch_flush_lazy_mmu_mode();
++
+ repeat:
+       kpte = lookup_address(address, &level);
+       if (!kpte)
+@@ -854,6 +861,13 @@ static int change_page_attr_set_clr(unsi
+       } else
+               cpa_flush_all(cache);
++      /*
++       * If we've been called with lazy mmu updates enabled, then
++       * make sure that everything gets flushed out before we
++       * return.
++       */
++      arch_flush_lazy_mmu_mode();
++
+ out:
+       return ret;
+ }
diff --git a/queue-2.6.28/x86-vm86-fix-preemption-bug.patch b/queue-2.6.28/x86-vm86-fix-preemption-bug.patch
new file mode 100644 (file)
index 0000000..f02c181
--- /dev/null
@@ -0,0 +1,64 @@
+From be716615fe596ee117292dc615e95f707fb67fd1 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 13 Jan 2009 23:36:34 +0100
+Subject: x86, vm86: fix preemption bug
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit be716615fe596ee117292dc615e95f707fb67fd1 upstream.
+
+Commit 3d2a71a596bd9c761c8487a2178e95f8a61da083 ("x86, traps: converge
+do_debug handlers") changed the preemption disable logic of do_debug()
+so vm86_handle_trap() is called with preemption disabled resulting in:
+
+ BUG: sleeping function called from invalid context at include/linux/kernel.h:155
+ in_atomic(): 1, irqs_disabled(): 0, pid: 3005, name: dosemu.bin
+ Pid: 3005, comm: dosemu.bin Tainted: G        W  2.6.29-rc1 #51
+ Call Trace:
+  [<c050d669>] copy_to_user+0x33/0x108
+  [<c04181f4>] save_v86_state+0x65/0x149
+  [<c0418531>] handle_vm86_trap+0x20/0x8f
+  [<c064e345>] do_debug+0x15b/0x1a4
+  [<c064df1f>] debug_stack_correct+0x27/0x2c
+  [<c040365b>] sysenter_do_call+0x12/0x2f
+ BUG: scheduling while atomic: dosemu.bin/3005/0x10000001
+
+Restore the original calling convention and reenable preemption before
+calling handle_vm86_trap().
+
+Reported-by: Michal Suchanek <hramrach@centrum.cz>
+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/traps.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/traps.c
++++ b/arch/x86/kernel/traps.c
+@@ -104,6 +104,12 @@ static inline void preempt_conditional_s
+               local_irq_enable();
+ }
++static inline void conditional_cli(struct pt_regs *regs)
++{
++      if (regs->flags & X86_EFLAGS_IF)
++              local_irq_disable();
++}
++
+ static inline void preempt_conditional_cli(struct pt_regs *regs)
+ {
+       if (regs->flags & X86_EFLAGS_IF)
+@@ -629,8 +635,10 @@ clear_dr7:
+ #ifdef CONFIG_X86_32
+ debug_vm86:
++      /* reenable preemption: handle_vm86_trap() might sleep */
++      dec_preempt_count();
+       handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
+-      preempt_conditional_cli(regs);
++      conditional_cli(regs);
+       return;
+ #endif