Commit fa7c0043 authored by Michael Holzheu's avatar Michael Holzheu Committed by Martin Schwidefsky

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent a9fbf1a5
...@@ -88,6 +88,9 @@ ENTRY(diag308_reset) ...@@ -88,6 +88,9 @@ ENTRY(diag308_reset)
stctg %c0,%c15,0(%r4) stctg %c0,%c15,0(%r4)
larl %r4,.Lfpctl # Floating point control register larl %r4,.Lfpctl # Floating point control register
stfpc 0(%r4) stfpc 0(%r4)
larl %r4,.Lcontinue_psw # Save PSW flags
epsw %r2,%r3
stm %r2,%r3,0(%r4)
larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0 larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0
lghi %r3,0 lghi %r3,0
lg %r4,0(%r4) # Save PSW lg %r4,0(%r4) # Save PSW
...@@ -103,11 +106,20 @@ ENTRY(diag308_reset) ...@@ -103,11 +106,20 @@ ENTRY(diag308_reset)
lctlg %c0,%c15,0(%r4) lctlg %c0,%c15,0(%r4)
larl %r4,.Lfpctl # Restore floating point ctl register larl %r4,.Lfpctl # Restore floating point ctl register
lfpc 0(%r4) lfpc 0(%r4)
larl %r4,.Lcontinue_psw # Restore PSW flags
lpswe 0(%r4)
.Lcontinue:
br %r14 br %r14
.align 16 .align 16
.Lrestart_psw: .Lrestart_psw:
.long 0x00080000,0x80000000 + .Lrestart_part2 .long 0x00080000,0x80000000 + .Lrestart_part2
.section .data..nosave,"aw",@progbits
.align 8
.Lcontinue_psw:
.quad 0,.Lcontinue
.previous
.section .bss .section .bss
.align 8 .align 8
.Lctlregs: .Lctlregs:
......
...@@ -1750,6 +1750,7 @@ static struct kobj_attribute on_restart_attr = ...@@ -1750,6 +1750,7 @@ static struct kobj_attribute on_restart_attr =
static void __do_restart(void *ignore) static void __do_restart(void *ignore)
{ {
__arch_local_irq_stosm(0x04); /* enable DAT */
smp_send_stop(); smp_send_stop();
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
crash_kexec(NULL); crash_kexec(NULL);
......
...@@ -80,8 +80,8 @@ static void __do_machine_kdump(void *image) ...@@ -80,8 +80,8 @@ static void __do_machine_kdump(void *image)
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; int (*start_kdump)(int) = (void *)((struct kimage *) image)->start;
__load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
setup_regs(); setup_regs();
__load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
start_kdump(1); start_kdump(1);
#endif #endif
} }
...@@ -214,6 +214,7 @@ static void __machine_kexec(void *data) ...@@ -214,6 +214,7 @@ static void __machine_kexec(void *data)
{ {
struct kimage *image = data; struct kimage *image = data;
__arch_local_irq_stosm(0x04); /* enable DAT */
pfault_fini(); pfault_fini();
tracing_off(); tracing_off();
debug_locks_off(); debug_locks_off();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment