From 73148ea4115e632dba41d634a194c9971eddabc8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Jan 2010 13:27:34 -0800 Subject: [PATCH] more .27 patches --- ...urrent-process-in-giveup_fpu-altivec.patch | 69 ++++++++++ ...ults-correctly-in-little-endian-mode.patch | 130 ++++++++++++++++++ queue-2.6.27/series | 2 + 3 files changed, 201 insertions(+) create mode 100644 queue-2.6.27/powerpc-disable-vsx-or-current-process-in-giveup_fpu-altivec.patch create mode 100644 queue-2.6.27/powerpc-handle-vsx-alignment-faults-correctly-in-little-endian-mode.patch diff --git a/queue-2.6.27/powerpc-disable-vsx-or-current-process-in-giveup_fpu-altivec.patch b/queue-2.6.27/powerpc-disable-vsx-or-current-process-in-giveup_fpu-altivec.patch new file mode 100644 index 00000000000..7720648a248 --- /dev/null +++ b/queue-2.6.27/powerpc-disable-vsx-or-current-process-in-giveup_fpu-altivec.patch @@ -0,0 +1,69 @@ +From 7e875e9dc8af70d126fa632446e967327ac3fdda Mon Sep 17 00:00:00 2001 +From: Michael Neuling +Date: Wed, 1 Apr 2009 18:02:42 +0000 +Subject: powerpc: Disable VSX or current process in giveup_fpu/altivec + +From: Michael Neuling + +commit 7e875e9dc8af70d126fa632446e967327ac3fdda upstream. + +When we call giveup_fpu, we need to need to turn off VSX for the +current process. If we don't, on return to userspace it may execute a +VSX instruction before the next FP instruction, and not have its +register state refreshed correctly from the thread_struct. Ditto for +altivec. + +This caused a bug where an unaligned lfs or stfs results in +fix_alignment calling giveup_fpu so it can use the FPRs (in order to +do a single <-> double conversion), and then returning to userspace +with FP off but VSX on. Then if a VSX instruction is executed, before +another FP instruction, it will proceed without another exception and +hence have the incorrect register state for VSX registers 0-31. + + lfs unaligned <- alignment exception turns FP off but leaves VSX on + + VSX instruction <- no exception since VSX on, hence we get the + wrong VSX register values for VSX registers 0-31, + which overlap the FPRs. + +Signed-off-by: Michael Neuling +Signed-off-by: Paul Mackerras +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/fpu.S | 5 +++++ + arch/powerpc/kernel/misc_64.S | 8 ++++++++ + 2 files changed, 13 insertions(+) + +--- a/arch/powerpc/kernel/fpu.S ++++ b/arch/powerpc/kernel/fpu.S +@@ -145,6 +145,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) + beq 1f + PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r3,MSR_FP|MSR_FE0|MSR_FE1 ++#ifdef CONFIG_VSX ++BEGIN_FTR_SECTION ++ oris r3,r3,MSR_VSX@h ++END_FTR_SECTION_IFSET(CPU_FTR_VSX) ++#endif + andc r4,r4,r3 /* disable FP for previous task */ + PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) + 1: +--- a/arch/powerpc/kernel/misc_64.S ++++ b/arch/powerpc/kernel/misc_64.S +@@ -493,7 +493,15 @@ _GLOBAL(giveup_altivec) + stvx vr0,r4,r3 + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) ++#ifdef CONFIG_VSX ++BEGIN_FTR_SECTION ++ lis r3,(MSR_VEC|MSR_VSX)@h ++FTR_SECTION_ELSE ++ lis r3,MSR_VEC@h ++ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX) ++#else + lis r3,MSR_VEC@h ++#endif + andc r4,r4,r3 /* disable FP for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) + 1: diff --git a/queue-2.6.27/powerpc-handle-vsx-alignment-faults-correctly-in-little-endian-mode.patch b/queue-2.6.27/powerpc-handle-vsx-alignment-faults-correctly-in-little-endian-mode.patch new file mode 100644 index 00000000000..bf03e1d3834 --- /dev/null +++ b/queue-2.6.27/powerpc-handle-vsx-alignment-faults-correctly-in-little-endian-mode.patch @@ -0,0 +1,130 @@ +From bb7f20b1c639606def3b91f4e4aca6daeee5d80a Mon Sep 17 00:00:00 2001 +From: Neil Campbell +Date: Mon, 14 Dec 2009 04:08:57 +0000 +Subject: powerpc: Handle VSX alignment faults correctly in little-endian mode + +From: Neil Campbell + +commit bb7f20b1c639606def3b91f4e4aca6daeee5d80a upstream. + +This patch fixes the handling of VSX alignment faults in little-endian +mode (the current code assumes the processor is in big-endian mode). + +The patch also makes the handlers clear the top 8 bytes of the register +when handling an 8 byte VSX load. + +This is based on 2.6.32. + +Signed-off-by: Neil Campbell +Acked-by: Michael Neuling +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/align.c | 63 ++++++++++++++++++++++++++++++++------------ + 1 file changed, 46 insertions(+), 17 deletions(-) + +--- a/arch/powerpc/kernel/align.c ++++ b/arch/powerpc/kernel/align.c +@@ -641,10 +641,14 @@ static int emulate_spe(struct pt_regs *r + */ + static int emulate_vsx(unsigned char __user *addr, unsigned int reg, + unsigned int areg, struct pt_regs *regs, +- unsigned int flags, unsigned int length) ++ unsigned int flags, unsigned int length, ++ unsigned int elsize) + { + char *ptr; ++ unsigned long *lptr; + int ret = 0; ++ int sw = 0; ++ int i, j; + + flush_vsx_to_thread(current); + +@@ -653,19 +657,35 @@ static int emulate_vsx(unsigned char __u + else + ptr = (char *) ¤t->thread.vr[reg - 32]; + +- if (flags & ST) +- ret = __copy_to_user(addr, ptr, length); +- else { +- if (flags & SPLT){ +- ret = __copy_from_user(ptr, addr, length); +- ptr += length; ++ lptr = (unsigned long *) ptr; ++ ++ if (flags & SW) ++ sw = elsize-1; ++ ++ for (j = 0; j < length; j += elsize) { ++ for (i = 0; i < elsize; ++i) { ++ if (flags & ST) ++ ret |= __put_user(ptr[i^sw], addr + i); ++ else ++ ret |= __get_user(ptr[i^sw], addr + i); + } +- ret |= __copy_from_user(ptr, addr, length); ++ ptr += elsize; ++ addr += elsize; + } +- if (flags & U) +- regs->gpr[areg] = regs->dar; +- if (ret) ++ ++ if (!ret) { ++ if (flags & U) ++ regs->gpr[areg] = regs->dar; ++ ++ /* Splat load copies the same data to top and bottom 8 bytes */ ++ if (flags & SPLT) ++ lptr[1] = lptr[0]; ++ /* For 8 byte loads, zero the top 8 bytes */ ++ else if (!(flags & ST) && (8 == length)) ++ lptr[1] = 0; ++ } else + return -EFAULT; ++ + return 1; + } + #endif +@@ -764,16 +784,25 @@ int fix_alignment(struct pt_regs *regs) + + #ifdef CONFIG_VSX + if ((instruction & 0xfc00003e) == 0x7c000018) { +- /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */ ++ unsigned int elsize; ++ ++ /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */ + reg |= (instruction & 0x1) << 5; + /* Simple inline decoder instead of a table */ ++ /* VSX has only 8 and 16 byte memory accesses */ ++ nb = 8; + if (instruction & 0x200) + nb = 16; +- else if (instruction & 0x080) +- nb = 8; +- else +- nb = 4; ++ ++ /* Vector stores in little-endian mode swap individual ++ elements, so process them separately */ ++ elsize = 4; ++ if (instruction & 0x80) ++ elsize = 8; ++ + flags = 0; ++ if (regs->msr & MSR_LE) ++ flags |= SW; + if (instruction & 0x100) + flags |= ST; + if (instruction & 0x040) +@@ -783,7 +812,7 @@ int fix_alignment(struct pt_regs *regs) + flags |= SPLT; + nb = 8; + } +- return emulate_vsx(addr, reg, areg, regs, flags, nb); ++ return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize); + } + #endif + /* A size of 0 indicates an instruction we don't support, with diff --git a/queue-2.6.27/series b/queue-2.6.27/series index f9f1b7489ce..58427bdb7ca 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -2,3 +2,5 @@ kernel-signal.c-fix-kernel-information-leak-with-print-fatal-signals-1.patch netfilter-ebtables-enforce-cap_net_admin.patch fix-braindamage-in-audit_tree.c-untag_chunk.patch fix-more-leaks-in-audit_tree.c-tag_chunk.patch +powerpc-disable-vsx-or-current-process-in-giveup_fpu-altivec.patch +powerpc-handle-vsx-alignment-faults-correctly-in-little-endian-mode.patch -- 2.47.3