zgetdump: Update s390 dump common functions

Update df_s390_dumper structure and dumper reading functions to read
certain dumper fields instead of the entire dump tool.
Update other s390 dump common functions in preparation for the new dumper
and the new s390 extended dump format.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Mikhail Zaslonko
2018-04-16 20:24:37 +02:00
committed by Jan Höppner
parent c3821f0821
commit aade05b01d
4 changed files with 122 additions and 137 deletions

View File

@@ -3,7 +3,7 @@
*
* S390 dump format common functions
*
* Copyright IBM Corp. 2001, 2017
* Copyright IBM Corp. 2001, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -41,7 +41,7 @@ void df_s390_cpu_info_add(struct df_s390_hdr *hdr, u64 addr_max)
{
unsigned int i;
if (hdr->version < 5) {
if (hdr->version < 5 && hdr->magic == DF_S390_MAGIC) {
/* No Prefix registers in header */
hdr->cpu_cnt = 0;
dfi_cpu_info_init(DFI_CPU_CONTENT_NONE);
@@ -85,11 +85,14 @@ void df_s390_hdr_add(struct df_s390_hdr *hdr)
dfi_arch_set(df_s390_to_dfi_arch(hdr->arch));
if (hdr->cpu_id)
dfi_attr_cpu_id_set(hdr->cpu_id);
if (hdr->version >= 3 && hdr->mem_size_real)
dfi_attr_mem_size_real_set(hdr->mem_size_real);
if (hdr->version >= 2 && hdr->build_arch)
if ((hdr->version >= 2 || hdr->magic == DF_S390_MAGIC_EXT) &&
hdr->build_arch)
dfi_attr_build_arch_set(df_s390_to_dfi_arch(hdr->build_arch));
if (hdr->version >= 5 && hdr->real_cpu_cnt)
if ((hdr->version >= 3 || hdr->magic == DF_S390_MAGIC_EXT) &&
hdr->mem_size_real)
dfi_attr_mem_size_real_set(hdr->mem_size_real);
if ((hdr->version >= 5 || hdr->magic == DF_S390_MAGIC_EXT) &&
hdr->real_cpu_cnt)
dfi_attr_real_cpu_cnt_set(hdr->real_cpu_cnt);
}
@@ -124,8 +127,38 @@ int df_s390_em_verify(struct df_s390_em *em, struct df_s390_hdr *hdr)
void df_s390_dumper_read(struct zg_fh *fh, int blk_size,
struct df_s390_dumper *dumper)
{
int offset = DF_S390_MAGIC_BLK_ECKD * blk_size;
int bytes_to_read, offset = DF_S390_MAGIC_BLK_ECKD * blk_size;
/*
* First read 3 fields at the start of the dumper. The magic number,
* version and one extra field for the old dumper case (no magic
* number, checking for specific assembler instructions).
*/
bytes_to_read = offsetof(struct df_s390_dumper, force);
zg_seek(fh, offset, ZG_CHECK);
zg_read(fh, dumper, sizeof(*dumper), ZG_CHECK);
zg_read(fh, dumper, bytes_to_read, ZG_CHECK);
if (memcmp(dumper->magic, OLD_DUMPER_HEX_INSTR1, 4) == 0 &&
memcmp(&dumper->size, OLD_DUMPER_HEX_INSTR2, 2) == 0)
/* We found basr r13,0 (old dumper) */
dumper->version = 0;
switch (dumper->version) {
case 1:
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_EXT, 7) == 0 ||
strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_MV_EXT, 7) == 0)
dumper->size = DF_S390_DUMPER_SIZE_V3;
else
dumper->size = DF_S390_DUMPER_SIZE_V1;
break;
case 2:
dumper->size = DF_S390_DUMPER_SIZE_V2;
break;
case 3:
default:
dumper->size = DF_S390_DUMPER_SIZE_V3;
}
/* Read force and mem fields in the end of the dumper */
bytes_to_read = sizeof(dumper->force) + sizeof(dumper->mem);
offset += dumper->size - bytes_to_read;
zg_seek(fh, offset, ZG_CHECK);
zg_read(fh, &dumper->force, bytes_to_read, ZG_CHECK);
}

View File

@@ -3,7 +3,7 @@
*
* S390 dump format common functions
*
* Copyright IBM Corp. 2001, 2017
* Copyright IBM Corp. 2001, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -16,6 +16,7 @@
#include "zg.h"
#define DF_S390_MAGIC 0xa8190173618f23fdULL
#define DF_S390_MAGIC_EXT 0xa8190173618f23feULL
#define DF_S390_HDR_SIZE 0x1000
#define DF_S390_EM_SIZE 16
#define DF_S390_EM_STR "DUMP_END"
@@ -68,6 +69,16 @@ struct df_s390_em {
u64 tod;
} __attribute__((packed));
/*
* Segment header for s390 extended dump format
*/
struct df_s390_dump_segm_hdr {
u64 start;
u64 len;
u64 stop_marker;
u8 reserved[0x1000 - 24];
} __attribute__((packed));
/*
* Convert DFI arch to s390 arch
*/
@@ -84,96 +95,31 @@ static inline enum dfi_arch df_s390_to_dfi_arch(enum df_s390_arch df_s390_arch)
return df_s390_arch == DF_S390_ARCH_64 ? DFI_ARCH_64 : DFI_ARCH_32;
}
/*
* Dump tool structure (version 1)
*/
struct df_s390_dumper_v1 {
char code[0xff7 - 0x8];
u8 force;
u64 mem;
} __attribute__ ((packed));
#define DF_S390_DUMPER_SIZE_V1 0x1000
/*
* Dump tool structure (version 2)
*/
struct df_s390_dumper_v2 {
char code[0x1ff7 - 0x8];
u8 force;
u64 mem;
} __attribute__ ((packed));
#define DF_S390_DUMPER_SIZE_V2 0x2000
/*
* Dump tool structure (version 3 and 4)
*/
struct df_s390_dumper_v3 {
char code[0x2ff7 - 0x8];
u8 force;
u64 mem;
} __attribute__ ((packed));
#define DF_S390_DUMPER_SIZE_V3 0x3000
#define DF_S390_DUMPER_SIZE_V1 0x1000
#define DF_S390_DUMPER_SIZE_V2 0x2000
#define DF_S390_DUMPER_SIZE_V3 0x3000
#define DF_S390_DUMPER_MAGIC32 "ZECKD31"
#define DF_S390_DUMPER_MAGIC64 "ZECKD64"
#define DF_S390_DUMPER_MAGIC_EXT "XECKD64"
#define DF_S390_DUMPER_MAGIC32_FBA "ZDFBA31"
#define DF_S390_DUMPER_MAGIC64_FBA "ZDFBA64"
#define DF_S390_DUMPER_MAGIC_FBA_EXT "XDFBA64"
#define DF_S390_DUMPER_MAGIC_MV "ZMULT64"
#define DF_S390_DUMPER_MAGIC_MV_EXT "XMULT64"
#define OLD_DUMPER_HEX_INSTR1 "\x0d\x10\x47\xf0" /* BASR + 1st halfword of BC */
#define OLD_DUMPER_HEX_INSTR2 "\x0d\xd0" /* BASR 13,0 */
/*
* Dump tool structure
*/
struct df_s390_dumper {
char magic[7];
u8 version;
union {
struct df_s390_dumper_v1 v1;
struct df_s390_dumper_v2 v2;
struct df_s390_dumper_v3 v3;
} d;
char magic[7];
u8 version;
u32 size;
u8 force;
u64 mem;
} __attribute__ ((packed));
/*
* Dumper member access helpers
*/
#define df_s390_dumper_magic(dumper) ((dumper).magic)
#define df_s390_dumper_version(dumper) ((dumper).version)
static inline u64 df_s390_dumper_mem(struct df_s390_dumper *dumper)
{
switch (dumper->version) {
case 1:
return dumper->d.v1.mem;
case 2:
return dumper->d.v2.mem;
case 3:
default:
return dumper->d.v3.mem;
}
}
static inline u8 df_s390_dumper_force(struct df_s390_dumper *dumper)
{
switch (dumper->version) {
case 1:
return dumper->d.v1.force;
case 2:
return dumper->d.v2.force;
case 3:
default:
return dumper->d.v3.force;
}
}
static inline unsigned long df_s390_dumper_size(struct df_s390_dumper *dumper)
{
switch (dumper->version) {
case 1:
return 0x1000;
case 2:
return 0x2000;
case 3:
default:
return 0x3000;
}
}
/*
* s390 dump helpers
*/

View File

@@ -3,7 +3,7 @@
*
* S390 multi-volume dump input format
*
* Copyright IBM Corp. 2001, 2017
* Copyright IBM Corp. 2001, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -109,8 +109,7 @@ static void table_read(struct zg_fh *fh, u16 blk_size,
{
int off;
off = DF_S390_MAGIC_BLK_ECKD * blk_size +
df_s390_dumper_size(&l.dumper);
off = DF_S390_MAGIC_BLK_ECKD * blk_size + l.dumper.size;
zg_seek(fh, off, ZG_CHECK);
zg_read(fh, table, sizeof(*table), ZG_CHECK);
}
@@ -263,7 +262,7 @@ static void vol_init(struct vol *vol, struct vol_parm *vol_parm, int ssid,
l.dump_incomplete = 1;
}
if (strncmp(df_s390_dumper_magic(vol->dumper), "ZMULT64", 7) != 0) {
if (strncmp(vol->dumper.magic, DF_S390_DUMPER_MAGIC_MV, 7) != 0) {
vol->sign = SIGN_INVALID;
l.dump_incomplete = 1;
}
@@ -445,7 +444,7 @@ static int mv_dumper_read(void)
ZG_CHECK_NONE) == -1)
return -ENODEV;
df_s390_dumper_read(g.fh, l.blk_size, &l.dumper);
if (memcmp(df_s390_dumper_magic(l.dumper), "ZMULT64", 7) != 0)
if (memcmp(l.dumper.magic, DF_S390_DUMPER_MAGIC_MV, 7) != 0)
return -ENODEV;
table_read(g.fh, l.blk_size, &l.table);
return 0;
@@ -529,9 +528,9 @@ int dt_s390mv_init(void)
return -ENODEV;
volumes_init();
dt_arch_set(DFI_ARCH_64);
dt_version_set(df_s390_dumper_version(l.dumper));
dt_attr_mem_limit_set(df_s390_dumper_mem(&l.dumper));
dt_attr_force_set(df_s390_dumper_force(&l.dumper));
dt_version_set(l.dumper.version);
dt_attr_mem_limit_set(l.dumper.mem);
dt_attr_force_set(l.dumper.force);
return 0;
}

View File

@@ -3,7 +3,7 @@
*
* S390 single-volume DASD dump tool
*
* Copyright IBM Corp. 2001, 2017
* Copyright IBM Corp. 2001, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -12,8 +12,6 @@
#include <linux/fs.h>
#include "zgetdump.h"
#define HEXINSTR "\x0d\x10\x47\xf0" /* BASR + 1st halfword of BC */
/*
* File local static data
*/
@@ -29,15 +27,13 @@ static int dumper_read_eckd(int blk_size)
{
df_s390_dumper_read(g.fh, blk_size, &l.dumper);
if (strncmp(l.dumper.magic, "ZECKD31", 7) == 0) {
l.dumper_arch = DFI_ARCH_32;
} else if (strncmp(l.dumper.magic, "ZECKD64", 7) == 0) {
if (strncmp(l.dumper.magic, DF_S390_DUMPER_MAGIC64, 7) == 0) {
l.dumper_arch = DFI_ARCH_64;
} else if ((memcmp(l.dumper.magic, HEXINSTR, 4) == 0) &&
(l.dumper.d.v1.code[0] == '\x0d') &&
(l.dumper.d.v1.code[1] == '\xd0')) {
/* We found basr r13,0 (old dumper) */
l.dumper.version = 0;
} else if (strncmp(l.dumper.magic, DF_S390_DUMPER_MAGIC32, 7) == 0) {
l.dumper_arch = DFI_ARCH_32;
} else if (memcmp(l.dumper.magic, OLD_DUMPER_HEX_INSTR1, 4) == 0 &&
l.dumper.version == 0) {
/* We found the old dumper */
l.dumper_arch = DFI_ARCH_UNKNOWN;
} else {
return -ENODEV;
@@ -46,28 +42,18 @@ static int dumper_read_eckd(int blk_size)
}
/*
* Read dump tool from FBA DASD device
* Check FBA dump tool magic number and set architecture attribute
*/
static void dumper_read_fba_gen(int size, void *buffer)
static int dumper_check_fba(struct df_s390_dumper *dumper)
{
zg_seek_end(g.fh, -size, ZG_CHECK);
zg_read(g.fh, buffer, size, ZG_CHECK);
}
/*
* Read dump tool on FBA disk and check its magic number
*/
static int dumper_check_fba(void)
{
if (strncmp(l.dumper.magic, "ZDFBA31", 7) == 0) {
l.dumper_arch = DFI_ARCH_32;
} else if (strncmp(l.dumper.magic, "ZDFBA64", 7) == 0) {
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC64_FBA, 7) == 0) {
l.dumper_arch = DFI_ARCH_64;
} else if ((memcmp(l.dumper.magic, HEXINSTR, 4) == 0) &&
(l.dumper.d.v1.code[0] == '\x0d') &&
(l.dumper.d.v1.code[1] == '\xd0')) {
} else if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC32_FBA, 7) == 0) {
l.dumper_arch = DFI_ARCH_32;
} else if (memcmp(dumper->magic, OLD_DUMPER_HEX_INSTR1, 4) == 0 &&
memcmp(&dumper->size, OLD_DUMPER_HEX_INSTR2, 2) == 0) {
/* We found basr r13,0 (old dumper) */
l.dumper.version = 0;
dumper->version = 0;
l.dumper_arch = DFI_ARCH_UNKNOWN;
} else {
return -ENODEV;
@@ -75,19 +61,40 @@ static int dumper_check_fba(void)
return 0;
}
/*
* Read dump tool from FBA device
*/
static int dumper_read_validate_fba(int size, struct df_s390_dumper *dumper)
{
int bytes_to_read;
/*
* On FBA device the dumper is written at the end of the volume because
* there is not enough space to place it at the beginning due to the
* linux disk layout
*/
zg_seek_end(g.fh, -size, ZG_CHECK);
bytes_to_read = offsetof(struct df_s390_dumper, force);
zg_read(g.fh, dumper, bytes_to_read, ZG_CHECK);
if (dumper_check_fba(dumper) != 0)
return -ENODEV;
dumper->size = size;
bytes_to_read = sizeof(dumper->force) + sizeof(dumper->mem);
zg_seek_end(g.fh, -bytes_to_read, ZG_CHECK);
zg_read(g.fh, &dumper->force, bytes_to_read, ZG_CHECK);
return 0;
}
/*
* Read dump tool on FBA disk and check its magic number
*/
static int dumper_read_fba(void)
{
dumper_read_fba_gen(DF_S390_DUMPER_SIZE_V1, &l.dumper);
if (dumper_check_fba() == 0)
if (dumper_read_validate_fba(DF_S390_DUMPER_SIZE_V3, &l.dumper) == 0)
return 0;
dumper_read_fba_gen(DF_S390_DUMPER_SIZE_V2, &l.dumper);
if (dumper_check_fba() == 0)
if (dumper_read_validate_fba(DF_S390_DUMPER_SIZE_V2, &l.dumper) == 0)
return 0;
dumper_read_fba_gen(DF_S390_DUMPER_SIZE_V3, &l.dumper);
if (dumper_check_fba() == 0)
if (dumper_read_validate_fba(DF_S390_DUMPER_SIZE_V1, &l.dumper) == 0)
return 0;
return -ENODEV;
}
@@ -121,8 +128,8 @@ static int dt_s390sv_init(void)
if (sv_dumper_read() != 0)
return -ENODEV;
dt_arch_set(l.dumper_arch);
dt_version_set(df_s390_dumper_version(l.dumper));
dt_attr_mem_limit_set(df_s390_dumper_mem(&l.dumper));
dt_version_set(l.dumper.version);
dt_attr_mem_limit_set(l.dumper.mem);
return 0;
}