aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2012-05-21 05:30:30 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-05-23 11:06:51 -0400
commitfa7c0043425624ed65b94a6fabe750c7b0af8719 (patch)
tree8e21c28d65b56a0bd22af1b9a196083233341b3c /arch/s390/kernel
parenta9fbf1a53836d4105f95df947ac00e22311dff33 (diff)
s390/kdump: Use real mode for PSW restart and kexec
Currently the PSW restart handler and kexec are executed in real mode with DAT=off. For kexec/kdump the function setup_regs() is called that uses the per-cpu variable "crash_notes". Because there are situations when the per-cpu implementation uses vmalloc memory, calling setup_regs() in real mode can cause a program check interrupt. To fix that problem this patch changes the following: * Ensure that diag308_reset() does not change PSW bits to real mode * Enable DAT in __do_restart() after we switched to an online CPU * Enable DAT in __machine_kexec() after we switched to the IPL CPU * Call setup_regs() before we switch to real mode and call purgatory Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/base.S12
-rw-r--r--arch/s390/kernel/ipl.c1
-rw-r--r--arch/s390/kernel/machine_kexec.c3
3 files changed, 15 insertions, 1 deletions
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index 3aa4d00aaf50..c880ff72db44 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -88,6 +88,9 @@ ENTRY(diag308_reset)
88 stctg %c0,%c15,0(%r4) 88 stctg %c0,%c15,0(%r4)
89 larl %r4,.Lfpctl # Floating point control register 89 larl %r4,.Lfpctl # Floating point control register
90 stfpc 0(%r4) 90 stfpc 0(%r4)
91 larl %r4,.Lcontinue_psw # Save PSW flags
92 epsw %r2,%r3
93 stm %r2,%r3,0(%r4)
91 larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0 94 larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0
92 lghi %r3,0 95 lghi %r3,0
93 lg %r4,0(%r4) # Save PSW 96 lg %r4,0(%r4) # Save PSW
@@ -103,11 +106,20 @@ ENTRY(diag308_reset)
103 lctlg %c0,%c15,0(%r4) 106 lctlg %c0,%c15,0(%r4)
104 larl %r4,.Lfpctl # Restore floating point ctl register 107 larl %r4,.Lfpctl # Restore floating point ctl register
105 lfpc 0(%r4) 108 lfpc 0(%r4)
109 larl %r4,.Lcontinue_psw # Restore PSW flags
110 lpswe 0(%r4)
111.Lcontinue:
106 br %r14 112 br %r14
107.align 16 113.align 16
108.Lrestart_psw: 114.Lrestart_psw:
109 .long 0x00080000,0x80000000 + .Lrestart_part2 115 .long 0x00080000,0x80000000 + .Lrestart_part2
110 116
117 .section .data..nosave,"aw",@progbits
118.align 8
119.Lcontinue_psw:
120 .quad 0,.Lcontinue
121 .previous
122
111 .section .bss 123 .section .bss
112.align 8 124.align 8
113.Lctlregs: 125.Lctlregs:
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 8342e65a140d..dcfdcb3ea163 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1750,6 +1750,7 @@ static struct kobj_attribute on_restart_attr =
1750 1750
1751static void __do_restart(void *ignore) 1751static void __do_restart(void *ignore)
1752{ 1752{
1753 __arch_local_irq_stosm(0x04); /* enable DAT */
1753 smp_send_stop(); 1754 smp_send_stop();
1754#ifdef CONFIG_CRASH_DUMP 1755#ifdef CONFIG_CRASH_DUMP
1755 crash_kexec(NULL); 1756 crash_kexec(NULL);
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 03d2027d656a..cdacf8f91b2d 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -80,8 +80,8 @@ static void __do_machine_kdump(void *image)
80#ifdef CONFIG_CRASH_DUMP 80#ifdef CONFIG_CRASH_DUMP
81 int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; 81 int (*start_kdump)(int) = (void *)((struct kimage *) image)->start;
82 82
83 __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
84 setup_regs(); 83 setup_regs();
84 __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
85 start_kdump(1); 85 start_kdump(1);
86#endif 86#endif
87} 87}
@@ -214,6 +214,7 @@ static void __machine_kexec(void *data)
214{ 214{
215 struct kimage *image = data; 215 struct kimage *image = data;
216 216
217 __arch_local_irq_stosm(0x04); /* enable DAT */
217 pfault_fini(); 218 pfault_fini();
218 tracing_off(); 219 tracing_off();
219 debug_locks_off(); 220 debug_locks_off();