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>
This commit is contained in:
parent
1b553839e1
commit
2ba24343bd
|
@ -133,6 +133,8 @@ int ipl_report_add_certificate(struct ipl_report *report, void *key,
|
||||||
* DIAG 308 support
|
* DIAG 308 support
|
||||||
*/
|
*/
|
||||||
enum diag308_subcode {
|
enum diag308_subcode {
|
||||||
|
DIAG308_CLEAR_RESET = 0,
|
||||||
|
DIAG308_LOAD_NORMAL_RESET = 1,
|
||||||
DIAG308_REL_HSA = 2,
|
DIAG308_REL_HSA = 2,
|
||||||
DIAG308_LOAD_CLEAR = 3,
|
DIAG308_LOAD_CLEAR = 3,
|
||||||
DIAG308_LOAD_NORMAL_DUMP = 4,
|
DIAG308_LOAD_NORMAL_DUMP = 4,
|
||||||
|
@ -141,6 +143,10 @@ enum diag308_subcode {
|
||||||
DIAG308_LOAD_NORMAL = 7,
|
DIAG308_LOAD_NORMAL = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum diag308_subcode_flags {
|
||||||
|
DIAG308_FLAG_EI = 1UL << 16,
|
||||||
|
};
|
||||||
|
|
||||||
enum diag308_rc {
|
enum diag308_rc {
|
||||||
DIAG308_RC_OK = 0x0001,
|
DIAG308_RC_OK = 0x0001,
|
||||||
DIAG308_RC_NOCONFIG = 0x0102,
|
DIAG308_RC_NOCONFIG = 0x0102,
|
||||||
|
|
|
@ -26,8 +26,10 @@
|
||||||
#include <asm/stacktrace.h>
|
#include <asm/stacktrace.h>
|
||||||
#include <asm/switch_to.h>
|
#include <asm/switch_to.h>
|
||||||
#include <asm/nmi.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 char relocate_kernel[];
|
||||||
extern const unsigned long long relocate_kernel_len;
|
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)
|
static void __do_machine_kexec(void *data)
|
||||||
{
|
{
|
||||||
|
unsigned long diag308_subcode;
|
||||||
relocate_kernel_t data_mover;
|
relocate_kernel_t data_mover;
|
||||||
struct kimage *image = data;
|
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 */
|
__arch_local_irq_stnsm(0xfb); /* disable DAT - avoid no-execute */
|
||||||
/* Call the moving routine */
|
/* 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 */
|
/* Die if kexec returns */
|
||||||
disabled_wait();
|
disabled_wait();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
* moves the new kernel to its destination...
|
* moves the new kernel to its destination...
|
||||||
* %r2 = pointer to first kimage_entry_t
|
* %r2 = pointer to first kimage_entry_t
|
||||||
* %r3 = start address - where to jump to after the job is done...
|
* %r3 = start address - where to jump to after the job is done...
|
||||||
|
* %r4 = subcode
|
||||||
*
|
*
|
||||||
* %r5 will be used as temp. storage
|
* %r5 will be used as temp. storage
|
||||||
* %r6 holds the destination address
|
* %r6 holds the destination address
|
||||||
|
@ -56,7 +57,7 @@ ENTRY(relocate_kernel)
|
||||||
jo 0b
|
jo 0b
|
||||||
j .base
|
j .base
|
||||||
.done:
|
.done:
|
||||||
sgr %r0,%r0 # clear register r0
|
lgr %r0,%r4 # subcode
|
||||||
cghi %r3,0
|
cghi %r3,0
|
||||||
je .diag
|
je .diag
|
||||||
la %r4,load_psw-.base(%r13) # load psw-address into the register
|
la %r4,load_psw-.base(%r13) # load psw-address into the register
|
||||||
|
|
Loading…
Reference in New Issue