From 029a3f8f523ea03f7a27ffba364a16b057cf970c Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Wed, 5 Oct 2022 07:09:32 +0000 Subject: [PATCH] zdump: add guarded storage support for ELF input and output format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add guarded storage registers support for the ELF input and the ELF output format. See `man 2 s390_guarded_storage` for details about guarded storage. Signed-off-by: Marc Hartmayer Reviewed-by: Steffen Eiden Signed-off-by: Jan Höppner --- zdump/df_elf.c | 6 ++++++ zdump/df_elf.h | 12 ++++++++++++ zdump/dfi.h | 12 +++++++++++- zdump/dfi_elf.c | 14 ++++++++++++++ zdump/dfo_elf.c | 2 ++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/zdump/df_elf.c b/zdump/df_elf.c index 85788ac6..69c51e3c 100644 --- a/zdump/df_elf.c +++ b/zdump/df_elf.c @@ -310,6 +310,11 @@ void *nt_s390_vxrs_high(void *ptr, const struct dfi_cpu *cpu) sizeof(cpu->vxrs_high), NOTE_NAME_LINUX); } +void *nt_s390_gs_cb(void *ptr, const struct dfi_cpu *cpu) +{ + return nt_init(ptr, NT_S390_GS_CB, &cpu->gscb, sizeof(cpu->gscb), NOTE_NAME_LINUX); +} + void *nt_prpsinfo(void *ptr) { struct nt_prpsinfo_64 prpsinfo; @@ -346,6 +351,7 @@ size_t get_max_note_size_per_cpu(void) size += ELF64_NOTE_SIZE(NOTE_NAME_LINUX, sizeof_field(struct dfi_cpu, prefix)); size += ELF64_NOTE_SIZE(NOTE_NAME_LINUX, sizeof_field(struct dfi_cpu, vxrs_low)); size += ELF64_NOTE_SIZE(NOTE_NAME_LINUX, sizeof_field(struct dfi_cpu, vxrs_high)); + size += ELF64_NOTE_SIZE(NOTE_NAME_LINUX, sizeof_field(struct dfi_cpu, gscb)); return size; } diff --git a/zdump/df_elf.h b/zdump/df_elf.h index 40b535ef..2a81fdea 100644 --- a/zdump/df_elf.h +++ b/zdump/df_elf.h @@ -74,6 +74,13 @@ #define NT_S390_VXRS_HIGH 0x30a #endif +/* + * S390 guarded-storage registers note (4 * u64) + */ +#ifndef NT_S390_GS_CB +#define NT_S390_GS_CB 0x30b +#endif + #define NOTE_NAME_CORE "CORE" #define NOTE_NAME_LINUX "LINUX" #define NOTE_NAME_VMCOREINFO "VMCOREINFO" @@ -259,6 +266,11 @@ void *nt_s390_vxrs_low(void *ptr, const struct dfi_cpu *cpu); */ void *nt_s390_vxrs_high(void *ptr, const struct dfi_cpu *cpu); +/* + * Initialize guarded-storage registers note + */ +void *nt_s390_gs_cb(void *ptr, const struct dfi_cpu *cpu); + /* * Initialize prpsinfo note */ diff --git a/zdump/dfi.h b/zdump/dfi.h index 42e51ecd..aa8f6dd9 100644 --- a/zdump/dfi.h +++ b/zdump/dfi.h @@ -99,6 +99,15 @@ struct dfi_cpu { u32 todpreg; u64 vxrs_low[16]; struct dfi_vxrs vxrs_high[16]; + union { + u64 gscb[4]; + struct { + u64 reserved; + u64 gsd; + u64 gssm; + u64 gs_epl_a; + }; + }; u16 cpu_id; }; @@ -127,7 +136,8 @@ enum dfi_cpu_content { DFI_CPU_CONTENT_ALL, /* Complete register information available */ }; -#define DFI_CPU_CONTENT_FAC_VX 0x00000001 +#define DFI_CPU_CONTENT_FAC_VX 0x00000001 +#define DFI_CPU_CONTENT_FAC_GS 0x00000002 int dfi_cpu_content_fac_check(int flags); void dfi_cpu_content_fac_add(int flags); diff --git a/zdump/dfi_elf.c b/zdump/dfi_elf.c index 605904bc..93e46f90 100644 --- a/zdump/dfi_elf.c +++ b/zdump/dfi_elf.c @@ -185,6 +185,15 @@ static int nt_s390_vxrs_high_read(const struct zg_fh *fh, struct dfi_cpu *cpu, return nt_read(fh, note, &cpu->vxrs_high, sizeof(cpu->vxrs_high)); } +/* + * Read s390 gs_cb note + */ +static int nt_s390_gs_cb_read(const struct zg_fh *fh, struct dfi_cpu *cpu, const Elf64_Nhdr *note) +{ + check_cpu(cpu, "S390_GSCB"); + return nt_read(fh, note, &cpu->gscb, sizeof(cpu->gscb)); +} + /* * Add all notes for notes phdr */ @@ -243,6 +252,11 @@ static int pt_notes_add(const Elf64_Phdr *phdr) return -EINVAL; dfi_cpu_content_fac_add(DFI_CPU_CONTENT_FAC_VX); break; + case NT_S390_GS_CB: + if (nt_s390_gs_cb_read(fh, cpu_current, ¬e)) + return -EINVAL; + dfi_cpu_content_fac_add(DFI_CPU_CONTENT_FAC_GS); + break; default: nt_skip(fh, ¬e); break; diff --git a/zdump/dfo_elf.c b/zdump/dfo_elf.c index 555d00dd..2a0ccac2 100644 --- a/zdump/dfo_elf.c +++ b/zdump/dfo_elf.c @@ -80,6 +80,8 @@ static void *notes_init(Elf64_Phdr *phdr, void *segment_start, u64 elf_offset) ptr = nt_s390_vxrs_low(ptr, cpu); ptr = nt_s390_vxrs_high(ptr, cpu); } + if (dfi_cpu_content_fac_check(DFI_CPU_CONTENT_FAC_GS)) + ptr = nt_s390_gs_cb(ptr, cpu); } out: ptr = nt_vmcoreinfo(ptr, dfi_vmcoreinfo_get());