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>
This commit is contained in:
parent
a9fbf1a538
commit
fa7c004342
3 changed files with 15 additions and 1 deletions
|
@ -88,6 +88,9 @@ ENTRY(diag308_reset)
|
|||
stctg %c0,%c15,0(%r4)
|
||||
larl %r4,.Lfpctl # Floating point control register
|
||||
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
|
||||
lghi %r3,0
|
||||
lg %r4,0(%r4) # Save PSW
|
||||
|
@ -103,11 +106,20 @@ ENTRY(diag308_reset)
|
|||
lctlg %c0,%c15,0(%r4)
|
||||
larl %r4,.Lfpctl # Restore floating point ctl register
|
||||
lfpc 0(%r4)
|
||||
larl %r4,.Lcontinue_psw # Restore PSW flags
|
||||
lpswe 0(%r4)
|
||||
.Lcontinue:
|
||||
br %r14
|
||||
.align 16
|
||||
.Lrestart_psw:
|
||||
.long 0x00080000,0x80000000 + .Lrestart_part2
|
||||
|
||||
.section .data..nosave,"aw",@progbits
|
||||
.align 8
|
||||
.Lcontinue_psw:
|
||||
.quad 0,.Lcontinue
|
||||
.previous
|
||||
|
||||
.section .bss
|
||||
.align 8
|
||||
.Lctlregs:
|
||||
|
|
|
@ -1750,6 +1750,7 @@ static struct kobj_attribute on_restart_attr =
|
|||
|
||||
static void __do_restart(void *ignore)
|
||||
{
|
||||
__arch_local_irq_stosm(0x04); /* enable DAT */
|
||||
smp_send_stop();
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
crash_kexec(NULL);
|
||||
|
|
|
@ -80,8 +80,8 @@ static void __do_machine_kdump(void *image)
|
|||
#ifdef CONFIG_CRASH_DUMP
|
||||
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();
|
||||
__load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
|
||||
start_kdump(1);
|
||||
#endif
|
||||
}
|
||||
|
@ -214,6 +214,7 @@ static void __machine_kexec(void *data)
|
|||
{
|
||||
struct kimage *image = data;
|
||||
|
||||
__arch_local_irq_stosm(0x04); /* enable DAT */
|
||||
pfault_fini();
|
||||
tracing_off();
|
||||
debug_locks_off();
|
||||
|
|
Loading…
Reference in a new issue