aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2018-04-04 08:42:41 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-04-10 01:39:00 -0400
commit3b9678472bab86ae654cf2c18d5dd551558045be (patch)
treea952f6901e8b0bec9f84e60099c502b4e13cf78f
parent0649685073422af82ab8e7d9119b9991403851a6 (diff)
s390/ipl: correct kdump reipl block checksum calculation
s390 kdump reipl implementation relies on os_info kernel structure residing in old memory being dumped. os_info contains reipl block, which is used (if valid) by the kdump kernel for reipl parameters. The problem is that the reipl block and its checksum inside os_info is updated only when /sys/firmware/reipl/reipl_type is written. This sets an offset of a reipl block for "reipl_type" and re-calculates reipl block checksum. Any further alteration of values under /sys/firmware/reipl/{reipl_type}/ without subsequent write to /sys/firmware/reipl/reipl_type lead to incorrect os_info reipl block checksum. In such a case kdump kernel ignores it and reboots using default logic. To fix this, os_info reipl block update is moved right before kdump execution. Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/ipl.h1
-rw-r--r--arch/s390/kernel/ipl.c11
-rw-r--r--arch/s390/kernel/machine_kexec.c1
3 files changed, 7 insertions, 6 deletions
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index cbc3e0945d7e..ae5135704616 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -120,6 +120,7 @@ struct ipl_info
120 120
121extern struct ipl_info ipl_info; 121extern struct ipl_info ipl_info;
122extern void setup_ipl(void); 122extern void setup_ipl(void);
123extern void set_os_info_reipl_block(void);
123 124
124/* 125/*
125 * DIAG 308 support 126 * DIAG 308 support
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index db86c67f48ec..75dd08547c31 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -913,11 +913,10 @@ static struct attribute_group reipl_nss_attr_group = {
913 .attrs = reipl_nss_attrs, 913 .attrs = reipl_nss_attrs,
914}; 914};
915 915
916static void set_reipl_block_actual(struct ipl_parameter_block *reipl_block) 916void set_os_info_reipl_block(void)
917{ 917{
918 reipl_block_actual = reipl_block;
919 os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual, 918 os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
920 reipl_block->hdr.len); 919 reipl_block_actual->hdr.len);
921} 920}
922 921
923/* reipl type */ 922/* reipl type */
@@ -930,18 +929,18 @@ static int reipl_set_type(enum ipl_type type)
930 switch(type) { 929 switch(type) {
931 case IPL_TYPE_CCW: 930 case IPL_TYPE_CCW:
932 reipl_method = REIPL_METHOD_CCW_DIAG; 931 reipl_method = REIPL_METHOD_CCW_DIAG;
933 set_reipl_block_actual(reipl_block_ccw); 932 reipl_block_actual = reipl_block_ccw;
934 break; 933 break;
935 case IPL_TYPE_FCP: 934 case IPL_TYPE_FCP:
936 reipl_method = REIPL_METHOD_FCP_DIAG; 935 reipl_method = REIPL_METHOD_FCP_DIAG;
937 set_reipl_block_actual(reipl_block_fcp); 936 reipl_block_actual = reipl_block_fcp;
938 break; 937 break;
939 case IPL_TYPE_FCP_DUMP: 938 case IPL_TYPE_FCP_DUMP:
940 reipl_method = REIPL_METHOD_FCP_DUMP; 939 reipl_method = REIPL_METHOD_FCP_DUMP;
941 break; 940 break;
942 case IPL_TYPE_NSS: 941 case IPL_TYPE_NSS:
943 reipl_method = REIPL_METHOD_NSS_DIAG; 942 reipl_method = REIPL_METHOD_NSS_DIAG;
944 set_reipl_block_actual(reipl_block_nss); 943 reipl_block_actual = reipl_block_nss;
945 break; 944 break;
946 case IPL_TYPE_UNKNOWN: 945 case IPL_TYPE_UNKNOWN:
947 reipl_method = REIPL_METHOD_DEFAULT; 946 reipl_method = REIPL_METHOD_DEFAULT;
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 9adae2a1e1a0..b7020e721ae3 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -252,6 +252,7 @@ void machine_shutdown(void)
252 252
253void machine_crash_shutdown(struct pt_regs *regs) 253void machine_crash_shutdown(struct pt_regs *regs)
254{ 254{
255 set_os_info_reipl_block();
255} 256}
256 257
257/* 258/*