From: Greg Kroah-Hartman Date: Fri, 7 Sep 2012 17:24:17 +0000 (-0700) Subject: 3.5-stable patches X-Git-Tag: v3.5.4~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a7bd3ff680bc0297cee1777af66d26271e2c49cc;p=thirdparty%2Fkernel%2Fstable-queue.git 3.5-stable patches added patches: powerpc-fix-dscr-inheritance-in-copy_thread.patch powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch powerpc-restore-correct-dscr-in-context-switch.patch powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch remove-user-triggerable-bug-from-mpol_to_str.patch --- diff --git a/queue-3.5/powerpc-fix-dscr-inheritance-in-copy_thread.patch b/queue-3.5/powerpc-fix-dscr-inheritance-in-copy_thread.patch new file mode 100644 index 00000000000..35b157f6dc7 --- /dev/null +++ b/queue-3.5/powerpc-fix-dscr-inheritance-in-copy_thread.patch @@ -0,0 +1,50 @@ +From 1021cb268b3025573c4811f1dee4a11260c4507b Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Mon, 3 Sep 2012 16:49:47 +0000 +Subject: powerpc: Fix DSCR inheritance in copy_thread() + +From: Anton Blanchard + +commit 1021cb268b3025573c4811f1dee4a11260c4507b upstream. + +If the default DSCR is non zero we set thread.dscr_inherit in +copy_thread() meaning the new thread and all its children will ignore +future updates to the default DSCR. This is not intended and is +a change in behaviour that a number of our users have hit. + +We just need to inherit thread.dscr and thread.dscr_inherit from +the parent which ends up being much simpler. + +This was found with the following test case: + +http://ozlabs.org/~anton/junkcode/dscr_default_test.c + +Signed-off-by: Anton Blanchard +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/process.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -802,16 +802,8 @@ int copy_thread(unsigned long clone_flag + #endif /* CONFIG_PPC_STD_MMU_64 */ + #ifdef CONFIG_PPC64 + if (cpu_has_feature(CPU_FTR_DSCR)) { +- if (current->thread.dscr_inherit) { +- p->thread.dscr_inherit = 1; +- p->thread.dscr = current->thread.dscr; +- } else if (0 != dscr_default) { +- p->thread.dscr_inherit = 1; +- p->thread.dscr = dscr_default; +- } else { +- p->thread.dscr_inherit = 0; +- p->thread.dscr = 0; +- } ++ p->thread.dscr_inherit = current->thread.dscr_inherit; ++ p->thread.dscr = current->thread.dscr; + } + #endif + diff --git a/queue-3.5/powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch b/queue-3.5/powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch new file mode 100644 index 00000000000..3d586e11858 --- /dev/null +++ b/queue-3.5/powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch @@ -0,0 +1,58 @@ +From 00ca0de02f80924dfff6b4f630e1dff3db005e35 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Mon, 3 Sep 2012 16:48:46 +0000 +Subject: powerpc: Keep thread.dscr and thread.dscr_inherit in sync + +From: Anton Blanchard + +commit 00ca0de02f80924dfff6b4f630e1dff3db005e35 upstream. + +When we update the DSCR either via emulation of mtspr(DSCR) or via +a change to dscr_default in sysfs we don't update thread.dscr. +We will eventually update it at context switch time but there is +a period where thread.dscr is incorrect. + +If we fork at this point we will copy the old value of thread.dscr +into the child. To avoid this, always keep thread.dscr in sync with +reality. + +This issue was found with the following testcase: + +http://ozlabs.org/~anton/junkcode/dscr_inherit_test.c + +Signed-off-by: Anton Blanchard +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/sysfs.c | 4 +++- + arch/powerpc/kernel/traps.c | 3 ++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/sysfs.c ++++ b/arch/powerpc/kernel/sysfs.c +@@ -196,8 +196,10 @@ static ssize_t show_dscr_default(struct + + static void update_dscr(void *dummy) + { +- if (!current->thread.dscr_inherit) ++ if (!current->thread.dscr_inherit) { ++ current->thread.dscr = dscr_default; + mtspr(SPRN_DSCR, dscr_default); ++ } + } + + static ssize_t __used store_dscr_default(struct device *dev, +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -972,8 +972,9 @@ static int emulate_instruction(struct pt + cpu_has_feature(CPU_FTR_DSCR)) { + PPC_WARN_EMULATED(mtdscr, regs); + rd = (instword >> 21) & 0x1f; +- mtspr(SPRN_DSCR, regs->gpr[rd]); ++ current->thread.dscr = regs->gpr[rd]; + current->thread.dscr_inherit = 1; ++ mtspr(SPRN_DSCR, current->thread.dscr); + return 0; + } + #endif diff --git a/queue-3.5/powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch b/queue-3.5/powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch new file mode 100644 index 00000000000..e8324102aa2 --- /dev/null +++ b/queue-3.5/powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch @@ -0,0 +1,108 @@ +From 9fb1b36ca1234e64a5d1cc573175303395e3354d Mon Sep 17 00:00:00 2001 +From: Paul Mackerras +Date: Tue, 4 Sep 2012 18:33:08 +0000 +Subject: powerpc: Make sure IPI handlers see data written by IPI senders + +From: Paul Mackerras + +commit 9fb1b36ca1234e64a5d1cc573175303395e3354d upstream. + +We have been observing hangs, both of KVM guest vcpu tasks and more +generally, where a process that is woken doesn't properly wake up and +continue to run, but instead sticks in TASK_WAKING state. This +happens because the update of rq->wake_list in ttwu_queue_remote() +is not ordered with the update of ipi_message in +smp_muxed_ipi_message_pass(), and the reading of rq->wake_list in +scheduler_ipi() is not ordered with the reading of ipi_message in +smp_ipi_demux(). Thus it is possible for the IPI receiver not to see +the updated rq->wake_list and therefore conclude that there is nothing +for it to do. + +In order to make sure that anything done before smp_send_reschedule() +is ordered before anything done in the resulting call to scheduler_ipi(), +this adds barriers in smp_muxed_message_pass() and smp_ipi_demux(). +The barrier in smp_muxed_message_pass() is a full barrier to ensure that +there is a full ordering between the smp_send_reschedule() caller and +scheduler_ipi(). In smp_ipi_demux(), we use xchg() rather than +xchg_local() because xchg() includes release and acquire barriers. +Using xchg() rather than xchg_local() makes sense given that +ipi_message is not just accessed locally. + +This moves the barrier between setting the message and calling the +cause_ipi() function into the individual cause_ipi implementations. +Most of them -- those that used outb, out_8 or similar -- already had +a full barrier because out_8 etc. include a sync before the MMIO +store. This adds an explicit barrier in the two remaining cases. + +These changes made no measurable difference to the speed of IPIs as +measured using a simple ping-pong latency test across two CPUs on +different cores of a POWER7 machine. + +The analysis of the reason why processes were not waking up properly +is due to Milton Miller. + +Reported-by: Milton Miller +Signed-off-by: Paul Mackerras +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/dbell.c | 2 ++ + arch/powerpc/kernel/smp.c | 11 +++++++++-- + arch/powerpc/sysdev/xics/icp-hv.c | 6 +++++- + 3 files changed, 16 insertions(+), 3 deletions(-) + +--- a/arch/powerpc/kernel/dbell.c ++++ b/arch/powerpc/kernel/dbell.c +@@ -28,6 +28,8 @@ void doorbell_setup_this_cpu(void) + + void doorbell_cause_ipi(int cpu, unsigned long data) + { ++ /* Order previous accesses vs. msgsnd, which is treated as a store */ ++ mb(); + ppc_msgsnd(PPC_DBELL, 0, data); + } + +--- a/arch/powerpc/kernel/smp.c ++++ b/arch/powerpc/kernel/smp.c +@@ -197,8 +197,15 @@ void smp_muxed_ipi_message_pass(int cpu, + struct cpu_messages *info = &per_cpu(ipi_message, cpu); + char *message = (char *)&info->messages; + ++ /* ++ * Order previous accesses before accesses in the IPI handler. ++ */ ++ smp_mb(); + message[msg] = 1; +- mb(); ++ /* ++ * cause_ipi functions are required to include a full barrier ++ * before doing whatever causes the IPI. ++ */ + smp_ops->cause_ipi(cpu, info->data); + } + +@@ -210,7 +217,7 @@ irqreturn_t smp_ipi_demux(void) + mb(); /* order any irq clear */ + + do { +- all = xchg_local(&info->messages, 0); ++ all = xchg(&info->messages, 0); + + #ifdef __BIG_ENDIAN + if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION))) +--- a/arch/powerpc/sysdev/xics/icp-hv.c ++++ b/arch/powerpc/sysdev/xics/icp-hv.c +@@ -65,7 +65,11 @@ static inline void icp_hv_set_xirr(unsig + static inline void icp_hv_set_qirr(int n_cpu , u8 value) + { + int hw_cpu = get_hard_smp_processor_id(n_cpu); +- long rc = plpar_hcall_norets(H_IPI, hw_cpu, value); ++ long rc; ++ ++ /* Make sure all previous accesses are ordered before IPI sending */ ++ mb(); ++ rc = plpar_hcall_norets(H_IPI, hw_cpu, value); + if (rc != H_SUCCESS) { + pr_err("%s: bad return code qirr cpu=%d hw_cpu=%d mfrr=0x%x " + "returned %ld\n", __func__, n_cpu, hw_cpu, value, rc); diff --git a/queue-3.5/powerpc-restore-correct-dscr-in-context-switch.patch b/queue-3.5/powerpc-restore-correct-dscr-in-context-switch.patch new file mode 100644 index 00000000000..628c0ad9eb2 --- /dev/null +++ b/queue-3.5/powerpc-restore-correct-dscr-in-context-switch.patch @@ -0,0 +1,99 @@ +From 714332858bfd40dcf8f741498336d93875c23aa7 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Mon, 3 Sep 2012 16:51:10 +0000 +Subject: powerpc: Restore correct DSCR in context switch + +From: Anton Blanchard + +commit 714332858bfd40dcf8f741498336d93875c23aa7 upstream. + +During a context switch we always restore the per thread DSCR value. +If we aren't doing explicit DSCR management +(ie thread.dscr_inherit == 0) and the default DSCR changed while +the process has been sleeping we end up with the wrong value. + +Check thread.dscr_inherit and select the default DSCR or per thread +DSCR as required. + +This was found with the following test case, when running with +more threads than CPUs (ie forcing context switching): + +http://ozlabs.org/~anton/junkcode/dscr_default_test.c + +With the four patches applied I can run a combination of all +test cases successfully at the same time: + +http://ozlabs.org/~anton/junkcode/dscr_default_test.c +http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c +http://ozlabs.org/~anton/junkcode/dscr_inherit_test.c + +Signed-off-by: Anton Blanchard +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/asm-offsets.c | 1 + + arch/powerpc/kernel/entry_64.S | 23 +++++++++++++++++------ + 2 files changed, 18 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/kernel/asm-offsets.c ++++ b/arch/powerpc/kernel/asm-offsets.c +@@ -76,6 +76,7 @@ int main(void) + DEFINE(SIGSEGV, SIGSEGV); + DEFINE(NMI_MASK, NMI_MASK); + DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr)); ++ DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit)); + #else + DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); + #endif /* CONFIG_PPC64 */ +--- a/arch/powerpc/kernel/entry_64.S ++++ b/arch/powerpc/kernel/entry_64.S +@@ -369,6 +369,12 @@ _GLOBAL(ret_from_fork) + li r3,0 + b syscall_exit + ++ .section ".toc","aw" ++DSCR_DEFAULT: ++ .tc dscr_default[TC],dscr_default ++ ++ .section ".text" ++ + /* + * This routine switches between two different tasks. The process + * state of one is saved on its kernel stack. Then the state +@@ -508,9 +514,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG + mr r1,r8 /* start using new stack pointer */ + std r7,PACAKSAVE(r13) + +- ld r6,_CCR(r1) +- mtcrf 0xFF,r6 +- + #ifdef CONFIG_ALTIVEC + BEGIN_FTR_SECTION + ld r0,THREAD_VRSAVE(r4) +@@ -519,14 +522,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + #endif /* CONFIG_ALTIVEC */ + #ifdef CONFIG_PPC64 + BEGIN_FTR_SECTION ++ lwz r6,THREAD_DSCR_INHERIT(r4) ++ ld r7,DSCR_DEFAULT@toc(2) + ld r0,THREAD_DSCR(r4) +- cmpd r0,r25 +- beq 1f ++ cmpwi r6,0 ++ bne 1f ++ ld r0,0(r7) ++1: cmpd r0,r25 ++ beq 2f + mtspr SPRN_DSCR,r0 +-1: ++2: + END_FTR_SECTION_IFSET(CPU_FTR_DSCR) + #endif + ++ ld r6,_CCR(r1) ++ mtcrf 0xFF,r6 ++ + /* r3-r13 are destroyed -- Cort */ + REST_8GPRS(14, r1) + REST_10GPRS(22, r1) diff --git a/queue-3.5/powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch b/queue-3.5/powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch new file mode 100644 index 00000000000..63cb5b1eeef --- /dev/null +++ b/queue-3.5/powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch @@ -0,0 +1,50 @@ +From 1b6ca2a6fe56e7697d57348646e07df08f43b1bb Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Mon, 3 Sep 2012 16:47:56 +0000 +Subject: powerpc: Update DSCR on all CPUs when writing sysfs dscr_default + +From: Anton Blanchard + +commit 1b6ca2a6fe56e7697d57348646e07df08f43b1bb upstream. + +Writing to dscr_default in sysfs doesn't actually change the DSCR - +we rely on a context switch on each CPU to do the work. There is no +guarantee we will get a context switch in a reasonable amount of time +so fire off an IPI to force an immediate change. + +This issue was found with the following test case: + +http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c + +Signed-off-by: Anton Blanchard +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/sysfs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/powerpc/kernel/sysfs.c ++++ b/arch/powerpc/kernel/sysfs.c +@@ -194,6 +194,12 @@ static ssize_t show_dscr_default(struct + return sprintf(buf, "%lx\n", dscr_default); + } + ++static void update_dscr(void *dummy) ++{ ++ if (!current->thread.dscr_inherit) ++ mtspr(SPRN_DSCR, dscr_default); ++} ++ + static ssize_t __used store_dscr_default(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +@@ -206,6 +212,8 @@ static ssize_t __used store_dscr_default + return -EINVAL; + dscr_default = val; + ++ on_each_cpu(update_dscr, NULL, 1); ++ + return count; + } + diff --git a/queue-3.5/remove-user-triggerable-bug-from-mpol_to_str.patch b/queue-3.5/remove-user-triggerable-bug-from-mpol_to_str.patch new file mode 100644 index 00000000000..fa8f07b6954 --- /dev/null +++ b/queue-3.5/remove-user-triggerable-bug-from-mpol_to_str.patch @@ -0,0 +1,42 @@ +From 80de7c3138ee9fd86a98696fd2cf7ad89b995d0a Mon Sep 17 00:00:00 2001 +From: Dave Jones +Date: Thu, 6 Sep 2012 12:01:00 -0400 +Subject: Remove user-triggerable BUG from mpol_to_str + +From: Dave Jones + +commit 80de7c3138ee9fd86a98696fd2cf7ad89b995d0a upstream. + +Trivially triggerable, found by trinity: + + kernel BUG at mm/mempolicy.c:2546! + Process trinity-child2 (pid: 23988, threadinfo ffff88010197e000, task ffff88007821a670) + Call Trace: + show_numa_map+0xd5/0x450 + show_pid_numa_map+0x13/0x20 + traverse+0xf2/0x230 + seq_read+0x34b/0x3e0 + vfs_read+0xac/0x180 + sys_pread64+0xa2/0xc0 + system_call_fastpath+0x1a/0x1f + RIP: mpol_to_str+0x156/0x360 + +Signed-off-by: Dave Jones +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/mempolicy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -2556,7 +2556,7 @@ int mpol_to_str(char *buffer, int maxlen + break; + + default: +- BUG(); ++ return -EINVAL; + } + + l = strlen(policy_modes[mode]); diff --git a/queue-3.5/series b/queue-3.5/series index e77ac882058..35571a9f769 100644 --- a/queue-3.5/series +++ b/queue-3.5/series @@ -75,3 +75,9 @@ alsa-snd-usb-use-list_for_each_safe-for-endpoint-resources.patch alsa-snd-usb-restore-delay-information.patch alsa-snd-usb-fix-calls-to-next_packet_size.patch alsa-snd-usb-fix-cross-interface-streaming-devices.patch +powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch +powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch +powerpc-fix-dscr-inheritance-in-copy_thread.patch +powerpc-restore-correct-dscr-in-context-switch.patch +powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch +remove-user-triggerable-bug-from-mpol_to_str.patch