From: Heiko Carstens <hca@linux.ibm.com>
To: Alexander Gordeev <agordeev@linux.ibm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Niklas Schnelle <schnelle@linux.ibm.com>,
Matthew Rosato <mjrosato@linux.ibm.com>,
Gerald Schaefer <gerald.schaefer@linux.ibm.com>,
Vineeth Vijayan <vneethv@linux.ibm.com>,
Peter Oberparleiter <oberpar@linux.ibm.com>,
Harald Freudenberger <freude@linux.ibm.com>,
Holger Dengler <dengler@linux.ibm.com>,
Stefan Haberland <sth@linux.ibm.com>,
Jan Hoeppner <hoeppner@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>,
Janosch Frank <frankja@linux.ibm.com>,
Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Subject: [PATCH 08/32] s390/dis: Improve show_code() output
Date: Thu, 1 Oct 2026 12:32:23 +0200 [thread overview]
Message-ID: <20261001103247.1989111-9-hca@linux.ibm.com> (raw)
In-Reply-To: <20261001103247.1989111-1-hca@linux.ibm.com>
Replace the '>' and '*' instruction markers with explicit 'PSW >' and
'PGM >' markers which identify both the PSW address and the faulting
instruction.
Previously, '>' marked the PSW address, while '*' marked the preceding
instruction as a guess for the faulting instruction for suppressing
exceptions:
Krnl Code:
000003ff8dc7bff8: e310f0080004 lg %r1,8(%r15)
*000003ff8dc7bffe: e3a0e0000004 lg %r10,0(%r14)
>000003ff8dc7c004: a7280000 lhi %r2,0
000003ff8dc7c008: eb9ff0900024 stmg %r9,%r15,144(%r15)
Now 'PGM >' explicitly marks the faulting instruction without guessing
and 'PSW >' marks the PSW address:
Krnl Code:
000003ff8dc7bff8: e310f0080004 lg %r1,8(%r15)
PGM >000003ff8dc7bffe: e3a0e0000004 lg %r10,0(%r14)
PSW >000003ff8dc7c004: a7280000 lhi %r2,0
000003ff8dc7c008: eb9ff0900024 stmg %r9,%r15,144(%r15)
For nullifying exceptions where both addresses are the same,
'PGM+PSW >' is printed instead:
Krnl Code:
000003ff8dc7bff8: e310f0080004 lg %r1,8(%r15)
PGM+PSW >000003ff8dc7bffe: e3a0e0000004 lg %r10,0(%r14)
000003ff8dc7c004: a7280000 lhi %r2,0
000003ff8dc7c008: eb9ff0900024 stmg %r9,%r15,144(%r15)
show_code() may also be called in other contexts where pt_regs does not
originate from a program check (e.g. system calls). Introduce and set
PIF_PGM_CHECK to indicate when in program check context, and print the
PGM marker only in such a context.
Note that corner cases are not taken into account. Like before kprobes is
not considered, which means that the disassembly may contain unexpected
instructions, or that disassembly and/or instruction length count as well
as interruption do not match.
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
---
arch/s390/include/asm/ptrace.h | 4 ++++
arch/s390/kernel/dis.c | 16 +++++++++++-----
arch/s390/kernel/early.c | 1 +
arch/s390/kernel/traps.c | 4 +++-
4 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index c844b8aa0fd9..3e56ef8c268b 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -18,12 +18,14 @@
#define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */
#define PIF_FTRACE_FULL_REGS 3 /* all register contents valid (ftrace) */
#define PIF_WARN_TRAP_SKIPPED 4 /* __WARN_trap() was skipped */
+#define PIF_PGM_CHECK 5 /* inside a program check */
#define _PIF_SYSCALL BIT(PIF_SYSCALL)
#define _PIF_ADDR_PSW_ADJUSTED BIT(PIF_PSW_ADDR_ADJUSTED)
#define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET)
#define _PIF_FTRACE_FULL_REGS BIT(PIF_FTRACE_FULL_REGS)
#define _PIF_WARN_TRAP_SKIPPED BIT(PIF_WARN_TRAP_SKIPPED)
+#define _PIF_PGM_CHECK BIT(PIF_PGM_CHECK)
#define PSW32_MASK_PER _AC(0x40000000, UL)
#define PSW32_MASK_DAT _AC(0x04000000, UL)
@@ -242,6 +244,8 @@ static inline void instruction_pointer_set(struct pt_regs *regs,
regs->psw.addr = val;
}
+unsigned long get_trap_ip(struct pt_regs *regs);
+
int regs_query_register_offset(const char *name);
const char *regs_query_register_name(unsigned int offset);
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 5a1a24d211c3..ece0b1e46ad4 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -503,7 +503,8 @@ static int copy_from_regs(struct pt_regs *regs, void *dst, void *src, int len)
void show_code(struct pt_regs *regs)
{
char *mode = user_mode(regs) ? "User" : "Krnl";
- unsigned long addr, pswaddr;
+ unsigned long addr, pswaddr, trapaddr;
+ bool pgm_check;
unsigned char code[64];
char buffer[128], *ptr;
int start, end, opsize, hops, i;
@@ -511,6 +512,9 @@ void show_code(struct pt_regs *regs)
pswaddr = regs->psw.addr;
if (test_pt_regs_flag(regs, PIF_PSW_ADDR_ADJUSTED))
pswaddr = __forward_psw(regs->psw, regs->int_code >> 16);
+ pgm_check = test_pt_regs_flag(regs, PIF_PGM_CHECK);
+ if (pgm_check)
+ trapaddr = get_trap_ip(regs);
/* Get a snapshot of the 64 bytes surrounding the fault address. */
for (start = 32; start && pswaddr >= 34 - start; start -= 2) {
addr = pswaddr - 34 + start;
@@ -545,15 +549,17 @@ void show_code(struct pt_regs *regs)
while (start < end && hops < 8) {
ptr = buffer;
opsize = insn_length(code[start]);
+ addr = pswaddr + start - 32;
if (start == 32 && test_pt_regs_flag(regs, PIF_WARN_TRAP_SKIPPED))
ptr += sprintf(ptr, " WARN RET >");
- else if (start + opsize == 32 && !test_pt_regs_flag(regs, PIF_WARN_TRAP_SKIPPED))
- ptr += sprintf(ptr, " *");
+ else if (pgm_check && addr == trapaddr && start == 32)
+ ptr += sprintf(ptr, " PGM+PSW >");
+ else if (pgm_check && addr == trapaddr)
+ ptr += sprintf(ptr, " PGM >");
else if (start == 32)
- ptr += sprintf(ptr, " >");
+ ptr += sprintf(ptr, " PSW >");
else
ptr += sprintf(ptr, " ");
- addr = pswaddr + start - 32;
ptr += sprintf(ptr, "%px: ", (void *)addr);
if (start + opsize >= end)
break;
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index d875b3b304be..a603e034fa82 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -159,6 +159,7 @@ void __init __do_early_pgm_check(struct pt_regs *regs)
regs->int_parm_long = lc->trans_exc_code;
regs->last_break = lc->pgm_last_break;
regs->monitor_code = lc->monitor_code;
+ set_pt_regs_flag(regs, PIF_PGM_CHECK);
/* Monitor Event? Might be a warning */
if ((regs->int_code & PGM_INT_CODE_MASK) == 0x40) {
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 5e63032a56db..a0937b4a6cf3 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -42,7 +42,7 @@ struct pgm_stat {
static DEFINE_PER_CPU_SHARED_ALIGNED(struct pgm_stat, pgm_stat);
-static inline unsigned long get_trap_ip(struct pt_regs *regs)
+unsigned long get_trap_ip(struct pt_regs *regs)
{
static const unsigned long nullified[2] = { PGM_CHECKS_NULLIFIED };
psw_t psw = regs->psw;
@@ -56,6 +56,7 @@ static inline unsigned long get_trap_ip(struct pt_regs *regs)
psw.addr = __rewind_psw(psw, regs->int_code >> 16);
return psw.addr;
}
+NOKPROBE_SYMBOL(get_trap_ip);
#ifdef CONFIG_GENERIC_BUG
int is_valid_bugaddr(unsigned long addr)
@@ -354,6 +355,7 @@ void noinstr __do_pgm_check(struct pt_regs *regs, unsigned long flags)
regs->int_code = lc->pgm_int_code;
regs->int_parm_long = teid.val;
regs->monitor_code = lc->monitor_code;
+ set_pt_regs_flag(regs, PIF_PGM_CHECK);
trapnr = regs->int_code & PGM_INT_CODE_MASK;
stat = this_cpu_ptr(&pgm_stat);
--
2.53.0
next prev parent reply other threads:[~2026-10-01 10:32 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 10:32 [PATCH 00/32] s390: Improve exception table handling and disassembler Heiko Carstens
2026-10-01 10:32 ` [PATCH 01/32] s390/kprobes: Prevent kprobes on instructions with exception table entry Heiko Carstens
2026-10-01 10:32 ` [PATCH 02/32] s390/early: Fix early warning handling Heiko Carstens
2026-10-01 10:32 ` [PATCH 03/32] s390: Clear pt_regs flags field Heiko Carstens
2026-10-01 10:32 ` [PATCH 04/32] s390/bug: Indicate modified PSW in disassembly Heiko Carstens
2026-10-01 10:32 ` [PATCH 05/32] s390/tools: Rename gen_facilities to gen_bitmaps Heiko Carstens
2026-10-01 10:32 ` [PATCH 06/32] s390/tools: Generate bitmap of nullified program checks Heiko Carstens
2026-10-01 10:32 ` [PATCH 07/32] s390/traps: Handle nullifying program checks in get_trap_ip() Heiko Carstens
2026-10-01 10:32 ` Heiko Carstens [this message]
2026-10-01 10:32 ` [PATCH 09/32] s390/extable: Rework exception handling logic Heiko Carstens
2026-10-01 10:32 ` [PATCH 10/32] s390/diag: Convert amode31 exception tables to EX_TABLE_INSN Heiko Carstens
2026-10-01 10:32 ` [PATCH 11/32] s390/uaccess: Convert inline assembly " Heiko Carstens
2026-10-01 10:32 ` [PATCH 12/32] s390/lib/uaccess: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 13/32] s390/futex: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 14/32] s390/diag: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 15/32] s390/mm/pfault: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 16/32] s390/cpu_mf: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 17/32] s390/cert_store: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 18/32] s390/ipl: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 19/32] s390/hypfs: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 20/32] s390/ap: " Heiko Carstens
2026-10-02 7:54 ` Harald Freudenberger
2026-10-01 10:32 ` [PATCH 21/32] s390/fpu: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 22/32] s390/traps: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 23/32] s390/word-at-a-time: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 24/32] s390/kvm: " Heiko Carstens
2026-10-02 8:24 ` Claudio Imbrenda
2026-10-01 10:32 ` [PATCH 25/32] s390/pci: " Heiko Carstens
2026-10-02 9:12 ` Niklas Schnelle
2026-10-01 10:32 ` [PATCH 26/32] s390/boot: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 27/32] s390/cio: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 28/32] s390/dasd: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 29/32] s390/diag_ftp: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 30/32] s390/sclp: " Heiko Carstens
2026-10-01 10:32 ` [PATCH 31/32] s390/bpf: Simplify exception table entry handling Heiko Carstens
2026-10-01 10:32 ` [PATCH 32/32] s390/extable: Remove EX_TABLE macros and fallback extable search Heiko Carstens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261001103247.1989111-9-hca@linux.ibm.com \
--to=hca@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=dengler@linux.ibm.com \
--cc=frankja@linux.ibm.com \
--cc=freude@linux.ibm.com \
--cc=gerald.schaefer@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hoeppner@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=imbrenda@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=mjrosato@linux.ibm.com \
--cc=oberpar@linux.ibm.com \
--cc=schnelle@linux.ibm.com \
--cc=sth@linux.ibm.com \
--cc=svens@linux.ibm.com \
--cc=vneethv@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®