summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/machine_kexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/machine_kexec.c')
-rw-r--r--arch/s390/kernel/machine_kexec.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index fb887674e159..f5d8abf3b4fb 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -30,6 +30,7 @@
#include <asm/sclp.h>
typedef void (*relocate_kernel_t)(unsigned long, unsigned long, unsigned long);
+typedef int (*purgatory_t)(int);
extern const unsigned char relocate_kernel[];
extern const unsigned long long relocate_kernel_len;
@@ -40,11 +41,14 @@ extern const unsigned long long relocate_kernel_len;
* Reset the system, copy boot CPU registers to absolute zero,
* and jump to the kdump image
*/
-static void __do_machine_kdump(void *image)
+static void __do_machine_kdump(void *data)
{
- int (*start_kdump)(int);
+ struct kimage *image = data;
+ purgatory_t purgatory;
unsigned long prefix;
+ purgatory = (purgatory_t)image->start;
+
/* store_status() saved the prefix register to lowcore */
prefix = (unsigned long) S390_lowcore.prefixreg_save_area;
@@ -59,11 +63,9 @@ static void __do_machine_kdump(void *image)
memcpy(absolute_pointer(__LC_FPREGS_SAVE_AREA),
phys_to_virt(prefix + __LC_FPREGS_SAVE_AREA), 512);
- __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
- start_kdump = (void *)((struct kimage *) image)->start;
- start_kdump(1);
+ call_nodat(1, int, purgatory, int, 1);
- /* Die if start_kdump returns */
+ /* Die if kdump returns */
disabled_wait();
}
@@ -112,13 +114,9 @@ static noinline void __machine_kdump(void *image)
static int do_start_kdump(struct kimage *image)
{
- int (*start_kdump)(int) = (void *)image->start;
- int rc;
+ purgatory_t purgatory = (purgatory_t)image->start;
- __arch_local_irq_stnsm(0xfb); /* disable DAT */
- rc = start_kdump(0);
- __arch_local_irq_stosm(0x04); /* enable DAT */
- return rc;
+ return call_nodat(1, int, purgatory, int, 0);
}
#endif /* CONFIG_CRASH_DUMP */
@@ -258,8 +256,10 @@ static void __do_machine_kexec(void *data)
diag308_subcode |= DIAG308_FLAG_EI;
s390_reset_system();
- __arch_local_irq_stnsm(0xfb); /* disable DAT - avoid no-execute */
- (*(relocate_kernel_t)data_mover)(entry, image->start, diag308_subcode);
+ call_nodat(3, void, (relocate_kernel_t)data_mover,
+ unsigned long, entry,
+ unsigned long, image->start,
+ unsigned long, diag308_subcode);
/* Die if kexec returns */
disabled_wait();