From d7db0dff014a45ffca8f420283ce405e86ba1d8e Mon Sep 17 00:00:00 2001 From: Yaxing Guo Date: Fri, 27 Jun 2025 14:04:07 +0800 Subject: [PATCH] Add page table dump when unhandled signal occurs Signed-off-by: Yaxing Guo --- arch/riscv/kernel/traps.c | 64 +++++++++++++++++++++++++++++++++++++++ lib/Kconfig.debug | 4 +++ 2 files changed, 68 insertions(+) diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 51ebfd23e007..4b889dedee63 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -33,6 +33,8 @@ #include #include +#include + int show_unhandled_signals = 1; static DEFINE_SPINLOCK(die_lock); @@ -111,6 +113,64 @@ void die(struct pt_regs *regs, const char *str) make_task_dead(SIGSEGV); } +#ifdef CONFIG_MY_PT_DUMP_DEBUG +static void debug_dump_pt(struct task_struct *tsk, unsigned long address) +{ + struct mm_struct *mm = tsk->mm; + struct vm_area_struct *vma; + pgd_t *pgd; + p4d_t *p4d; + pud_t *pud; + pmd_t *pmd; + pte_t *ptep; + spinlock_t *ptl; + + vma = find_vma(mm, address); + if (!vma) { + printk("####### %s -- Do not find vma\n", __FUNCTION__); + } + else { + printk("####### %s -- addr:0x%lx, vm_start:0x%lx, vm_end:0x%lx\n", + __FUNCTION__, address, vma->vm_start, vma->vm_end); + } + + printk("============= %s =============\n", __FUNCTION__); + + pgd = pgd_offset(mm, address); + printk("pgdp -- 0x%px(pa: 0x%llx) : 0x%lx\n", pgd, page_to_phys(virt_to_page(pgd)), pgd_val(*pgd)); + if (pgd_none(*pgd) || pgd_bad(*pgd)) + return; + + if (pgtable_l5_enabled) { + p4d = p4d_offset(pgd, address); + printk("p4dp -- 0x%px(pa: 0x%llx) : 0x%lx\n", p4d, page_to_phys(virt_to_page(p4d)), p4d_val(*p4d)); + if (p4d_none(*p4d) || p4d_bad(*p4d)) + return; + } + else + p4d = (p4d_t *)pgd; + + if (pgtable_l4_enabled) { + pud = pud_offset(p4d, address); + printk("pudp -- 0x%px(pa: 0x%llx) : 0x%lx\n", pud, page_to_phys(virt_to_page(pud)), pud_val(*pud)); + if (pud_none(*pud) || unlikely(pud_bad(*pud))) + return; + + } + else + pud = (pud_t *)p4d; + + pmd = pmd_offset(pud, address); + printk("pmdp -- 0x%px(pa: 0x%llx) : 0x%lx\n", pmd, page_to_phys(virt_to_page(pmd)), pmd_val(*pmd)); + + ptep = pte_offset_map_lock(mm, pmd, address, &ptl); + if (!ptep) + return; + printk("ptep -- 0x%px(pa: 0x%llx) : 0x%lx\n", ptep, page_to_phys(virt_to_page(pmd)), pte_val(*ptep)); + pte_unmap_unlock(ptep, ptl); +} +#endif + void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) { struct task_struct *tsk = current; @@ -123,6 +183,10 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) pr_cont("\n"); __show_regs(regs); dump_instr(KERN_INFO, regs); + +#ifdef CONFIG_MY_PT_DUMP_DEBUG + debug_dump_pt(tsk, addr); +#endif } force_sig_fault(signo, code, (void __user *)addr); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 59b6765d86b8..442a85efee0f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1,6 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only menu "Kernel hacking" +config MY_PT_DUMP_DEBUG + bool "Show page table entry on printks when unhandled signal occur" + default y + menu "printk and dmesg options" config PRINTK_TIME