From: Greg Kroah-Hartman Date: Wed, 12 Dec 2007 00:00:47 +0000 (-0800) Subject: more 2.6.23 patches added X-Git-Tag: v2.6.23.10~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=21e221f3cf836e2f97569ccf39b5622117610600;p=thirdparty%2Fkernel%2Fstable-queue.git more 2.6.23 patches added --- diff --git a/queue-2.6.23/create-sys-...-power-when-config_pm-is-set.patch b/queue-2.6.23/create-sys-...-power-when-config_pm-is-set.patch new file mode 100644 index 00000000000..81f17d4eff1 --- /dev/null +++ b/queue-2.6.23/create-sys-...-power-when-config_pm-is-set.patch @@ -0,0 +1,146 @@ +From stable-bounces@linux.kernel.org Wed Nov 28 14:53:59 2007 +From: Daniel Drake +Date: Wed, 28 Nov 2007 14:52:16 -0800 +Subject: create /sys/.../power when CONFIG_PM is set +To: linux-kernel@vger.kernel.org +Cc: Greg Kroah-Hartman , Kay Sievers , Alan Stern , Daniel Drake , Andrew Morton , stable +Message-ID: <1196290340-28828-2-git-send-email-gregkh@suse.de> + + +From: Daniel Drake + +patch dec13c15445fec29ca9087890895718450e80b95 in mainline. + +The CONFIG_SUSPEND changes in 2.6.23 caused a regression under certain +configuration conditions (SUSPEND=n, USB_AUTOSUSPEND=y) where all USB +device attributes in sysfs (idVendor, idProduct, ...) silently disappeared, +causing udev breakage and more. + +The cause of this is that the /sys/.../power subdirectory is now only +created when CONFIG_PM_SLEEP is set, however, it should be created whenever +CONFIG_PM is set to handle the above situation. The following patch fixes +the regression. + +Signed-off-by: Daniel Drake +Acked-by: Rafael J. Wysocki +Cc: Alan Stern +Cc: Kay Sievers +Cc: stable +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/core.c | 4 +++- + drivers/base/power/Makefile | 3 ++- + drivers/base/power/main.c | 8 +------- + drivers/base/power/power.h | 25 ++++++++++++++++++------- + 4 files changed, 24 insertions(+), 16 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -814,9 +814,10 @@ int device_add(struct device *dev) + error = device_add_attrs(dev); + if (error) + goto AttrsError; +- error = device_pm_add(dev); ++ error = dpm_sysfs_add(dev); + if (error) + goto PMError; ++ device_pm_add(dev); + error = bus_add_device(dev); + if (error) + goto BusError; +@@ -841,6 +842,7 @@ int device_add(struct device *dev) + return error; + BusError: + device_pm_remove(dev); ++ dpm_sysfs_remove(dev); + PMError: + if (dev->bus) + blocking_notifier_call_chain(&dev->bus->bus_notifier, +--- a/drivers/base/power/Makefile ++++ b/drivers/base/power/Makefile +@@ -1,5 +1,6 @@ + obj-y := shutdown.o +-obj-$(CONFIG_PM_SLEEP) += main.o suspend.o resume.o sysfs.o ++obj-$(CONFIG_PM) += sysfs.o ++obj-$(CONFIG_PM_SLEEP) += main.o suspend.o resume.o + obj-$(CONFIG_PM_TRACE) += trace.o + + ifeq ($(CONFIG_DEBUG_DRIVER),y) +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -33,20 +33,14 @@ DEFINE_MUTEX(dpm_list_mtx); + + int (*platform_enable_wakeup)(struct device *dev, int is_on); + +-int device_pm_add(struct device *dev) ++void device_pm_add(struct device *dev) + { +- int error; +- + pr_debug("PM: Adding info for %s:%s\n", + dev->bus ? dev->bus->name : "No Bus", + kobject_name(&dev->kobj)); + mutex_lock(&dpm_list_mtx); + list_add_tail(&dev->power.entry, &dpm_active); +- error = dpm_sysfs_add(dev); +- if (error) +- list_del(&dev->power.entry); + mutex_unlock(&dpm_list_mtx); +- return error; + } + + void device_pm_remove(struct device *dev) +--- a/drivers/base/power/power.h ++++ b/drivers/base/power/power.h +@@ -34,14 +34,26 @@ static inline struct dev_pm_info * to_pm + return container_of(entry, struct dev_pm_info, entry); + } + +-static inline struct device * to_device(struct list_head * entry) ++static inline struct device *to_device(struct list_head *entry) + { + return container_of(to_pm_info(entry), struct device, power); + } + +-extern int device_pm_add(struct device *); ++extern void device_pm_add(struct device *); + extern void device_pm_remove(struct device *); + ++#else /* CONFIG_PM_SLEEP */ ++ ++static inline void device_pm_add(struct device *dev) ++{ ++} ++ ++static inline void device_pm_remove(struct device *dev) ++{ ++} ++#endif ++ ++#ifdef CONFIG_PM + /* + * sysfs.c + */ +@@ -62,16 +74,15 @@ extern int resume_device(struct device * + */ + extern int suspend_device(struct device *, pm_message_t); + +-#else /* CONFIG_PM_SLEEP */ +- ++#else /* CONFIG_PM */ + +-static inline int device_pm_add(struct device * dev) ++static inline int dpm_sysfs_add(struct device *dev) + { + return 0; + } +-static inline void device_pm_remove(struct device * dev) +-{ + ++static inline void dpm_sysfs_remove(struct device *dev) ++{ + } + + #endif diff --git a/queue-2.6.23/esp_scsi-fix-reset-cleanup-spinlock-recursion.patch b/queue-2.6.23/esp_scsi-fix-reset-cleanup-spinlock-recursion.patch new file mode 100644 index 00000000000..52a119caf13 --- /dev/null +++ b/queue-2.6.23/esp_scsi-fix-reset-cleanup-spinlock-recursion.patch @@ -0,0 +1,114 @@ +From stable-bounces@linux.kernel.org Mon Dec 10 15:50:11 2007 +From: "Maciej W. Rozycki" +Date: Mon, 10 Dec 2007 15:49:31 -0800 +Subject: esp_scsi: fix reset cleanup spinlock recursion +To: torvalds@linux-foundation.org +Cc: James.Bottomley@steeleye.com, akpm@linux-foundation.org, davem@davemloft.net, macro@linux-mips.org, stable@kernel.org +Message-ID: <200712102349.lBANnWYP025320@imap1.linux-foundation.org> + + +From: "Maciej W. Rozycki" + +patch 522939d45c293388e6a360210905f9230298df16 in mainline. + +The esp_reset_cleanup() function is called with the host lock held and +invokes starget_for_each_device() which wants to take it too. Here is a +fix along the lines of shost_for_each_device()/__shost_for_each_device() +adding a __starget_for_each_device() counterpart which assumes the lock +has already been taken. + +Eventually, I think the driver should get modified so that more work is +done as a softirq rather than in the interrupt context, but for now it +fixes a bug that causes the spinlock debugger to fire. + +While at it, it fixes a small number of cosmetic problems with +starget_for_each_device() too. + +Signed-off-by: Maciej W. Rozycki +Acked-by: David S. Miller +Cc: James Bottomley +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/esp_scsi.c | 4 ++-- + drivers/scsi/scsi.c | 31 +++++++++++++++++++++++++++++-- + include/scsi/scsi_device.h | 3 +++ + 3 files changed, 34 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/esp_scsi.c ++++ b/drivers/scsi/esp_scsi.c +@@ -2026,8 +2026,8 @@ static void esp_reset_cleanup(struct esp + tp->flags |= ESP_TGT_CHECK_NEGO; + + if (tp->starget) +- starget_for_each_device(tp->starget, NULL, +- esp_clear_hold); ++ __starget_for_each_device(tp->starget, NULL, ++ esp_clear_hold); + } + esp->flags &= ~ESP_FLAG_RESETTING; + } +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -886,11 +886,11 @@ EXPORT_SYMBOL(__scsi_iterate_devices); + * starget_for_each_device - helper to walk all devices of a target + * @starget: target whose devices we want to iterate over. + * +- * This traverses over each devices of @shost. The devices have ++ * This traverses over each device of @starget. The devices have + * a reference that must be released by scsi_host_put when breaking + * out of the loop. + */ +-void starget_for_each_device(struct scsi_target *starget, void * data, ++void starget_for_each_device(struct scsi_target *starget, void *data, + void (*fn)(struct scsi_device *, void *)) + { + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); +@@ -905,6 +905,33 @@ void starget_for_each_device(struct scsi + EXPORT_SYMBOL(starget_for_each_device); + + /** ++ * __starget_for_each_device - helper to walk all devices of a target ++ * (UNLOCKED) ++ * @starget: target whose devices we want to iterate over. ++ * ++ * This traverses over each device of @starget. It does _not_ ++ * take a reference on the scsi_device, so the whole loop must be ++ * protected by shost->host_lock. ++ * ++ * Note: The only reason why drivers would want to use this is because ++ * they need to access the device list in irq context. Otherwise you ++ * really want to use starget_for_each_device instead. ++ **/ ++void __starget_for_each_device(struct scsi_target *starget, void *data, ++ void (*fn)(struct scsi_device *, void *)) ++{ ++ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); ++ struct scsi_device *sdev; ++ ++ __shost_for_each_device(sdev, shost) { ++ if ((sdev->channel == starget->channel) && ++ (sdev->id == starget->id)) ++ fn(sdev, data); ++ } ++} ++EXPORT_SYMBOL(__starget_for_each_device); ++ ++/** + * __scsi_device_lookup_by_target - find a device given the target (UNLOCKED) + * @starget: SCSI target pointer + * @lun: SCSI Logical Unit Number +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -222,6 +222,9 @@ extern struct scsi_device *__scsi_device + uint); + extern void starget_for_each_device(struct scsi_target *, void *, + void (*fn)(struct scsi_device *, void *)); ++extern void __starget_for_each_device(struct scsi_target *, void *, ++ void (*fn)(struct scsi_device *, ++ void *)); + + /* only exposed to implement shost_for_each_device */ + extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, diff --git a/queue-2.6.23/fb_ddc-fix-ddc-lines-quirk.patch b/queue-2.6.23/fb_ddc-fix-ddc-lines-quirk.patch new file mode 100644 index 00000000000..d92e47554db --- /dev/null +++ b/queue-2.6.23/fb_ddc-fix-ddc-lines-quirk.patch @@ -0,0 +1,92 @@ +From stable-bounces@linux.kernel.org Wed Nov 28 16:28:03 2007 +From: Jean Delvare +Date: Wed, 28 Nov 2007 16:21:35 -0800 +Subject: fb_ddc: fix DDC lines quirk +To: torvalds@linux-foundation.org +Cc: rleigh@whinlatter.ukfsn.org, benh@kernel.crashing.org, mb@bu3sch.de, khali@linux-fr.org, adaplas@pol.net, akpm@linux-foundation.org, stable@kernel.org +Message-ID: <200711290021.lAT0LZgT026655@imap1.linux-foundation.org> + + +From: Jean Delvare + +patch b64d70825abbf706bbe80be1b11b09514b71f45e in mainline. + +The code in fb_ddc_read() is said to be based on the implementation of the +radeon driver: +http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=fc5891c8a3ba284f13994d7bc1f1bfa8283982de + +However, comparing the old radeon driver code with the new fb_ddc code +reveals some differences. Most notably, the I2C bus lines are held at the +end of the function, while the original code was releasing them (as the +comment above correctly says.) + +There are a few other differences, which appear to be responsible for read +failures on my system. While tracing low-level I2C code in i2c-algo-bit, I +noticed that the initial attempt to read the EDID always failed. It takes +one retry for the read to succeed. As we are about to remove this +automatic retry property from i2c-algo-bit, reading the EDID would really +fail. + +As a summary, the I2C lines quirk which is supposedly needed to read EDID +on some older monitors is currently breaking the (first) read on all other +monitors (and might not even work with older ones - did anyone try since +October 2006?) + +After applying the patch below, which makes the code in fb_ddc_read() +really similar to what the radeon driver used to have, the first EDID read +succeeds again. + +On top of that, as it appears that this code has been broken for one year +now and nobody seems to have complained, I'm curious if it makes sense to +keep this quirk in place. It makes the code more complex and slower just +for the sake of monitors which I guess nobody uses anymore. Can't we just +get rid of it? + +Signed-off-by: Jean Delvare +Acked-by: Benjamin Herrenschmidt +Tested-by: Roger Leigh +Tested-by: Michael Buesch +Cc: "Antonino A. Daplas" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/fb_ddc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/video/fb_ddc.c ++++ b/drivers/video/fb_ddc.c +@@ -56,13 +56,12 @@ unsigned char *fb_ddc_read(struct i2c_ad + int i, j; + + algo_data->setscl(algo_data->data, 1); +- algo_data->setscl(algo_data->data, 0); + + for (i = 0; i < 3; i++) { + /* For some old monitors we need the + * following process to initialize/stop DDC + */ +- algo_data->setsda(algo_data->data, 0); ++ algo_data->setsda(algo_data->data, 1); + msleep(13); + + algo_data->setscl(algo_data->data, 1); +@@ -97,14 +96,15 @@ unsigned char *fb_ddc_read(struct i2c_ad + algo_data->setsda(algo_data->data, 1); + msleep(15); + algo_data->setscl(algo_data->data, 0); ++ algo_data->setsda(algo_data->data, 0); + if (edid) + break; + } + /* Release the DDC lines when done or the Apple Cinema HD display + * will switch off + */ +- algo_data->setsda(algo_data->data, 0); +- algo_data->setscl(algo_data->data, 0); ++ algo_data->setsda(algo_data->data, 1); ++ algo_data->setscl(algo_data->data, 1); + + return edid; + } diff --git a/queue-2.6.23/freezer-fix-apm-emulation-breakage.patch b/queue-2.6.23/freezer-fix-apm-emulation-breakage.patch new file mode 100644 index 00000000000..94fa7c730b9 --- /dev/null +++ b/queue-2.6.23/freezer-fix-apm-emulation-breakage.patch @@ -0,0 +1,74 @@ +From cb43c54ca05c01533c45e4d3abfe8f99b7acf624 Mon Sep 17 00:00:00 2001 +From: Rafael J. Wysocki +Date: Wed, 21 Nov 2007 02:53:14 +0100 +Subject: Freezer: Fix APM emulation breakage + +From: Rafael J. Wysocki + +patch cb43c54ca05c01533c45e4d3abfe8f99b7acf624 in mainline. + +The APM emulation is currently broken as a result of commit +831441862956fffa17b9801db37e6ea1650b0f69 +"Freezer: make kernel threads nonfreezable by default" +that removed the PF_NOFREEZE annotations from apm_ioctl() without adding +the appropriate freezer hooks. Fix it and remove the unnecessary variable flags +from apm_ioctl(). + +Special thanks to Franck Bui-Huu for pointing out the +problem. + +Signed-off-by: Rafael J. Wysocki +Cc: Pavel Machek +Cc: Franck Bui-Huu +Cc: Nigel Cunningham +Signed-off-by: Len Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/apm-emulation.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/drivers/char/apm-emulation.c ++++ b/drivers/char/apm-emulation.c +@@ -295,7 +295,6 @@ static int + apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) + { + struct apm_user *as = filp->private_data; +- unsigned long flags; + int err = -EINVAL; + + if (!as->suser || !as->writer) +@@ -331,10 +330,16 @@ apm_ioctl(struct inode * inode, struct f + * Wait for the suspend/resume to complete. If there + * are pending acknowledges, we wait here for them. + */ +- flags = current->flags; ++ freezer_do_not_count(); + + wait_event(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); ++ ++ /* ++ * Since we are waiting until the suspend is done, the ++ * try_to_freeze() in freezer_count() will not trigger ++ */ ++ freezer_count(); + } else { + as->suspend_state = SUSPEND_WAIT; + mutex_unlock(&state_lock); +@@ -362,14 +367,10 @@ apm_ioctl(struct inode * inode, struct f + * Wait for the suspend/resume to complete. If there + * are pending acknowledges, we wait here for them. + */ +- flags = current->flags; +- +- wait_event_interruptible(apm_suspend_waitqueue, ++ wait_event_freezable(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); + } + +- current->flags = flags; +- + mutex_lock(&state_lock); + err = as->suspend_result; + as->suspend_state = SUSPEND_NONE; diff --git a/queue-2.6.23/futex-fix-for-futex_wait-signal-stack-corruption.patch b/queue-2.6.23/futex-fix-for-futex_wait-signal-stack-corruption.patch new file mode 100644 index 00000000000..0e1bb28c61c --- /dev/null +++ b/queue-2.6.23/futex-fix-for-futex_wait-signal-stack-corruption.patch @@ -0,0 +1,216 @@ +From ce6bd420f43b28038a2c6e8fbb86ad24014727b6 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Wed, 5 Dec 2007 15:46:09 +0100 +Subject: [PATCH] futex: fix for futex_wait signal stack corruption + +From Steven Rostedt + +patch ce6bd420f43b28038a2c6e8fbb86ad24014727b6 in mainline. + +David Holmes found a bug in the -rt tree with respect to +pthread_cond_timedwait. After trying his test program on the latest git +from mainline, I found the bug was there too. The bug he was seeing +that his test program showed, was that if one were to do a "Ctrl-Z" on a +process that was in the pthread_cond_timedwait, and then did a "bg" on +that process, it would return with a "-ETIMEDOUT" but early. That is, +the timer would go off early. + +Looking into this, I found the source of the problem. And it is a rather +nasty bug at that. + +Here's the relevant code from kernel/futex.c: (not in order in the file) + +[...] +smlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, + struct timespec __user *utime, u32 __user *uaddr2, + u32 val3) +{ + struct timespec ts; + ktime_t t, *tp = NULL; + u32 val2 = 0; + int cmd = op & FUTEX_CMD_MASK; + + if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI)) { + if (copy_from_user(&ts, utime, sizeof(ts)) != 0) + return -EFAULT; + if (!timespec_valid(&ts)) + return -EINVAL; + + t = timespec_to_ktime(ts); + if (cmd == FUTEX_WAIT) + t = ktime_add(ktime_get(), t); + tp = &t; + } +[...] + return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); +} + +[...] + +long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + u32 __user *uaddr2, u32 val2, u32 val3) +{ + int ret; + int cmd = op & FUTEX_CMD_MASK; + struct rw_semaphore *fshared = NULL; + + if (!(op & FUTEX_PRIVATE_FLAG)) + fshared = ¤t->mm->mmap_sem; + + switch (cmd) { + case FUTEX_WAIT: + ret = futex_wait(uaddr, fshared, val, timeout); + +[...] + +static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, + u32 val, ktime_t *abs_time) +{ +[...] + struct restart_block *restart; + restart = ¤t_thread_info()->restart_block; + restart->fn = futex_wait_restart; + restart->arg0 = (unsigned long)uaddr; + restart->arg1 = (unsigned long)val; + restart->arg2 = (unsigned long)abs_time; + restart->arg3 = 0; + if (fshared) + restart->arg3 |= ARG3_SHARED; + return -ERESTART_RESTARTBLOCK; +[...] + +static long futex_wait_restart(struct restart_block *restart) +{ + u32 __user *uaddr = (u32 __user *)restart->arg0; + u32 val = (u32)restart->arg1; + ktime_t *abs_time = (ktime_t *)restart->arg2; + struct rw_semaphore *fshared = NULL; + + restart->fn = do_no_restart_syscall; + if (restart->arg3 & ARG3_SHARED) + fshared = ¤t->mm->mmap_sem; + return (long)futex_wait(uaddr, fshared, val, abs_time); +} + +So when the futex_wait is interrupt by a signal we break out of the +hrtimer code and set up or return from signal. This code does not return +back to userspace, so we set up a RESTARTBLOCK. The bug here is that we +save the "abs_time" which is a pointer to the stack variable "ktime_t t" +from sys_futex. + +This returns and unwinds the stack before we get to call our signal. On +return from the signal we go to futex_wait_restart, where we update all +the parameters for futex_wait and call it. But here we have a problem +where abs_time is no longer valid. + +I verified this with print statements, and sure enough, what abs_time +was set to ends up being garbage when we get to futex_wait_restart. + +The solution I did to solve this (with input from Linus Torvalds) +was to add unions to the restart_block to allow system calls to +use the restart with specific parameters. This way the futex code now +saves the time in a 64bit value in the restart block instead of storing +it on the stack. + +Note: I'm a bit nervious to add "linux/types.h" and use u32 and u64 +in thread_info.h, when there's a #ifdef __KERNEL__ just below that. +Not sure what that is there for. If this turns out to be a problem, I've +tested this with using "unsigned int" for u32 and "unsigned long long" for +u64 and it worked just the same. I'm using u32 and u64 just to be +consistent with what the futex code uses. + +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar +Signed-off-by: Thomas Gleixner +Acked-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/thread_info.h | 17 +++++++++++++++-- + kernel/futex.c | 25 +++++++++++++------------ + 2 files changed, 28 insertions(+), 14 deletions(-) + +--- a/include/linux/thread_info.h ++++ b/include/linux/thread_info.h +@@ -7,12 +7,25 @@ + #ifndef _LINUX_THREAD_INFO_H + #define _LINUX_THREAD_INFO_H + ++#include ++ + /* +- * System call restart block. ++ * System call restart block. + */ + struct restart_block { + long (*fn)(struct restart_block *); +- unsigned long arg0, arg1, arg2, arg3; ++ union { ++ struct { ++ unsigned long arg0, arg1, arg2, arg3; ++ }; ++ /* For futex_wait */ ++ struct { ++ u32 *uaddr; ++ u32 val; ++ u32 flags; ++ u64 time; ++ } futex; ++ }; + }; + + extern long do_no_restart_syscall(struct restart_block *parm); +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1149,9 +1149,9 @@ static int fixup_pi_state_owner(u32 __us + + /* + * In case we must use restart_block to restart a futex_wait, +- * we encode in the 'arg3' shared capability ++ * we encode in the 'flags' shared capability + */ +-#define ARG3_SHARED 1 ++#define FLAGS_SHARED 1 + + static long futex_wait_restart(struct restart_block *restart); + +@@ -1290,12 +1290,13 @@ static int futex_wait(u32 __user *uaddr, + struct restart_block *restart; + restart = ¤t_thread_info()->restart_block; + restart->fn = futex_wait_restart; +- restart->arg0 = (unsigned long)uaddr; +- restart->arg1 = (unsigned long)val; +- restart->arg2 = (unsigned long)abs_time; +- restart->arg3 = 0; ++ restart->futex.uaddr = (u32 *)uaddr; ++ restart->futex.val = val; ++ restart->futex.time = abs_time->tv64; ++ restart->futex.flags = 0; ++ + if (fshared) +- restart->arg3 |= ARG3_SHARED; ++ restart->futex.flags |= FLAGS_SHARED; + return -ERESTART_RESTARTBLOCK; + } + +@@ -1310,15 +1311,15 @@ static int futex_wait(u32 __user *uaddr, + + static long futex_wait_restart(struct restart_block *restart) + { +- u32 __user *uaddr = (u32 __user *)restart->arg0; +- u32 val = (u32)restart->arg1; +- ktime_t *abs_time = (ktime_t *)restart->arg2; ++ u32 __user *uaddr = (u32 __user *)restart->futex.uaddr; + struct rw_semaphore *fshared = NULL; ++ ktime_t t; + ++ t.tv64 = restart->futex.time; + restart->fn = do_no_restart_syscall; +- if (restart->arg3 & ARG3_SHARED) ++ if (restart->futex.flags & FLAGS_SHARED) + fshared = ¤t->mm->mmap_sem; +- return (long)futex_wait(uaddr, fshared, val, abs_time); ++ return (long)futex_wait(uaddr, fshared, restart->futex.val, &t); + } + + diff --git a/queue-2.6.23/netfilter-fix-kernel-panic-with-redirect-target.patch b/queue-2.6.23/netfilter-fix-kernel-panic-with-redirect-target.patch new file mode 100644 index 00000000000..cfbacdce55b --- /dev/null +++ b/queue-2.6.23/netfilter-fix-kernel-panic-with-redirect-target.patch @@ -0,0 +1,68 @@ +From stable-bounces@linux.kernel.org Wed Nov 28 00:57:19 2007 +From: Evgeniy Polyakov +Date: Wed, 28 Nov 2007 09:56:54 +0100 +Subject: netfilter: Fix kernel panic with REDIRECT target. +To: stable@kernel.org +Cc: Netfilter Development Mailinglist , "David S. Miller" +Message-ID: <474D2D56.9090503@trash.net> + +From: Evgeniy Polyakov + +This patch fixes a NAT regression in 2.6.23, resulting in a +crash when a connection is NATed and matches a conntrack +helper after NAT. + +Please apply, thanks. +[NETFILTER]: Fix kernel panic with REDIRECT target. + +Upstream commit 1f305323ff5b9ddc1a4346d36072bcdb58f3f68a + +When connection tracking entry (nf_conn) is about to copy itself it can +have some of its extension users (like nat) as being already freed and +thus not required to be copied. + +Actually looking at this function I suspect it was copied from +nf_nat_setup_info() and thus bug was introduced. + +Report and testing from David . + +[ Patrick McHardy states: + + I now understand whats happening: + + - new connection is allocated without helper + - connection is REDIRECTed to localhost + - nf_nat_setup_info adds NAT extension, but doesn't initialize it yet + - nf_conntrack_alter_reply performs a helper lookup based on the + new tuple, finds the SIP helper and allocates a helper extension, + causing reallocation because of too little space + - nf_nat_move_storage is called with the uninitialized nat extension + + So your fix is entirely correct, thanks a lot :) ] + +Signed-off-by: Evgeniy Polyakov +Acked-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/netfilter/nf_nat_core.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/net/ipv4/netfilter/nf_nat_core.c ++++ b/net/ipv4/netfilter/nf_nat_core.c +@@ -607,13 +607,10 @@ static void nf_nat_move_storage(struct n + struct nf_conn_nat *new_nat = nf_ct_ext_find(conntrack, NF_CT_EXT_NAT); + struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old; + struct nf_conn *ct = old_nat->ct; +- unsigned int srchash; + +- if (!(ct->status & IPS_NAT_DONE_MASK)) ++ if (!ct || !(ct->status & IPS_NAT_DONE_MASK)) + return; + +- srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- + write_lock_bh(&nf_nat_lock); + hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource); + new_nat->ct = ct; diff --git a/queue-2.6.23/nf_nat-fix-memset-error.patch b/queue-2.6.23/nf_nat-fix-memset-error.patch new file mode 100644 index 00000000000..bb955673439 --- /dev/null +++ b/queue-2.6.23/nf_nat-fix-memset-error.patch @@ -0,0 +1,43 @@ +From stable-bounces@linux.kernel.org Wed Nov 28 00:56:55 2007 +From: Li Zefan +Date: Wed, 28 Nov 2007 09:56:27 +0100 +Subject: nf_nat: fix memset error +To: stable@kernel.org +Cc: Netfilter Development Mailinglist , "David S. Miller" +Message-ID: <474D2D3B.5030909@trash.net> + +From: Li Zefan + +This patch fixes an incorrect memset in the NAT code, causing +misbehaviour when unloading and reloading the NAT module. +Applies to stable-2.6.22 and stable-2.6.23. + +Please apply, thanks. +[NETFILTER]: nf_nat: fix memset error + +Upstream commit e0bf9cf15fc30d300b7fbd821c6bc975531fab44 + +The size passing to memset is the size of a pointer. Fixes +misbehaviour when unloading and reloading the NAT module. + +Signed-off-by: Li Zefan +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + + +--- + net/ipv4/netfilter/nf_nat_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/netfilter/nf_nat_core.c ++++ b/net/ipv4/netfilter/nf_nat_core.c +@@ -681,7 +681,7 @@ static int clean_nat(struct nf_conn *i, + + if (!nat) + return 0; +- memset(nat, 0, sizeof(nat)); ++ memset(nat, 0, sizeof(*nat)); + i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST); + return 0; + } diff --git a/queue-2.6.23/pnp-increase-the-maximum-number-of-resources.patch b/queue-2.6.23/pnp-increase-the-maximum-number-of-resources.patch new file mode 100644 index 00000000000..3dbcc3b7a0a --- /dev/null +++ b/queue-2.6.23/pnp-increase-the-maximum-number-of-resources.patch @@ -0,0 +1,93 @@ +From stable-bounces@linux.kernel.org Wed Nov 28 16:21:49 2007 +From: Zhao Yakui +Date: Wed, 28 Nov 2007 16:21:21 -0800 +Subject: PNP: increase the maximum number of resources +To: torvalds@linux-foundation.org +Cc: trenn@suse.de, yakui.zhao@intel.com, shaohua.li@intel.com, akpm@linux-foundation.org, stable@kernel.org, bjorn.helgaas@hp.com +Message-ID: <200711290021.lAT0LM7A026611@imap1.linux-foundation.org> + + +From: Zhao Yakui + +patch a7839e960675b549f06209d18283d5cee2ce9261 in mainline. + +On some systems the number of resources(IO,MEM) returnedy by PNP device is +greater than the PNP constant, for example motherboard devices. It brings +that some resources can't be reserved and resource confilicts. This will +cause PCI resources are assigned wrongly in some systems, and cause hang. +This is a regression since we deleted ACPI motherboard driver and use PNP +system driver. + +[akpm@linux-foundation.org: fix text and coding-style a bit] +Signed-off-by: Li Shaohua +Signed-off-by: Zhao Yakui +Cc: Bjorn Helgaas +Cc: Thomas Renninger +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pnp/pnpacpi/rsparser.c | 15 +++++++++++++-- + include/linux/pnp.h | 4 ++-- + 2 files changed, 15 insertions(+), 4 deletions(-) + +--- a/drivers/pnp/pnpacpi/rsparser.c ++++ b/drivers/pnp/pnpacpi/rsparser.c +@@ -82,9 +82,11 @@ static void pnpacpi_parse_allocated_irqr + while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && + i < PNP_MAX_IRQ) + i++; +- if (i >= PNP_MAX_IRQ) ++ if (i >= PNP_MAX_IRQ) { ++ printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ " ++ "resources: %d \n", PNP_MAX_IRQ); + return; +- ++ } + res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag + res->irq_resource[i].flags |= irq_flags(triggering, polarity); + irq = acpi_register_gsi(gsi, triggering, polarity); +@@ -163,6 +165,9 @@ static void pnpacpi_parse_allocated_dmar + } + res->dma_resource[i].start = dma; + res->dma_resource[i].end = dma; ++ } else { ++ printk(KERN_ERR "pnpacpi: exceeded the max number of DMA " ++ "resources: %d \n", PNP_MAX_DMA); + } + } + +@@ -184,6 +189,9 @@ static void pnpacpi_parse_allocated_iore + } + res->port_resource[i].start = io; + res->port_resource[i].end = io + len - 1; ++ } else { ++ printk(KERN_ERR "pnpacpi: exceeded the max number of IO " ++ "resources: %d \n", PNP_MAX_PORT); + } + } + +@@ -207,6 +215,9 @@ static void pnpacpi_parse_allocated_memr + + res->mem_resource[i].start = mem; + res->mem_resource[i].end = mem + len - 1; ++ } else { ++ printk(KERN_ERR "pnpacpi: exceeded the max number of mem " ++ "resources: %d\n", PNP_MAX_MEM); + } + } + +--- a/include/linux/pnp.h ++++ b/include/linux/pnp.h +@@ -13,8 +13,8 @@ + #include + #include + +-#define PNP_MAX_PORT 8 +-#define PNP_MAX_MEM 4 ++#define PNP_MAX_PORT 24 ++#define PNP_MAX_MEM 12 + #define PNP_MAX_IRQ 2 + #define PNP_MAX_DMA 2 + #define PNP_NAME_LEN 50 diff --git a/queue-2.6.23/revert-dpt_i2o-convert-to-scsi-hotplug-model.patch b/queue-2.6.23/revert-dpt_i2o-convert-to-scsi-hotplug-model.patch new file mode 100644 index 00000000000..3f52fe9562c --- /dev/null +++ b/queue-2.6.23/revert-dpt_i2o-convert-to-scsi-hotplug-model.patch @@ -0,0 +1,314 @@ +From stable-bounces@linux.kernel.org Mon Dec 10 15:50:22 2007 +From: Andrew Morton +Date: Mon, 10 Dec 2007 15:49:20 -0800 +Subject: revert "dpt_i2o: convert to SCSI hotplug model" +To: torvalds@linux-foundation.org +Cc: James.Bottomley@SteelEye.com, matthew@wil.cx, fujita.tomonori@lab.ntt.co.jp, anders.henke@1und1.de, akpm@linux-foundation.org, stable@kernel.org, mark_salyzyn@adaptec.com +Message-ID: <200712102349.lBANnKnq025284@imap1.linux-foundation.org> + + +From: Andrew Morton + +patch 24601bbcacb3356657747f2e64317923feb7a1a2 in mainline. + +revert + + commit 55d9fcf57ba5ec427544fca7abc335cf3da78160 + Author: Matthew Wilcox + Date: Mon Jul 30 15:19:18 2007 -0600 + + [SCSI] dpt_i2o: convert to SCSI hotplug model + + - Delete refereces to HOSTS_C + - Switch to module_init/module_exit instead of detect/release + - Don't pass around the host template and rename it to adpt_template + - Switch from scsi_register/scsi_unregister to scsi_host_alloc, + scsi_add_host, scsi_scan_host and scsi_host_put. + +Because it caused (for unknown reasons) Andres' all-data-reads-as-zeroes +problem, reported at +http://groups.google.com/group/fa.linux.kernel/msg/083a9acff0330234 + +Cc: Matthew Wilcox +Cc: "Salyzyn, Mark" +Cc: James Bottomley +Acked-by: FUJITA Tomonori +Cc: Anders Henke +Signed-off-by: Andrew Morton +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/dpt_i2o.c | 132 ++++++++++++++++++++++--------------------------- + drivers/scsi/dpti.h | 9 ++- + 2 files changed, 68 insertions(+), 73 deletions(-) + +--- a/drivers/scsi/dpt_i2o.c ++++ b/drivers/scsi/dpt_i2o.c +@@ -173,20 +173,20 @@ static struct pci_device_id dptids[] = { + }; + MODULE_DEVICE_TABLE(pci,dptids); + +-static void adpt_exit(void); +- +-static int adpt_detect(void) ++static int adpt_detect(struct scsi_host_template* sht) + { + struct pci_dev *pDev = NULL; + adpt_hba* pHba; + ++ adpt_init(); ++ + PINFO("Detecting Adaptec I2O RAID controllers...\n"); + + /* search for all Adatpec I2O RAID cards */ + while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) { + if(pDev->device == PCI_DPT_DEVICE_ID || + pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){ +- if(adpt_install_hba(pDev) ){ ++ if(adpt_install_hba(sht, pDev) ){ + PERROR("Could not Init an I2O RAID device\n"); + PERROR("Will not try to detect others.\n"); + return hba_count-1; +@@ -248,33 +248,34 @@ rebuild_sys_tab: + } + + for (pHba = hba_chain; pHba; pHba = pHba->next) { +- if (adpt_scsi_register(pHba) < 0) { ++ if( adpt_scsi_register(pHba,sht) < 0){ + adpt_i2o_delete_hba(pHba); + continue; + } + pHba->initialized = TRUE; + pHba->state &= ~DPTI_STATE_RESET; +- scsi_scan_host(pHba->host); + } + + // Register our control device node + // nodes will need to be created in /dev to access this + // the nodes can not be created from within the driver + if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) { +- adpt_exit(); ++ adpt_i2o_sys_shutdown(); + return 0; + } + return hba_count; + } + + +-static int adpt_release(adpt_hba *pHba) ++/* ++ * scsi_unregister will be called AFTER we return. ++ */ ++static int adpt_release(struct Scsi_Host *host) + { +- struct Scsi_Host *shost = pHba->host; +- scsi_remove_host(shost); ++ adpt_hba* pHba = (adpt_hba*) host->hostdata[0]; + // adpt_i2o_quiesce_hba(pHba); + adpt_i2o_delete_hba(pHba); +- scsi_host_put(shost); ++ scsi_unregister(host); + return 0; + } + +@@ -881,7 +882,7 @@ static int adpt_reboot_event(struct noti + #endif + + +-static int adpt_install_hba(struct pci_dev* pDev) ++static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) + { + + adpt_hba* pHba = NULL; +@@ -1030,6 +1031,8 @@ static void adpt_i2o_delete_hba(adpt_hba + + + mutex_lock(&adpt_configuration_lock); ++ // scsi_unregister calls our adpt_release which ++ // does a quiese + if(pHba->host){ + free_irq(pHba->host->irq, pHba); + } +@@ -1081,6 +1084,17 @@ static void adpt_i2o_delete_hba(adpt_hba + } + + ++static int adpt_init(void) ++{ ++ printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); ++#ifdef REBOOT_NOTIFIER ++ register_reboot_notifier(&adpt_reboot_notifier); ++#endif ++ ++ return 0; ++} ++ ++ + static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun) + { + struct adpt_device* d; +@@ -2166,6 +2180,37 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pH + } + + ++static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht) ++{ ++ struct Scsi_Host *host = NULL; ++ ++ host = scsi_register(sht, sizeof(adpt_hba*)); ++ if (host == NULL) { ++ printk ("%s: scsi_register returned NULL\n",pHba->name); ++ return -1; ++ } ++ host->hostdata[0] = (unsigned long)pHba; ++ pHba->host = host; ++ ++ host->irq = pHba->pDev->irq; ++ /* no IO ports, so don't have to set host->io_port and ++ * host->n_io_port ++ */ ++ host->io_port = 0; ++ host->n_io_port = 0; ++ /* see comments in scsi_host.h */ ++ host->max_id = 16; ++ host->max_lun = 256; ++ host->max_channel = pHba->top_scsi_channel + 1; ++ host->cmd_per_lun = 1; ++ host->unique_id = (uint) pHba; ++ host->sg_tablesize = pHba->sg_tablesize; ++ host->can_queue = pHba->post_fifo_size; ++ ++ return 0; ++} ++ ++ + static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd) + { + adpt_hba* pHba; +@@ -3284,10 +3329,12 @@ static static void adpt_delay(int millis + + #endif + +-static struct scsi_host_template adpt_template = { ++static struct scsi_host_template driver_template = { + .name = "dpt_i2o", + .proc_name = "dpt_i2o", + .proc_info = adpt_proc_info, ++ .detect = adpt_detect, ++ .release = adpt_release, + .info = adpt_info, + .queuecommand = adpt_queue, + .eh_abort_handler = adpt_abort, +@@ -3301,62 +3348,5 @@ static struct scsi_host_template adpt_te + .cmd_per_lun = 1, + .use_clustering = ENABLE_CLUSTERING, + }; +- +-static s32 adpt_scsi_register(adpt_hba* pHba) +-{ +- struct Scsi_Host *host; +- +- host = scsi_host_alloc(&adpt_template, sizeof(adpt_hba*)); +- if (host == NULL) { +- printk ("%s: scsi_host_alloc returned NULL\n",pHba->name); +- return -1; +- } +- host->hostdata[0] = (unsigned long)pHba; +- pHba->host = host; +- +- host->irq = pHba->pDev->irq; +- /* no IO ports, so don't have to set host->io_port and +- * host->n_io_port +- */ +- host->io_port = 0; +- host->n_io_port = 0; +- /* see comments in scsi_host.h */ +- host->max_id = 16; +- host->max_lun = 256; +- host->max_channel = pHba->top_scsi_channel + 1; +- host->cmd_per_lun = 1; +- host->unique_id = (uint) pHba; +- host->sg_tablesize = pHba->sg_tablesize; +- host->can_queue = pHba->post_fifo_size; +- +- if (scsi_add_host(host, &pHba->pDev->dev)) { +- scsi_host_put(host); +- return -1; +- } +- +- return 0; +-} +- +-static int __init adpt_init(void) +-{ +- int count; +- +- printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); +-#ifdef REBOOT_NOTIFIER +- register_reboot_notifier(&adpt_reboot_notifier); +-#endif +- +- count = adpt_detect(); +- +- return count > 0 ? 0 : -ENODEV; +-} +- +-static void __exit adpt_exit(void) +-{ +- while (hba_chain) +- adpt_release(hba_chain); +-} +- +-module_init(adpt_init); +-module_exit(adpt_exit); ++#include "scsi_module.c" + MODULE_LICENSE("GPL"); +--- a/drivers/scsi/dpti.h ++++ b/drivers/scsi/dpti.h +@@ -28,9 +28,11 @@ + * SCSI interface function Prototypes + */ + ++static int adpt_detect(struct scsi_host_template * sht); + static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *)); + static int adpt_abort(struct scsi_cmnd * cmd); + static int adpt_reset(struct scsi_cmnd* cmd); ++static int adpt_release(struct Scsi_Host *host); + static int adpt_slave_configure(struct scsi_device *); + + static const char *adpt_info(struct Scsi_Host *pSHost); +@@ -47,6 +49,8 @@ static int adpt_device_reset(struct scsi + + #define DPT_DRIVER_NAME "Adaptec I2O RAID" + ++#ifndef HOSTS_C ++ + #include "dpt/sys_info.h" + #include + #include "dpt/dpti_i2o.h" +@@ -285,7 +289,7 @@ static s32 adpt_i2o_init_outbound_q(adpt + static s32 adpt_i2o_hrt_get(adpt_hba* pHba); + static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice); + static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd); +-static s32 adpt_scsi_register(adpt_hba* pHba); ++static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht); + static s32 adpt_hba_reset(adpt_hba* pHba); + static s32 adpt_i2o_reset_hba(adpt_hba* pHba); + static s32 adpt_rescan(adpt_hba* pHba); +@@ -295,7 +299,7 @@ static void adpt_i2o_delete_hba(adpt_hba + static void adpt_inquiry(adpt_hba* pHba); + static void adpt_fail_posted_scbs(adpt_hba* pHba); + static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun); +-static int adpt_install_hba(struct pci_dev* pDev) ; ++static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ; + static int adpt_i2o_online_hba(adpt_hba* pHba); + static void adpt_i2o_post_wait_complete(u32, int); + static int adpt_i2o_systab_send(adpt_hba* pHba); +@@ -339,4 +343,5 @@ static void adpt_i386_info(sysInfo_S* si + #define FW_DEBUG_BLED_OFFSET 8 + + #define FW_DEBUG_FLAGS_NO_HEADERS_B 0x01 ++#endif /* !HOSTS_C */ + #endif /* _DPT_H */ diff --git a/queue-2.6.23/series b/queue-2.6.23/series index f45b2f932d8..1be08837cc2 100644 --- a/queue-2.6.23/series +++ b/queue-2.6.23/series @@ -26,3 +26,13 @@ kvm-vmx-force-vm86-mode-if-setting-flags-during-real-mode.patch kvm-vmx-reset-mmu-context-when-entering-real-mode.patch x86-setup-add-a-near-jump-to-serialize-cr0-on-386-486.patch isdn-avoid-copying-overly-long-strings.patch +futex-fix-for-futex_wait-signal-stack-corruption.patch +freezer-fix-apm-emulation-breakage.patch +pnp-increase-the-maximum-number-of-resources.patch +wait_task_stopped-pass-correct-exit_code-to-wait_noreap_copyout.patch +fb_ddc-fix-ddc-lines-quirk.patch +revert-dpt_i2o-convert-to-scsi-hotplug-model.patch +esp_scsi-fix-reset-cleanup-spinlock-recursion.patch +nf_nat-fix-memset-error.patch +netfilter-fix-kernel-panic-with-redirect-target.patch +create-sys-...-power-when-config_pm-is-set.patch diff --git a/queue-2.6.23/wait_task_stopped-pass-correct-exit_code-to-wait_noreap_copyout.patch b/queue-2.6.23/wait_task_stopped-pass-correct-exit_code-to-wait_noreap_copyout.patch new file mode 100644 index 00000000000..2ce0bb6499f --- /dev/null +++ b/queue-2.6.23/wait_task_stopped-pass-correct-exit_code-to-wait_noreap_copyout.patch @@ -0,0 +1,47 @@ +From stable-bounces@linux.kernel.org Wed Nov 28 16:27:42 2007 +From: Scott James Remnant +Date: Wed, 28 Nov 2007 16:22:07 -0800 +Subject: wait_task_stopped(): pass correct exit_code to wait_noreap_copyout() +To: torvalds@linux-foundation.org +Cc: stable@kernel.org, akpm@linux-foundation.org, oleg@tv-sign.ru, roland@redhat.com, scott@ubuntu.com +Message-ID: <200711290022.lAT0M7kw026781@imap1.linux-foundation.org> + + +From: Scott James Remnant + +patch e6ceb32aa25fc33f21af84cc7a32fe289b3e860c in mainline. + +In wait_task_stopped() exit_code already contains the right value for the +si_status member of siginfo, and this is simply set in the non WNOWAIT +case. + +If you call waitid() with a stopped or traced process, you'll get the signal +in siginfo.si_status as expected -- however if you call waitid(WNOWAIT) at the +same time, you'll get the signal << 8 | 0x7f + +Pass it unchanged to wait_noreap_copyout(); we would only need to shift it +and add 0x7f if we were returning it in the user status field and that +isn't used for any function that permits WNOWAIT. + +Signed-off-by: Scott James Remnant +Signed-off-by: Oleg Nesterov +Cc: Roland McGrath +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/exit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -1365,7 +1365,7 @@ static int wait_task_stopped(struct task + if (unlikely(!exit_code) || unlikely(p->exit_state)) + goto bail_ref; + return wait_noreap_copyout(p, pid, uid, +- why, (exit_code << 8) | 0x7f, ++ why, exit_code, + infop, ru); + } +