diff options
author | Alexander Egorenkov | 2021-09-03 11:08:48 +0200 |
---|---|---|
committer | Heiko Carstens | 2022-04-25 13:54:12 +0200 |
commit | 2ba24343bdb8637135bd0d9b5e249c44bd751670 (patch) | |
tree | a2ab5eb17592f217dc2e23bf47b5eeeb54bcd564 /arch/s390/kernel | |
parent | 1b553839e1326b6a73431e399f575862696be51b (diff) |
s390/kexec: set end-of-ipl flag in last diag308 call
If the facility IPL-complete-control is present then the last diag308
call made by kexec shall set the end-of-ipl flag in the subcode register
to signal the hypervisor that this is the last diag308 call made by Linux.
Only the diag308 calls made during a regular kexec need to set
the end-of-ipl flag, in all other cases the hypervisor will ignore it.
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/machine_kexec.c | 10 | ||||
-rw-r--r-- | arch/s390/kernel/relocate_kernel.S | 3 |
2 files changed, 10 insertions, 3 deletions
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 6ebf02e15c85..ab761c008f98 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -26,8 +26,10 @@ #include <asm/stacktrace.h> #include <asm/switch_to.h> #include <asm/nmi.h> +#include <asm/sclp.h> -typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long); +typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long, + unsigned long); extern const unsigned char relocate_kernel[]; extern const unsigned long long relocate_kernel_len; @@ -243,6 +245,7 @@ void machine_crash_shutdown(struct pt_regs *regs) */ static void __do_machine_kexec(void *data) { + unsigned long diag308_subcode; relocate_kernel_t data_mover; struct kimage *image = data; @@ -251,7 +254,10 @@ static void __do_machine_kexec(void *data) __arch_local_irq_stnsm(0xfb); /* disable DAT - avoid no-execute */ /* Call the moving routine */ - (*data_mover)(&image->head, image->start); + diag308_subcode = DIAG308_CLEAR_RESET; + if (sclp.has_iplcc) + diag308_subcode |= DIAG308_FLAG_EI; + (*data_mover)(&image->head, image->start, diag308_subcode); /* Die if kexec returns */ disabled_wait(); diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index 9438368c3632..a9a1a6f45375 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S @@ -14,6 +14,7 @@ * moves the new kernel to its destination... * %r2 = pointer to first kimage_entry_t * %r3 = start address - where to jump to after the job is done... + * %r4 = subcode * * %r5 will be used as temp. storage * %r6 holds the destination address @@ -56,7 +57,7 @@ ENTRY(relocate_kernel) jo 0b j .base .done: - sgr %r0,%r0 # clear register r0 + lgr %r0,%r4 # subcode cghi %r3,0 je .diag la %r4,load_psw-.base(%r13) # load psw-address into the register |