lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 17 Sep 2012 01:37:04 +0100
From:	Ben Hutchings <>
Cc:,,, Anton Blanchard <>,
	Benjamin Herrenschmidt <>
Subject: [ 039/135] powerpc: Restore correct DSCR in context switch

3.2-stable review patch.  If anyone has any objections, please let me know.


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):

With the four patches applied I can run a combination of all
test cases successfully at the same time:

Signed-off-by: Anton Blanchard <>
Signed-off-by: Benjamin Herrenschmidt <>
Signed-off-by: Ben Hutchings <>
 arch/powerpc/kernel/asm-offsets.c |    1 +
 arch/powerpc/kernel/entry_64.S    |   23 +++++++++++++++++------
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 85b05c4..e899572 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -76,6 +76,7 @@ int main(void)
 	DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr));
+	DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit));
 	DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
 #endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 4b01a25..b40e0b4 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -370,6 +370,12 @@ _GLOBAL(ret_from_fork)
 	li	r3,0
 	b	syscall_exit
+	.section	".toc","aw"
+	.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
 	mr	r1,r8		/* start using new stack pointer */
 	std	r7,PACAKSAVE(r13)
-	ld	r6,_CCR(r1)
-	mtcrf	0xFF,r6
 	ld	r0,THREAD_VRSAVE(r4)
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_PPC64
+	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
+	ld	r6,_CCR(r1)
+	mtcrf	0xFF,r6
 	/* r3-r13 are destroyed -- Cort */
 	REST_8GPRS(14, r1)
 	REST_10GPRS(22, r1)

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

Powered by blists - more mailing lists