powerpc/signals: Mark VSX not saved with small contexts

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Nov 22 17:59:02 EST 2013


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=c13f20ac48328b05cd3b8c19e31ed6c132b44b42
Commit:     c13f20ac48328b05cd3b8c19e31ed6c132b44b42
Parent:     148924f7a282b3acb1f8868ae03c3f76be301d8d
Author:     Michael Neuling <mikey at neuling.org>
AuthorDate: Wed Nov 20 16:18:54 2013 +1100
Committer:  Benjamin Herrenschmidt <benh at kernel.crashing.org>
CommitDate: Thu Nov 21 10:33:45 2013 +1100

    powerpc/signals: Mark VSX not saved with small contexts
    
    The VSX MSR bit in the user context indicates if the context contains VSX
    state.  Currently we set this when the process has touched VSX at any stage.
    
    Unfortunately, if the user has not provided enough space to save the VSX state,
    we can't save it but we currently still set the MSR VSX bit.
    
    This patch changes this to clear the MSR VSX bit when the user doesn't provide
    enough space.  This indicates that there is no valid VSX state in the user
    context.
    
    This is needed to support get/set/make/swapcontext for applications that use
    VSX but only provide a small context.  For example, getcontext in glibc
    provides a smaller context since the VSX registers don't need to be saved over
    the glibc function call.  But since the program calling getcontext may have
    used VSX, the kernel currently says the VSX state is valid when it's not.  If
    the returned context is then used in setcontext (ie. a small context without
    VSX but with MSR VSX set), the kernel will refuse the context.  This situation
    has been reported by the glibc community.
    
    Based on patch from Carlos O'Donell.
    
    Tested-by: Haren Myneni <haren at linux.vnet.ibm.com>
    Signed-off-by: Michael Neuling <mikey at neuling.org>
    Cc: stable at vger.kernel.org
    Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 arch/powerpc/kernel/signal_32.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 749778e..1844298 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -457,7 +457,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 		if (copy_vsx_to_user(&frame->mc_vsregs, current))
 			return 1;
 		msr |= MSR_VSX;
-	}
+	} else if (!ctx_has_vsx_region)
+		/*
+		 * With a small context structure we can't hold the VSX
+		 * registers, hence clear the MSR value to indicate the state
+		 * was not saved.
+		 */
+		msr &= ~MSR_VSX;
+
+
 #endif /* CONFIG_VSX */
 #ifdef CONFIG_SPE
 	/* save spe registers */



More information about the linux-mtd-cvs mailing list