[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250623163836.745702-1-florian.fainelli@broadcom.com>
Date: Mon, 23 Jun 2025 09:38:26 -0700
From: Florian Fainelli <florian.fainelli@...adcom.com>
To: linux-kernel@...r.kernel.org
Cc: Florian Fainelli <florian.fainelli@...adcom.com>,
Jan Kiszka <jan.kiszka@...mens.com>,
Kieran Bingham <kbingham@...nel.org>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: [PATCH] scripts/gdb: Fix interrupts display after MCP on x86
The text line would not be appended to as it should have, it should have
been a '+=' but ended up being a '==', fix that.
Fixes: b0969d7687a7 ("scripts/gdb: print interrupts")
Signed-off-by: Florian Fainelli <florian.fainelli@...adcom.com>
---
scripts/gdb/linux/interrupts.py | 2 +-
scripts/gdb/linux/irq.py | 47 ++++++++++
scripts/gdb/linux/mtree_load_debug.py | 122 ++++++++++++++++++++++++++
3 files changed, 170 insertions(+), 1 deletion(-)
create mode 100644 scripts/gdb/linux/irq.py
create mode 100644 scripts/gdb/linux/mtree_load_debug.py
diff --git a/scripts/gdb/linux/interrupts.py b/scripts/gdb/linux/interrupts.py
index a48b5874663e..419ab98d2e2b 100644
--- a/scripts/gdb/linux/interrupts.py
+++ b/scripts/gdb/linux/interrupts.py
@@ -141,7 +141,7 @@ def x86_show_interupts(prec):
if constants.LX_CONFIG_X86_MCE:
text += x86_show_mce(prec, "&mce_exception_count", "MCE", "Machine check exceptions")
- text == x86_show_mce(prec, "&mce_poll_count", "MCP", "Machine check polls")
+ text += x86_show_mce(prec, "&mce_poll_count", "MCP", "Machine check polls")
text += show_irq_err_count(prec)
diff --git a/scripts/gdb/linux/irq.py b/scripts/gdb/linux/irq.py
new file mode 100644
index 000000000000..b2a3f0e01336
--- /dev/null
+++ b/scripts/gdb/linux/irq.py
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# linux/scripts/gdb/linux/interrupts.py
+#
+# List IRQs using irq_to_desc() backed by maple tree
+
+import gdb
+
+class LxIrqs(gdb.Command):
+ """List active IRQs via irq_to_desc()."""
+
+ def __init__(self):
+ super(LxIrqs, self).__init__("lx-irqs", gdb.COMMAND_USER)
+
+ def invoke(self, arg, from_tty):
+ try:
+ max_irqs = int(gdb.parse_and_eval("nr_irqs"))
+ except gdb.error:
+ max_irqs = 4096 # Fallback value
+
+ print("{:<20} {:<6} {:<20} {}".format("Address", "IRQ", "Handler", "Name"))
+ print("-" * 50)
+
+ for irq in range(max_irqs):
+ try:
+ desc = gdb.parse_and_eval(f"irq_to_desc({irq})")
+ if desc == 0:
+ continue
+
+ ptr = desc
+ desc = desc.dereference()
+ action = desc["action"]
+ if int(action) == 0:
+ continue
+
+ name = action["name"]
+ handler = action["handler"]
+
+ name_str = name.string() if name else "<no name>"
+ print("{:<20} {:<6} {:<20} {}".format(str(ptr), irq, str(handler), name_str))
+
+ except gdb.error:
+ continue
+
+
+LxIrqs()
+
diff --git a/scripts/gdb/linux/mtree_load_debug.py b/scripts/gdb/linux/mtree_load_debug.py
new file mode 100644
index 000000000000..374fe01f2b4f
--- /dev/null
+++ b/scripts/gdb/linux/mtree_load_debug.py
@@ -0,0 +1,122 @@
+import gdb
+
+class MTreeLoad(gdb.Command):
+ def __init__(self):
+ super(MTreeLoad, self).__init__("mtree-load", gdb.COMMAND_USER)
+
+ def invoke(self, arg, from_tty):
+ try:
+ args = gdb.string_to_argv(arg)
+ if len(args) != 2:
+ print("Usage: mtree-load <symbol> <key>")
+ return
+
+ sym_name = args[0]
+ key = int(args[1])
+
+ sym = gdb.parse_and_eval(sym_name)
+ root_val = sym['ma_root']
+ root_ptr_val = root_val.cast(gdb.lookup_type("void").pointer())
+ root_ptr_int = int(root_ptr_val)
+
+ print(f"[debug] Starting at root: {hex(root_ptr_int)}")
+
+ if root_ptr_int == 0 or root_ptr_int == 0xffffffffffffffff:
+ print("[error] Empty or invalid tree root.")
+ return
+
+ clean_ptr_val = root_ptr_val.cast(gdb.lookup_type("unsigned long"))
+ clean_addr = int(clean_ptr_val) & ~0xf
+ print(f"[debug] Untagged node ptr: {hex(clean_addr)}")
+
+ node_ptr_val = gdb.Value(clean_addr).cast(
+ gdb.lookup_type("void").pointer()).cast(
+ gdb.lookup_type("struct maple_node").pointer())
+ node = node_ptr_val.dereference()
+
+ self.walk_node(node)
+
+ except Exception as e:
+ print(f"Initialization or lookup error: {e}")
+
+ def get_slot_count(self, node):
+ try:
+ base = int(node.address.cast(gdb.lookup_type("unsigned long")))
+ meta_end_offset = 264
+ end_ptr = gdb.Value(base + meta_end_offset).cast(
+ gdb.lookup_type('unsigned char').pointer())
+ count = int(end_ptr.dereference())
+ print(f"[debug] Extracted count from meta.end @ {hex(base + meta_end_offset)} = {count}")
+ return count
+ except Exception as e:
+ print(f"[error] Could not determine slot count: {e}")
+ raise
+
+ def walk_node(self, node):
+ count = self.get_slot_count(node)
+ print(f"[debug] Brute-force scanning node with count = {count}")
+
+ base = int(node.address.cast(gdb.lookup_type("unsigned long")))
+ slot_offset = 8
+ pointer_size = gdb.lookup_type("void").pointer().sizeof
+
+ for i in range(count + 1):
+ slot_addr = base + slot_offset + i * pointer_size
+ try:
+ val = gdb.Value(slot_addr).cast(gdb.lookup_type("unsigned long").pointer()).dereference()
+ addr = int(val)
+ except Exception as e:
+ print(f"[error] Failed to read raw slot[{i}] at {hex(slot_addr)}: {e}")
+ continue
+
+ if addr == 0 or addr == 0xffffffffffffffff:
+ print(f"[debug] Skipping null/invalid slot[{i}] = {hex(addr)}")
+ continue
+
+ clean_ptr = addr & ~0xf
+
+ # Attempt to treat it as irq_desc
+ try:
+ irq_desc_ptr = gdb.Value(clean_ptr).cast(
+ gdb.lookup_type("struct irq_desc").pointer())
+ _ = irq_desc_ptr.dereference()
+ self.print_irq_desc(clean_ptr)
+ continue
+ except:
+ pass
+
+ # If not irq_desc, maybe it's another node
+ try:
+ subnode_ptr = gdb.Value(clean_ptr).cast(
+ gdb.lookup_type("void").pointer()).cast(
+ gdb.lookup_type("struct maple_node").pointer())
+ subnode = subnode_ptr.dereference()
+ print(f"[debug] Recursively walking subnode from slot[{i}] = {hex(clean_ptr)}")
+ self.walk_node(subnode)
+ except Exception as e:
+ print(f"[debug] Slot[{i}] @ {hex(clean_ptr)} is not a known structure: {e}")
+
+ def print_irq_desc(self, ptr):
+ try:
+ print(f"[debug] Attempting to print irq_desc at {hex(ptr)}")
+ irq_desc_ptr = gdb.Value(ptr).cast(
+ gdb.lookup_type("struct irq_desc").pointer())
+ irq_desc = irq_desc_ptr.dereference()
+
+ irq_number = int(irq_desc['irq_data']['irq'])
+
+ try:
+ chip = irq_desc['irq_data']['chip']
+ chip_name = chip.dereference().type.name
+ except Exception:
+ chip_name = "<unavailable>"
+
+ print("""--- IRQ Descriptor ---
+ IRQ number: {}
+ Chip type: {}
+----------------------""".format(irq_number, chip_name))
+
+ except Exception as e:
+ print(f"[error] Could not print IRQ descriptor: {e}")
+
+MTreeLoad()
--
2.43.0
Powered by blists - more mailing lists