diff --git a/ChangeLog b/ChangeLog
index b0e9e1999069b397e8ae28ae6384c3ac1515cc26..1f2e2d40e7af8b683afa56b0ba675b9a616c4ee4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,9 @@
 2020-12-01  Niels Möller  <nisse@lysator.liu.se>
 
-	* powerpc64/p7/chacha-4core.asm (QR): Instruction level
-	interleaving in the main loop, written by Torbjörn Granlund.
+	* powerpc64/p7/chacha-4core.asm: Use protected zone below stack
+	pointer to save registers, without modifying the stack pointer.
+	(QR): Instruction level interleaving in the main loop, written by
+	Torbjörn Granlund.
 
 2020-11-30  Niels Möller  <nisse@lysator.liu.se>
 
diff --git a/powerpc64/p7/chacha-4core.asm b/powerpc64/p7/chacha-4core.asm
index 0cd5c877b88234c995234111ce2d92143c7ed3e9..b2330247a40cac4af0baf3465ab3bab3ddcb402f 100644
--- a/powerpc64/p7/chacha-4core.asm
+++ b/powerpc64/p7/chacha-4core.asm
@@ -132,11 +132,13 @@ PROLOGUE(_nettle_chacha_4core)
 	li	r7, 0x20	C ...useful...
 	li	r8, 0x30	C ...offsets
 
-	addi	SP, SP, -0x40	C Save callee-save registers
-	stvx	v20, 0, SP
-	stvx	v21, r6, SP
-	stvx	v22, r7, SP
-	stvx	v23, r8, SP
+	C Save callee-save registers. Use the "protected zone", max
+	C 228 bytes, below the stack pointer, accessed via r10.
+	addi	r10, SP, -0x40
+	stvx	v20, 0, r10
+	stvx	v21, r6, r10
+	stvx	v22, r7, r10
+	stvx	v23, r8, r10
 
 	vspltisw ROT16, -16	C -16 instead of 16 actually works!
 	vspltisw ROT12, 12
@@ -257,11 +259,10 @@ IF_BE(`
 	stxvw4x	VSR(v15), r8, DST
 
 	C Restore callee-save registers
-	lvx	v20, 0, SP
-	lvx	v21, r6, SP
-	lvx	v22, r7, SP
-	lvx	v23, r8, SP
-	addi	SP, SP, 0x40
+	lvx	v20, 0, r10
+	lvx	v21, r6, r10
+	lvx	v22, r7, r10
+	lvx	v23, r8, r10
 
 	blr
 EPILOGUE(_nettle_chacha_4core)