mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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


  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®