--- /dev/null
+From lenb@kernel.org Mon May 4 16:01:55 2009
+From: Zhang Rui <rui.zhang@intel.com>
+Date: Fri, 01 May 2009 11:12:41 -0400 (EDT)
+Subject: ACPI: Revert conflicting workaround for BIOS w/ mangled PRT entries
+To: stable@kernel.org
+Cc: linux-acpi@vger.kernel.org, tmb@mandriva.org
+Message-ID: <alpine.LFD.2.00.0905011106130.6437@localhost.localdomain>
+
+
+From: Zhang Rui <rui.zhang@intel.com>
+
+upstream 82babbb3887e234c995626e4121d411ea9070ca5
+backported to 2.6.29.2
+
+2f894ef9c8b36a35d80709bedca276d2fc691941
+in Linux-2.6.21 worked around BIOS with mangled _PRT entries:
+http://bugzilla.kernel.org/show_bug.cgi?id=6859
+
+d0e184abc5983281ef189db2c759d65d56eb1b80
+worked around the same issue via ACPICA, and shipped in 2.6.27.
+
+Unfortunately the two workarounds conflict:
+http://bugzilla.kernel.org/show_bug.cgi?id=12270
+
+So revert the Linux specific one.
+
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/acpica/rscreate.c | 27 ++-------------------------
+ 1 file changed, 2 insertions(+), 25 deletions(-)
+
+--- a/drivers/acpi/acpica/rscreate.c
++++ b/drivers/acpi/acpica/rscreate.c
+@@ -191,8 +191,6 @@ acpi_rs_create_pci_routing_table(union a
+ user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
+
+ for (index = 0; index < number_of_elements; index++) {
+- int source_name_index = 2;
+- int source_index_index = 3;
+
+ /*
+ * Point user_prt past this current structure
+@@ -261,27 +259,6 @@ acpi_rs_create_pci_routing_table(union a
+ return_ACPI_STATUS(AE_BAD_DATA);
+ }
+
+- /*
+- * If BIOS erroneously reversed the _PRT source_name and source_index,
+- * then reverse them back.
+- */
+- if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
+- ACPI_TYPE_INTEGER) {
+- if (acpi_gbl_enable_interpreter_slack) {
+- source_name_index = 3;
+- source_index_index = 2;
+- printk(KERN_WARNING
+- "ACPI: Handling Garbled _PRT entry\n");
+- } else {
+- ACPI_ERROR((AE_INFO,
+- "(PRT[%X].source_index) Need Integer, found %s",
+- index,
+- acpi_ut_get_object_type_name
+- (sub_object_list[3])));
+- return_ACPI_STATUS(AE_BAD_DATA);
+- }
+- }
+-
+ user_prt->pin = (u32) obj_desc->integer.value;
+
+ /*
+@@ -305,7 +282,7 @@ acpi_rs_create_pci_routing_table(union a
+ * 3) Third subobject: Dereference the PRT.source_name
+ * The name may be unresolved (slack mode), so allow a null object
+ */
+- obj_desc = sub_object_list[source_name_index];
++ obj_desc = sub_object_list[2];
+ if (obj_desc) {
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+@@ -379,7 +356,7 @@ acpi_rs_create_pci_routing_table(union a
+
+ /* 4) Fourth subobject: Dereference the PRT.source_index */
+
+- obj_desc = sub_object_list[source_index_index];
++ obj_desc = sub_object_list[3];
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ ACPI_ERROR((AE_INFO,
+ "(PRT[%X].SourceIndex) Need Integer, found %s",
--- /dev/null
+From jwboyer@linux.vnet.ibm.com Mon May 4 16:02:51 2009
+From: Josh Boyer <jwboyer@linux.vnet.ibm.com>
+Date: Tue, 28 Apr 2009 11:15:59 -0400
+Subject: powerpc: Sanitize stack pointer in signal handling code
+To: stable@kernel.org
+Cc: benh@kernel.crashing.org
+Message-ID: <20090428151559.GC5281@yoda.jdub.homelinux.org>
+Content-Disposition: inline
+
+From: Josh Boyer <jwboyer@linux.vnet.ibm.com>
+
+This has been backported to 2.6.29.x from commit efbda86098 in Linus' tree
+
+On powerpc64 machines running 32-bit userspace, we can get garbage bits in the
+stack pointer passed into the kernel. Most places handle this correctly, but
+the signal handling code uses the passed value directly for allocating signal
+stack frames.
+
+This fixes the issue by introducing a get_clean_sp function that returns a
+sanitized stack pointer. For 32-bit tasks on a 64-bit kernel, the stack
+pointer is masked correctly. In all other cases, the stack pointer is simply
+returned.
+
+Additionally, we pass an 'is_32' parameter to get_sigframe now in order to
+get the properly sanitized stack. The callers are know to be 32 or 64-bit
+statically.
+
+Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/include/asm/processor.h | 19 +++++++++++++++++++
+ arch/powerpc/kernel/signal.c | 4 ++--
+ arch/powerpc/kernel/signal.h | 2 +-
+ arch/powerpc/kernel/signal_32.c | 4 ++--
+ arch/powerpc/kernel/signal_64.c | 2 +-
+ 5 files changed, 25 insertions(+), 6 deletions(-)
+
+--- a/arch/powerpc/include/asm/processor.h
++++ b/arch/powerpc/include/asm/processor.h
+@@ -313,6 +313,25 @@ static inline void prefetchw(const void
+ #define HAVE_ARCH_PICK_MMAP_LAYOUT
+ #endif
+
++#ifdef CONFIG_PPC64
++static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
++{
++ unsigned long sp;
++
++ if (is_32)
++ sp = regs->gpr[1] & 0x0ffffffffUL;
++ else
++ sp = regs->gpr[1];
++
++ return sp;
++}
++#else
++static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
++{
++ return regs->gpr[1];
++}
++#endif
++
+ #endif /* __KERNEL__ */
+ #endif /* __ASSEMBLY__ */
+ #endif /* _ASM_POWERPC_PROCESSOR_H */
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig
+
+ /* Set up Signal Frame */
+ /* Put a Real Time Context onto stack */
+- rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf));
++ rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1);
+ addr = rt_sf;
+ if (unlikely(rt_sf == NULL))
+ goto badframe;
+@@ -1182,7 +1182,7 @@ int handle_signal32(unsigned long sig, s
+ unsigned long newsp = 0;
+
+ /* Set up Signal Frame */
+- frame = get_sigframe(ka, regs, sizeof(*frame));
++ frame = get_sigframe(ka, regs, sizeof(*frame), 1);
+ if (unlikely(frame == NULL))
+ goto badframe;
+ sc = (struct sigcontext __user *) &frame->sctx;
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -402,7 +402,7 @@ int handle_rt_signal64(int signr, struct
+ unsigned long newsp = 0;
+ long err = 0;
+
+- frame = get_sigframe(ka, regs, sizeof(*frame));
++ frame = get_sigframe(ka, regs, sizeof(*frame), 0);
+ if (unlikely(frame == NULL))
+ goto badframe;
+
+--- a/arch/powerpc/kernel/signal.c
++++ b/arch/powerpc/kernel/signal.c
+@@ -26,12 +26,12 @@ int show_unhandled_signals = 0;
+ * Allocate space for the signal frame
+ */
+ void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+- size_t frame_size)
++ size_t frame_size, int is_32)
+ {
+ unsigned long oldsp, newsp;
+
+ /* Default to using normal stack */
+- oldsp = regs->gpr[1];
++ oldsp = get_clean_sp(regs, is_32);
+
+ /* Check for alt stack */
+ if ((ka->sa.sa_flags & SA_ONSTACK) &&
+--- a/arch/powerpc/kernel/signal.h
++++ b/arch/powerpc/kernel/signal.h
+@@ -15,7 +15,7 @@
+ extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
+
+ extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+- size_t frame_size);
++ size_t frame_size, int is_32);
+ extern void restore_sigmask(sigset_t *set);
+
+ extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
--- /dev/null
+From stern@rowland.harvard.edu Mon May 4 16:00:35 2009
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 4 May 2009 11:30:32 -0400 (EDT)
+Subject: USB: serial: fix lifetime and locking problems
+To: stable@kernel.org
+Message-ID: <Pine.LNX.4.44L0.0905041130110.6437-100000@iolanthe.rowland.org>
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+This is commit 2d93148ab6988cad872e65d694c95e8944e1b626 back-ported to
+2.6.29.
+
+This patch (as1229-3) fixes a few lifetime and locking problems in the
+usb-serial driver. The main symptom is that an invalid kevent is
+created when the serial device is unplugged while a connection is
+active.
+
+ Ports should be unregistered when device is disconnected,
+ not when the parent usb_serial structure is deallocated.
+
+ Each open file should hold a reference to the corresponding
+ port structure, and the reference should be released when
+ the file is closed.
+
+ serial->disc_mutex should be acquired in serial_open(), to
+ resolve the classic race between open and disconnect.
+
+ serial_close() doesn't need to hold both serial->disc_mutex
+ and port->mutex at the same time.
+
+ Release the subdriver's module reference only after releasing
+ all the other references, in case one of the release routines
+ needs to invoke some code in the subdriver module.
+
+ Replace a call to flush_scheduled_work() (which is prone to
+ deadlocks) with cancel_work_sync(). Also, add a call to
+ cancel_work_sync() in the disconnect routine.
+
+ Reduce the scope of serial->disc_mutex in serial_disconnect().
+ The only place it really needs to protect is where the
+ "disconnected" flag is set.
+
+ Call the shutdown method from within serial_disconnect()
+ instead of destroy_serial(), because some subdrivers expect
+ the port data structures still to be in existence when
+ their shutdown method runs.
+
+This fixes the bug reported in
+
+ http://bugs.freedesktop.org/show_bug.cgi?id=20703
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+
+---
+ drivers/usb/serial/usb-serial.c | 99 +++++++++++++++++++++++++++-------------
+ 1 file changed, 68 insertions(+), 31 deletions(-)
+
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -136,22 +136,10 @@ static void destroy_serial(struct kref *
+
+ dbg("%s - %s", __func__, serial->type->description);
+
+- serial->type->shutdown(serial);
+-
+ /* return the minor range that this device had */
+ if (serial->minor != SERIAL_TTY_NO_MINOR)
+ return_serial(serial);
+
+- for (i = 0; i < serial->num_ports; ++i)
+- serial->port[i]->port.count = 0;
+-
+- /* the ports are cleaned up and released in port_release() */
+- for (i = 0; i < serial->num_ports; ++i)
+- if (serial->port[i]->dev.parent != NULL) {
+- device_unregister(&serial->port[i]->dev);
+- serial->port[i] = NULL;
+- }
+-
+ /* If this is a "fake" port, we have to clean it up here, as it will
+ * not get cleaned up in port_release() as it was never registered with
+ * the driver core */
+@@ -186,7 +174,7 @@ static int serial_open (struct tty_struc
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ unsigned int portNumber;
+- int retval;
++ int retval = 0;
+
+ dbg("%s", __func__);
+
+@@ -197,16 +185,24 @@ static int serial_open (struct tty_struc
+ return -ENODEV;
+ }
+
++ mutex_lock(&serial->disc_mutex);
+ portNumber = tty->index - serial->minor;
+ port = serial->port[portNumber];
+- if (!port) {
++ if (!port || serial->disconnected)
+ retval = -ENODEV;
+- goto bailout_kref_put;
+- }
++ else
++ get_device(&port->dev);
++ /*
++ * Note: Our locking order requirement does not allow port->mutex
++ * to be acquired while serial->disc_mutex is held.
++ */
++ mutex_unlock(&serial->disc_mutex);
++ if (retval)
++ goto bailout_serial_put;
+
+ if (mutex_lock_interruptible(&port->mutex)) {
+ retval = -ERESTARTSYS;
+- goto bailout_kref_put;
++ goto bailout_port_put;
+ }
+
+ ++port->port.count;
+@@ -226,14 +222,20 @@ static int serial_open (struct tty_struc
+ goto bailout_mutex_unlock;
+ }
+
+- retval = usb_autopm_get_interface(serial->interface);
++ mutex_lock(&serial->disc_mutex);
++ if (serial->disconnected)
++ retval = -ENODEV;
++ else
++ retval = usb_autopm_get_interface(serial->interface);
+ if (retval)
+ goto bailout_module_put;
++
+ /* only call the device specific open if this
+ * is the first time the port is opened */
+ retval = serial->type->open(tty, port, filp);
+ if (retval)
+ goto bailout_interface_put;
++ mutex_unlock(&serial->disc_mutex);
+ }
+
+ mutex_unlock(&port->mutex);
+@@ -242,13 +244,16 @@ static int serial_open (struct tty_struc
+ bailout_interface_put:
+ usb_autopm_put_interface(serial->interface);
+ bailout_module_put:
++ mutex_unlock(&serial->disc_mutex);
+ module_put(serial->type->driver.owner);
+ bailout_mutex_unlock:
+ port->port.count = 0;
+ tty->driver_data = NULL;
+ tty_port_tty_set(&port->port, NULL);
+ mutex_unlock(&port->mutex);
+-bailout_kref_put:
++bailout_port_put:
++ put_device(&port->dev);
++bailout_serial_put:
+ usb_serial_put(serial);
+ return retval;
+ }
+@@ -256,6 +261,9 @@ bailout_kref_put:
+ static void serial_close(struct tty_struct *tty, struct file *filp)
+ {
+ struct usb_serial_port *port = tty->driver_data;
++ struct usb_serial *serial;
++ struct module *owner;
++ int count;
+
+ if (!port)
+ return;
+@@ -263,6 +271,8 @@ static void serial_close(struct tty_stru
+ dbg("%s - port %d", __func__, port->number);
+
+ mutex_lock(&port->mutex);
++ serial = port->serial;
++ owner = serial->type->driver.owner;
+
+ if (port->port.count == 0) {
+ mutex_unlock(&port->mutex);
+@@ -275,7 +285,7 @@ static void serial_close(struct tty_stru
+ * this before we drop the port count. The call is protected
+ * by the port mutex
+ */
+- port->serial->type->close(tty, port, filp);
++ serial->type->close(tty, port, filp);
+
+ if (port->port.count == (port->console ? 2 : 1)) {
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+@@ -289,17 +299,23 @@ static void serial_close(struct tty_stru
+ }
+ }
+
+- if (port->port.count == 1) {
+- mutex_lock(&port->serial->disc_mutex);
+- if (!port->serial->disconnected)
+- usb_autopm_put_interface(port->serial->interface);
+- mutex_unlock(&port->serial->disc_mutex);
+- module_put(port->serial->type->driver.owner);
+- }
+ --port->port.count;
+-
++ count = port->port.count;
+ mutex_unlock(&port->mutex);
+- usb_serial_put(port->serial);
++ put_device(&port->dev);
++
++ /* Mustn't dereference port any more */
++ if (count == 0) {
++ mutex_lock(&serial->disc_mutex);
++ if (!serial->disconnected)
++ usb_autopm_put_interface(serial->interface);
++ mutex_unlock(&serial->disc_mutex);
++ }
++ usb_serial_put(serial);
++
++ /* Mustn't dereference serial any more */
++ if (count == 0)
++ module_put(owner);
+ }
+
+ static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+@@ -548,7 +564,13 @@ static void kill_traffic(struct usb_seri
+
+ static void port_free(struct usb_serial_port *port)
+ {
++ /*
++ * Stop all the traffic before cancelling the work, so that
++ * nobody will restart it by calling usb_serial_port_softint.
++ */
+ kill_traffic(port);
++ cancel_work_sync(&port->work);
++
+ usb_free_urb(port->read_urb);
+ usb_free_urb(port->write_urb);
+ usb_free_urb(port->interrupt_in_urb);
+@@ -557,7 +579,6 @@ static void port_free(struct usb_serial_
+ kfree(port->bulk_out_buffer);
+ kfree(port->interrupt_in_buffer);
+ kfree(port->interrupt_out_buffer);
+- flush_scheduled_work(); /* port->work */
+ kfree(port);
+ }
+
+@@ -1042,6 +1063,12 @@ void usb_serial_disconnect(struct usb_in
+ usb_set_intfdata(interface, NULL);
+ /* must set a flag, to signal subdrivers */
+ serial->disconnected = 1;
++ mutex_unlock(&serial->disc_mutex);
++
++ /* Unfortunately, many of the sub-drivers expect the port structures
++ * to exist when their shutdown method is called, so we have to go
++ * through this awkward two-step unregistration procedure.
++ */
+ for (i = 0; i < serial->num_ports; ++i) {
+ port = serial->port[i];
+ if (port) {
+@@ -1051,11 +1078,21 @@ void usb_serial_disconnect(struct usb_in
+ tty_kref_put(tty);
+ }
+ kill_traffic(port);
++ cancel_work_sync(&port->work);
++ device_del(&port->dev);
+ }
+ }
++ serial->type->shutdown(serial);
++ for (i = 0; i < serial->num_ports; ++i) {
++ port = serial->port[i];
++ if (port) {
++ put_device(&port->dev);
++ serial->port[i] = NULL;
++ }
++ }
++
+ /* let the last holder of this object
+ * cause it to be cleaned up */
+- mutex_unlock(&serial->disc_mutex);
+ usb_serial_put(serial);
+ dev_info(dev, "device disconnected\n");
+ }