Blob Blame History Raw
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Subject: s390/noexec: execute kexec datamover without DAT
Patch-mainline: v4.15-rc1
Git-commit: d0e810eeb3d326978f248b8f0233a2f30f58c72d
References: bnc#1066799, LTC#161403

Description:  s390/noexec: execute kexec datamover without DAT
Symptom:      System hangs when using kexec on new hardware with no-execute
              support (z14).
Problem:      The datamover code gets executed with DAT on (MMU is active)
              and the page that contains the datamover is marked as non-
              executable. Therefore when branching into the datamover an
              unexpected program check happens and afterwards the machine
              is dead.
Solution:     Disable DAT, which also disables any no-execute checks, just
              before the datamover gets executed.
Reproduction: Use kexec on new hardware with no-execute support (z14).

Upstream-Description:

              s390/noexec: execute kexec datamover without DAT

              Rebooting into a new kernel with kexec fails (system dies) if tried on
              a machine that has no-execute support. Reason for this is that the so
              called datamover code gets executed with DAT on (MMU is active) and
              the page that contains the datamover is marked as non-executable.
              Therefore when branching into the datamover an unexpected program
              check happens and afterwards the machine is dead.

              This can be simply avoided by disabling DAT, which also disables any
              no-execute checks, just before the datamover gets executed.

              In fact the first thing done by the datamover is to disable DAT. The
              code in the datamover that disables DAT can be removed as well.

              Thanks to Michael Holzheu and Gerald Schaefer for tracking this down.

              Reviewed-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
              Reviewed-by: Philipp Rudo <prudo@linux.vnet.ibm.com>
              Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
              Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
              Fixes: 57d7f939e7bd ("s390: add no-execute support")
              Cc: <stable@vger.kernel.org> # v4.11+
              Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>


Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Acked-by: Hannes Reinecke <hare@suse.com>
---
 arch/s390/kernel/machine_kexec.c   |    1 +
 arch/s390/kernel/relocate_kernel.S |    3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -268,6 +268,7 @@ static void __do_machine_kexec(void *dat
 	s390_reset_system();
 	data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page);
 
+	__arch_local_irq_stnsm(0xfb); /* disable DAT - avoid no-execute */
 	/* Call the moving routine */
 	(*data_mover)(&image->head, image->start);
 
--- a/arch/s390/kernel/relocate_kernel.S
+++ b/arch/s390/kernel/relocate_kernel.S
@@ -27,7 +27,6 @@
 ENTRY(relocate_kernel)
 		basr	%r13,0		# base address
 	.base:
-		stnsm	sys_msk-.base(%r13),0xfb	# disable DAT
 		stctg	%c0,%c15,ctlregs-.base(%r13)
 		stmg	%r0,%r15,gprregs-.base(%r13)
 		lghi	%r0,3
@@ -101,8 +100,6 @@ ENTRY(relocate_kernel)
 		.align	8
 	load_psw:
 		.long	0x00080000,0x80000000
-	sys_msk:
-		.quad	0
 	ctlregs:
 		.rept	16
 		.quad	0