From da230ba222210f516661f60e9286a1224f7d3ffb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 15 Jun 2013 10:02:39 -0700 Subject: [PATCH] 3.9-stable patches added patches: powerpc-fix-emulation-of-illegal-instructions-on-powernv-platform.patch powerpc-fix-missing-delayed-calls-to-irq_work.patch powerpc-fix-stack-overflow-crash-in-resume_kernel-when-ftracing.patch usb-chipidea-fix-id-change-handling.patch usb-f81232-fix-device-initialisation-at-open.patch usb-pl2303-fix-device-initialisation-at-open.patch usb-spcp8x5-fix-device-initialisation-at-open.patch --- ...gal-instructions-on-powernv-platform.patch | 61 +++++++++ ...ix-missing-delayed-calls-to-irq_work.patch | 40 ++++++ ...crash-in-resume_kernel-when-ftracing.patch | 116 ++++++++++++++++++ queue-3.9/series | 7 ++ .../usb-chipidea-fix-id-change-handling.patch | 33 +++++ ...32-fix-device-initialisation-at-open.patch | 52 ++++++++ ...03-fix-device-initialisation-at-open.patch | 69 +++++++++++ ...x5-fix-device-initialisation-at-open.patch | 65 ++++++++++ 8 files changed, 443 insertions(+) create mode 100644 queue-3.9/powerpc-fix-emulation-of-illegal-instructions-on-powernv-platform.patch create mode 100644 queue-3.9/powerpc-fix-missing-delayed-calls-to-irq_work.patch create mode 100644 queue-3.9/powerpc-fix-stack-overflow-crash-in-resume_kernel-when-ftracing.patch create mode 100644 queue-3.9/usb-chipidea-fix-id-change-handling.patch create mode 100644 queue-3.9/usb-f81232-fix-device-initialisation-at-open.patch create mode 100644 queue-3.9/usb-pl2303-fix-device-initialisation-at-open.patch create mode 100644 queue-3.9/usb-spcp8x5-fix-device-initialisation-at-open.patch diff --git a/queue-3.9/powerpc-fix-emulation-of-illegal-instructions-on-powernv-platform.patch b/queue-3.9/powerpc-fix-emulation-of-illegal-instructions-on-powernv-platform.patch new file mode 100644 index 00000000000..4b4c32f475e --- /dev/null +++ b/queue-3.9/powerpc-fix-emulation-of-illegal-instructions-on-powernv-platform.patch @@ -0,0 +1,61 @@ +From bf593907f7236e95698a76b7c7a2bbf8b1165327 Mon Sep 17 00:00:00 2001 +From: Paul Mackerras +Date: Fri, 14 Jun 2013 20:07:41 +1000 +Subject: powerpc: Fix emulation of illegal instructions on PowerNV platform + +From: Paul Mackerras + +commit bf593907f7236e95698a76b7c7a2bbf8b1165327 upstream. + +Normally, the kernel emulates a few instructions that are unimplemented +on some processors (e.g. the old dcba instruction), or privileged (e.g. +mfpvr). The emulation of unimplemented instructions is currently not +working on the PowerNV platform. The reason is that on these machines, +unimplemented and illegal instructions cause a hypervisor emulation +assist interrupt, rather than a program interrupt as on older CPUs. +Our vector for the emulation assist interrupt just calls +program_check_exception() directly, without setting the bit in SRR1 +that indicates an illegal instruction interrupt. This fixes it by +making the emulation assist interrupt set that bit before calling +program_check_interrupt(). With this, old programs that use no-longer +implemented instructions such as dcba now work again. + +Signed-off-by: Paul Mackerras +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/exceptions-64s.S | 2 +- + arch/powerpc/kernel/traps.c | 10 ++++++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/exceptions-64s.S ++++ b/arch/powerpc/kernel/exceptions-64s.S +@@ -707,7 +707,7 @@ machine_check_common: + STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) + STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) + STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) +- STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception) ++ STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt) + STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) + #ifdef CONFIG_PPC_DOORBELL + STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception) +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -1142,6 +1142,16 @@ void __kprobes program_check_exception(s + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); + } + ++/* ++ * This occurs when running in hypervisor mode on POWER6 or later ++ * and an illegal instruction is encountered. ++ */ ++void __kprobes emulation_assist_interrupt(struct pt_regs *regs) ++{ ++ regs->msr |= REASON_ILLEGAL; ++ program_check_exception(regs); ++} ++ + void alignment_exception(struct pt_regs *regs) + { + int sig, code, fixed = 0; diff --git a/queue-3.9/powerpc-fix-missing-delayed-calls-to-irq_work.patch b/queue-3.9/powerpc-fix-missing-delayed-calls-to-irq_work.patch new file mode 100644 index 00000000000..51a9b5c216a --- /dev/null +++ b/queue-3.9/powerpc-fix-missing-delayed-calls-to-irq_work.patch @@ -0,0 +1,40 @@ +From 230b3034793247f61e6a0b08c44cf415f6d92981 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Sat, 15 Jun 2013 12:13:40 +1000 +Subject: powerpc: Fix missing/delayed calls to irq_work + +From: Benjamin Herrenschmidt + +commit 230b3034793247f61e6a0b08c44cf415f6d92981 upstream. + +When replaying interrupts (as a result of the interrupt occurring +while soft-disabled), in the case of the decrementer, we are exclusively +testing for a pending timer target. However we also use decrementer +interrupts to trigger the new "irq_work", which in this case would +be missed. + +This change the logic to force a replay in both cases of a timer +boundary reached and a decrementer interrupt having actually occurred +while disabled. The former test is still useful to catch cases where +a CPU having been hard-disabled for a long time completely misses the +interrupt due to a decrementer rollover. + +Signed-off-by: Benjamin Herrenschmidt +Tested-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/irq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/irq.c ++++ b/arch/powerpc/kernel/irq.c +@@ -162,7 +162,7 @@ notrace unsigned int __check_irq_replay( + * in case we also had a rollover while hard disabled + */ + local_paca->irq_happened &= ~PACA_IRQ_DEC; +- if (decrementer_check_overflow()) ++ if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow()) + return 0x900; + + /* Finally check if an external interrupt happened */ diff --git a/queue-3.9/powerpc-fix-stack-overflow-crash-in-resume_kernel-when-ftracing.patch b/queue-3.9/powerpc-fix-stack-overflow-crash-in-resume_kernel-when-ftracing.patch new file mode 100644 index 00000000000..2bd7e1f1b11 --- /dev/null +++ b/queue-3.9/powerpc-fix-stack-overflow-crash-in-resume_kernel-when-ftracing.patch @@ -0,0 +1,116 @@ +From 0e37739b1c96d65e6433998454985de994383019 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Thu, 13 Jun 2013 21:04:56 +1000 +Subject: powerpc: Fix stack overflow crash in resume_kernel when ftracing + +From: Michael Ellerman + +commit 0e37739b1c96d65e6433998454985de994383019 upstream. + +It's possible for us to crash when running with ftrace enabled, eg: + + Bad kernel stack pointer bffffd12 at c00000000000a454 + cpu 0x3: Vector: 300 (Data Access) at [c00000000ffe3d40] + pc: c00000000000a454: resume_kernel+0x34/0x60 + lr: c00000000000335c: performance_monitor_common+0x15c/0x180 + sp: bffffd12 + msr: 8000000000001032 + dar: bffffd12 + dsisr: 42000000 + +If we look at current's stack (paca->__current->stack) we see it is +equal to c0000002ecab0000. Our stack is 16K, and comparing to +paca->kstack (c0000002ecab3e30) we can see that we have overflowed our +kernel stack. This leads to us writing over our struct thread_info, and +in this case we have corrupted thread_info->flags and set +_TIF_EMULATE_STACK_STORE. + +Dumping the stack we see: + + 3:mon> t c0000002ecab0000 + [c0000002ecab0000] c00000000002131c .performance_monitor_exception+0x5c/0x70 + [c0000002ecab0080] c00000000000335c performance_monitor_common+0x15c/0x180 + --- Exception: f01 (Performance Monitor) at c0000000000fb2ec .trace_hardirqs_off+0x1c/0x30 + [c0000002ecab0370] c00000000016fdb0 .trace_graph_entry+0xb0/0x280 (unreliable) + [c0000002ecab0410] c00000000003d038 .prepare_ftrace_return+0x98/0x130 + [c0000002ecab04b0] c00000000000a920 .ftrace_graph_caller+0x14/0x28 + [c0000002ecab0520] c0000000000d6b58 .idle_cpu+0x18/0x90 + [c0000002ecab05a0] c00000000000a934 .return_to_handler+0x0/0x34 + [c0000002ecab0620] c00000000001e660 .timer_interrupt+0x160/0x300 + [c0000002ecab06d0] c0000000000025dc decrementer_common+0x15c/0x180 + --- Exception: 901 (Decrementer) at c0000000000104d4 .arch_local_irq_restore+0x74/0xa0 + [c0000002ecab09c0] c0000000000fe044 .trace_hardirqs_on+0x14/0x30 (unreliable) + [c0000002ecab0fb0] c00000000016fe3c .trace_graph_entry+0x13c/0x280 + [c0000002ecab1050] c00000000003d038 .prepare_ftrace_return+0x98/0x130 + [c0000002ecab10f0] c00000000000a920 .ftrace_graph_caller+0x14/0x28 + [c0000002ecab1160] c0000000000161f0 .__ppc64_runlatch_on+0x10/0x40 + [c0000002ecab11d0] c00000000000a934 .return_to_handler+0x0/0x34 + --- Exception: 901 (Decrementer) at c0000000000104d4 .arch_local_irq_restore+0x74/0xa0 + + ... and so on + +__ppc64_runlatch_on() is called from RUNLATCH_ON in the exception entry +path. At that point the irq state is not consistent, ie. interrupts are +hard disabled (by the exception entry), but the paca soft-enabled flag +may be out of sync. + +This leads to the local_irq_restore() in trace_graph_entry() actually +enabling interrupts, which we do not want. Because we have not yet +reprogrammed the decrementer we immediately take another decrementer +exception, and recurse. + +The fix is twofold. Firstly make sure we call DISABLE_INTS before +calling RUNLATCH_ON. The badly named DISABLE_INTS actually reconciles +the irq state in the paca with the hardware, making it safe again to +call local_irq_save/restore(). + +Although that should be sufficient to fix the bug, we also mark the +runlatch routines as notrace. They are called very early in the +exception entry and we are asking for trouble tracing them. They are +also fairly uninteresting and tracing them just adds unnecessary +overhead. + +[ This regression was introduced by fe1952fc0afb9a2e4c79f103c08aef5d13db1873 + "powerpc: Rework runlatch code" by myself --BenH +] + +Signed-off-by: Michael Ellerman +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/exception-64s.h | 2 +- + arch/powerpc/kernel/process.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/powerpc/include/asm/exception-64s.h ++++ b/arch/powerpc/include/asm/exception-64s.h +@@ -513,7 +513,7 @@ label##_common: \ + */ + #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ + EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ +- FINISH_NAP;RUNLATCH_ON;DISABLE_INTS) ++ FINISH_NAP;DISABLE_INTS;RUNLATCH_ON) + + /* + * When the idle code in power4_idle puts the CPU into NAP mode, +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -1371,7 +1371,7 @@ EXPORT_SYMBOL(dump_stack); + + #ifdef CONFIG_PPC64 + /* Called with hard IRQs off */ +-void __ppc64_runlatch_on(void) ++void notrace __ppc64_runlatch_on(void) + { + struct thread_info *ti = current_thread_info(); + unsigned long ctrl; +@@ -1384,7 +1384,7 @@ void __ppc64_runlatch_on(void) + } + + /* Called with hard IRQs off */ +-void __ppc64_runlatch_off(void) ++void notrace __ppc64_runlatch_off(void) + { + struct thread_info *ti = current_thread_info(); + unsigned long ctrl; diff --git a/queue-3.9/series b/queue-3.9/series index 06e4944ff64..a19b8ec16e6 100644 --- a/queue-3.9/series +++ b/queue-3.9/series @@ -37,3 +37,10 @@ libceph-add-update_authorizer-auth-method.patch libceph-wrap-auth-ops-in-wrapper-functions.patch libceph-wrap-auth-methods-in-a-mutex.patch modify-uefi-anti-bricking-code.patch +powerpc-fix-stack-overflow-crash-in-resume_kernel-when-ftracing.patch +powerpc-fix-emulation-of-illegal-instructions-on-powernv-platform.patch +powerpc-fix-missing-delayed-calls-to-irq_work.patch +usb-chipidea-fix-id-change-handling.patch +usb-pl2303-fix-device-initialisation-at-open.patch +usb-f81232-fix-device-initialisation-at-open.patch +usb-spcp8x5-fix-device-initialisation-at-open.patch diff --git a/queue-3.9/usb-chipidea-fix-id-change-handling.patch b/queue-3.9/usb-chipidea-fix-id-change-handling.patch new file mode 100644 index 00000000000..59456790b01 --- /dev/null +++ b/queue-3.9/usb-chipidea-fix-id-change-handling.patch @@ -0,0 +1,33 @@ +From 0c3f3dc68bb6e6950e8cd7851e7778c550e8dfb4 Mon Sep 17 00:00:00 2001 +From: Alexander Shishkin +Date: Tue, 11 Jun 2013 13:41:48 +0300 +Subject: usb: chipidea: fix id change handling + +From: Alexander Shishkin + +commit 0c3f3dc68bb6e6950e8cd7851e7778c550e8dfb4 upstream. + +Re-enable chipidea irq even if there's no role changing to do. This is +a problem since b183c19f ("USB: chipidea: re-order irq handling to avoid +unhandled irqs"); when it manifests, chipidea irq gets disabled for good. + +Signed-off-by: Alexander Shishkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -279,8 +279,9 @@ static void ci_role_work(struct work_str + + ci_role_stop(ci); + ci_role_start(ci, role); +- enable_irq(ci->irq); + } ++ ++ enable_irq(ci->irq); + } + + static ssize_t show_role(struct device *dev, struct device_attribute *attr, diff --git a/queue-3.9/usb-f81232-fix-device-initialisation-at-open.patch b/queue-3.9/usb-f81232-fix-device-initialisation-at-open.patch new file mode 100644 index 00000000000..ed703c5f9af --- /dev/null +++ b/queue-3.9/usb-f81232-fix-device-initialisation-at-open.patch @@ -0,0 +1,52 @@ +From 21886725d58e92188159731c7c1aac803dd6b9dc Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 10 Jun 2013 18:29:37 +0200 +Subject: USB: f81232: fix device initialisation at open + +From: Johan Hovold + +commit 21886725d58e92188159731c7c1aac803dd6b9dc upstream. + +Do not use uninitialised termios data to determine when to configure the +device at open. + +This also prevents stack data from leaking to userspace. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/f81232.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/f81232.c ++++ b/drivers/usb/serial/f81232.c +@@ -165,11 +165,12 @@ static void f81232_set_termios(struct tt + /* FIXME - Stubbed out for now */ + + /* Don't change anything if nothing has changed */ +- if (!tty_termios_hw_change(&tty->termios, old_termios)) ++ if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) + return; + + /* Do the real work here... */ +- tty_termios_copy_hw(&tty->termios, old_termios); ++ if (old_termios) ++ tty_termios_copy_hw(&tty->termios, old_termios); + } + + static int f81232_tiocmget(struct tty_struct *tty) +@@ -187,12 +188,11 @@ static int f81232_tiocmset(struct tty_st + + static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) + { +- struct ktermios tmp_termios; + int result; + + /* Setup termios */ + if (tty) +- f81232_set_termios(tty, port, &tmp_termios); ++ f81232_set_termios(tty, port, NULL); + + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (result) { diff --git a/queue-3.9/usb-pl2303-fix-device-initialisation-at-open.patch b/queue-3.9/usb-pl2303-fix-device-initialisation-at-open.patch new file mode 100644 index 00000000000..c1a24541740 --- /dev/null +++ b/queue-3.9/usb-pl2303-fix-device-initialisation-at-open.patch @@ -0,0 +1,69 @@ +From 2d8f4447b58bba5f8cb895c07690434c02307eaf Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 10 Jun 2013 18:29:38 +0200 +Subject: USB: pl2303: fix device initialisation at open + +From: Johan Hovold + +commit 2d8f4447b58bba5f8cb895c07690434c02307eaf upstream. + +Do not use uninitialised termios data to determine when to configure the +device at open. + +This also prevents stack data from leaking to userspace in the OOM error +path. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/pl2303.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -283,7 +283,7 @@ static void pl2303_set_termios(struct tt + serial settings even to the same values as before. Thus + we actually need to filter in this specific case */ + +- if (!tty_termios_hw_change(&tty->termios, old_termios)) ++ if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) + return; + + cflag = tty->termios.c_cflag; +@@ -292,7 +292,8 @@ static void pl2303_set_termios(struct tt + if (!buf) { + dev_err(&port->dev, "%s - out of memory.\n", __func__); + /* Report back no change occurred */ +- tty->termios = *old_termios; ++ if (old_termios) ++ tty->termios = *old_termios; + return; + } + +@@ -432,7 +433,7 @@ static void pl2303_set_termios(struct tt + control = priv->line_control; + if ((cflag & CBAUD) == B0) + priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); +- else if ((old_termios->c_cflag & CBAUD) == B0) ++ else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) + priv->line_control |= (CONTROL_DTR | CONTROL_RTS); + if (control != priv->line_control) { + control = priv->line_control; +@@ -491,7 +492,6 @@ static void pl2303_close(struct usb_seri + + static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) + { +- struct ktermios tmp_termios; + struct usb_serial *serial = port->serial; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); + int result; +@@ -507,7 +507,7 @@ static int pl2303_open(struct tty_struct + + /* Setup termios */ + if (tty) +- pl2303_set_termios(tty, port, &tmp_termios); ++ pl2303_set_termios(tty, port, NULL); + + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (result) { diff --git a/queue-3.9/usb-spcp8x5-fix-device-initialisation-at-open.patch b/queue-3.9/usb-spcp8x5-fix-device-initialisation-at-open.patch new file mode 100644 index 00000000000..182ffb769d3 --- /dev/null +++ b/queue-3.9/usb-spcp8x5-fix-device-initialisation-at-open.patch @@ -0,0 +1,65 @@ +From 5e4211f1c47560c36a8b3d4544dfd866dcf7ccd0 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 10 Jun 2013 18:29:39 +0200 +Subject: USB: spcp8x5: fix device initialisation at open + +From: Johan Hovold + +commit 5e4211f1c47560c36a8b3d4544dfd866dcf7ccd0 upstream. + +Do not use uninitialised termios data to determine when to configure the +device at open. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/spcp8x5.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/spcp8x5.c ++++ b/drivers/usb/serial/spcp8x5.c +@@ -314,7 +314,6 @@ static void spcp8x5_set_termios(struct t + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int cflag = tty->termios.c_cflag; +- unsigned int old_cflag = old_termios->c_cflag; + unsigned short uartdata; + unsigned char buf[2] = {0, 0}; + int baud; +@@ -323,15 +322,15 @@ static void spcp8x5_set_termios(struct t + + + /* check that they really want us to change something */ +- if (!tty_termios_hw_change(&tty->termios, old_termios)) ++ if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) + return; + + /* set DTR/RTS active */ + spin_lock_irqsave(&priv->lock, flags); + control = priv->line_control; +- if ((old_cflag & CBAUD) == B0) { ++ if (old_termios && (old_termios->c_cflag & CBAUD) == B0) { + priv->line_control |= MCR_DTR; +- if (!(old_cflag & CRTSCTS)) ++ if (!(old_termios->c_cflag & CRTSCTS)) + priv->line_control |= MCR_RTS; + } + if (control != priv->line_control) { +@@ -421,7 +420,6 @@ static void spcp8x5_set_termios(struct t + * status of the device. */ + static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) + { +- struct ktermios tmp_termios; + struct usb_serial *serial = port->serial; + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + int ret; +@@ -442,7 +440,7 @@ static int spcp8x5_open(struct tty_struc + + /* Setup termios */ + if (tty) +- spcp8x5_set_termios(tty, port, &tmp_termios); ++ spcp8x5_set_termios(tty, port, NULL); + + spcp8x5_get_msr(serial->dev, &status, priv->type); + -- 2.47.3