mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl/boot: Conditionally clear memory upon reipl at ccw dump end
- Instead of always clearing the memory on reipl after the ccw dump has been taken, check for the special OS_INFO_FLAG_REIPL_CLEAR flag in os_info flags entry (indicates if sysfs 'clear' attribute has been set on the panicked system) and trigger diag308 with a proper subcode. - Get rid of superfluous ipib_info structure in stage2dump.c. - Collect ipl_pbt constants in boot/ipl.h header. Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Acked-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
2b7df1fcac
commit
d205b47c08
@@ -59,7 +59,7 @@ static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps,
|
||||
ipib_size = MAX(ipl_pl_hdr_size + blk0_len, (uint32_t)PAGE_SIZE);
|
||||
g_assert(pv_ipib_get_size(comps_length) == ipib_size);
|
||||
|
||||
pv->pbt = IPL_TYPE_PV;
|
||||
pv->pbt = IPL_PBT_PV;
|
||||
pv->len = GUINT32_TO_BE(blk0_len);
|
||||
pv->num_comp = GUINT32_TO_BE(comps_length);
|
||||
/* both values will be overwritten during the IPL process by
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
#define IPL_MAX_SUPPORTED_VERSION 0
|
||||
#define IPL_PARM_BLOCK_VERSION 0x1
|
||||
|
||||
/* IPL Types */
|
||||
#define IPL_TYPE_PV 0x5
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -43,6 +39,16 @@ struct ipl_pb_hdr {
|
||||
uint8_t pbt;
|
||||
} __packed;
|
||||
|
||||
/* IPL Parameter Block types */
|
||||
enum ipl_pbt {
|
||||
IPL_PBT_FCP = 0,
|
||||
IPL_PBT_SCP_DATA = 1,
|
||||
IPL_PBT_CCW = 2,
|
||||
IPL_PBT_ECKD = 3,
|
||||
IPL_PBT_NVME = 4,
|
||||
IPL_PBT_PV = 5,
|
||||
};
|
||||
|
||||
/* IPL Parameter Block 0 with common fields */
|
||||
struct ipl_pb0_common {
|
||||
uint32_t len;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "libc.h"
|
||||
#include "sclp.h"
|
||||
#include "stage2dump.h"
|
||||
#include "boot/ipl.h"
|
||||
#include "boot/os_info.h"
|
||||
|
||||
#define CPU_ADDRESS_MAX 1000
|
||||
#define MACHINE_HAS_VX machine_has_vx
|
||||
@@ -26,14 +28,6 @@
|
||||
*/
|
||||
static uint8_t machine_has_vx;
|
||||
|
||||
/*
|
||||
* IPL info in lowcore
|
||||
*/
|
||||
struct ipib_info {
|
||||
unsigned long ipib;
|
||||
uint32_t ipib_csum;
|
||||
};
|
||||
|
||||
/*
|
||||
* Tail parameters
|
||||
*/
|
||||
@@ -395,17 +389,41 @@ static void store_status(void)
|
||||
*/
|
||||
static __noreturn void dump_exit(unsigned long code)
|
||||
{
|
||||
struct ipib_info *ipib_info = (struct ipib_info *)&S390_lowcore.ipib;
|
||||
uint32_t ipib_len, csum;
|
||||
struct ipl_parameter_block *ipib = (struct ipl_parameter_block *)S390_lowcore.ipib;
|
||||
const struct os_info *os_info = (struct os_info *)S390_lowcore.os_info;
|
||||
const struct os_info_entry *os_info_entry = NULL;
|
||||
unsigned long os_info_flags = 0;
|
||||
uint32_t csum;
|
||||
|
||||
if (!ipib_info->ipib)
|
||||
if (!ipib)
|
||||
libc_stop(code);
|
||||
ipib_len = *((uint32_t *) ipib_info->ipib);
|
||||
csum = csum_partial((void *) ipib_info->ipib, ipib_len, 0);
|
||||
if (ipib_info->ipib_csum != csum)
|
||||
csum = csum_partial(ipib, ipib->hdr.len, 0);
|
||||
/* Verify ipib checksum against the value stored in lowcore */
|
||||
if (csum != S390_lowcore.ipib_checksum)
|
||||
libc_stop(code);
|
||||
diag308(DIAG308_SET, (void *) ipib_info->ipib);
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
diag308(DIAG308_SET, ipib);
|
||||
/*
|
||||
* Check os_info flags entry for REIPL_CLEAR flag and make
|
||||
* diag308 call with a proper subcode.
|
||||
* Verify the bit flags field size before accessing it.
|
||||
*/
|
||||
if (os_info_check(os_info) == 0) {
|
||||
os_info_entry = &os_info->entry[OS_INFO_FLAGS_ENTRY];
|
||||
if (os_info_entry_is_valid(os_info_entry) &&
|
||||
os_info_entry->size >= OS_INFO_FLAGS_ENTRY_SIZE)
|
||||
os_info_flags = *((unsigned long *)os_info_entry->addr);
|
||||
else
|
||||
printf("Warning: os_info flags entry is missing or corrupted");
|
||||
} else {
|
||||
printf("Warning: os_info is missing or corrupted");
|
||||
}
|
||||
if (os_info_flags & OS_INFO_FLAG_REIPL_CLEAR)
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
/* Use special diag308 subcode for CCW normal ipl */
|
||||
if (ipib->pb0_hdr.pbt == IPL_PBT_CCW)
|
||||
diag308(DIAG308_LOAD_NORMAL_DUMP, NULL);
|
||||
else
|
||||
diag308(DIAG308_LOAD_NORMAL, NULL);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user