aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/ipl.c
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2018-04-04 14:42:41 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-04-10 07:39:00 +0200
commit3b9678472bab86ae654cf2c18d5dd551558045be (patch)
treea952f6901e8b0bec9f84e60099c502b4e13cf78f /arch/s390/kernel/ipl.c
parents390/ipl: remove non-existing functions declaration (diff)
downloadlinux-dev-3b9678472bab86ae654cf2c18d5dd551558045be.tar.xz
linux-dev-3b9678472bab86ae654cf2c18d5dd551558045be.zip
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>
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r--arch/s390/kernel/ipl.c11
1 files changed, 5 insertions, 6 deletions
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 = {
.attrs = reipl_nss_attrs,
};
-static void set_reipl_block_actual(struct ipl_parameter_block *reipl_block)
+void set_os_info_reipl_block(void)
{
- reipl_block_actual = reipl_block;
os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
- reipl_block->hdr.len);
+ reipl_block_actual->hdr.len);
}
/* reipl type */
@@ -930,18 +929,18 @@ static int reipl_set_type(enum ipl_type type)
switch(type) {
case IPL_TYPE_CCW:
reipl_method = REIPL_METHOD_CCW_DIAG;
- set_reipl_block_actual(reipl_block_ccw);
+ reipl_block_actual = reipl_block_ccw;
break;
case IPL_TYPE_FCP:
reipl_method = REIPL_METHOD_FCP_DIAG;
- set_reipl_block_actual(reipl_block_fcp);
+ reipl_block_actual = reipl_block_fcp;
break;
case IPL_TYPE_FCP_DUMP:
reipl_method = REIPL_METHOD_FCP_DUMP;
break;
case IPL_TYPE_NSS:
reipl_method = REIPL_METHOD_NSS_DIAG;
- set_reipl_block_actual(reipl_block_nss);
+ reipl_block_actual = reipl_block_nss;
break;
case IPL_TYPE_UNKNOWN:
reipl_method = REIPL_METHOD_DEFAULT;