Skip to content

Commit

Permalink
RISCV64: Make crash tool enter command line and support some commands
Browse files Browse the repository at this point in the history
1. Add riscv64_init() implementation, do all necessary machine-specific setup,
   which will be called multiple times during initialization.
2. Add riscv64 sv39/48/57 pagetable macro definitions, the function of converting
   virtual address to a physical address via 4K page table.
   For 2M and 1G pagesize, they will be implemented in the future(currently not supported).
3. Add the implementation of the vtop command, which is used to convert a
   virtual address to a physical address(call the functions defined in 2).
4. Add the implementation to get virtual memory layout, va_bits, phys_ram_base
   from vmcoreinfo. As these configurations changes from time to time, we sent
   a Linux kernel patch to export these configurations, which can simplify the
   development of crash tool.
   The kernel commit: 649d6b1019a2 ("RISC-V: Add arch_crash_save_vmcoreinfo")
5. Add riscv64_get_smp_cpus() implementation, get the number of cpus.
6. Add riscv64_get_page_size() implementation, get page size.
And so on.

With this patch, we can enter crash command line, and run "vtop", "mod", "rd",
"*", "p", "kmem" ...

Tested on QEMU RISCV64 end and SoC platform of T-head Xuantie 910 CPU.

      KERNEL: vmlinux
    DUMPFILE: vmcore
        CPUS: 1
        DATE: Fri Jul 15 10:24:25 CST 2022
      UPTIME: 00:00:33
LOAD AVERAGE: 0.05, 0.01, 0.00
       TASKS: 41
    NODENAME: buildroot
     RELEASE: 5.18.9
     VERSION: #30 SMP Fri Jul 15 09:47:03 CST 2022
     MACHINE: riscv64  (unknown Mhz)
      MEMORY: 1 GB
       PANIC: "Kernel panic - not syncing: sysrq triggered crash"
         PID: 113
     COMMAND: "sh"
        TASK: ff60000002269600  [THREAD_INFO: ff60000002269600]
         CPU: 0
       STATE: TASK_RUNNING (PANIC)

crash> p mem_map
mem_map = $1 = (struct page *) 0xff6000003effbf00

crash> p /x *(struct page *) 0xff6000003effbf00
$5 = {
  flags = 0x1000,
  {
    {
      {
        lru = {
          next = 0xff6000003effbf08,
          prev = 0xff6000003effbf08
        },
        {
          __filler = 0xff6000003effbf08,
          mlock_count = 0x3effbf08
        }
      },
      mapping = 0x0,
      index = 0x0,
      private = 0x0
    },

crash> mod
     MODULE       NAME             BASE         SIZE  OBJECT FILE
ffffffff0113e740  nvme_core  ffffffff01133000  98304  (not loaded)  [CONFIG_KALLSYMS]
ffffffff011542c0  nvme       ffffffff0114c000  61440  (not loaded)  [CONFIG_KALLSYMS]

crash> rd ffffffff0113e740 8
ffffffff0113e740:  0000000000000000 ffffffff810874f8   .........t......
ffffffff0113e750:  ffffffff011542c8 726f635f656d766e   .B......nvme_cor
ffffffff0113e760:  0000000000000065 0000000000000000   e...............
ffffffff0113e770:  0000000000000000 0000000000000000   ................

crash> vtop ffffffff0113e740
VIRTUAL           PHYSICAL
ffffffff0113e740  8254d740

  PGD: ffffffff810e9ff8 => 2ffff001
  P4D: 0000000000000000 => 000000002fffec01
  PUD: 00005605c2957470 => 0000000020949801
  PMD: 00007fff7f1750c0 => 0000000020947401
  PTE: 0 => 209534e7
 PAGE: 000000008254d000

  PTE     PHYSICAL  FLAGS
209534e7  8254d000  (PRESENT|READ|WRITE|GLOBAL|ACCESSED|DIRTY)

      PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS
ff6000003f0777d8 8254d000                0        0  1 0

Tested-by: Yixun Lan <[email protected]>
Signed-off-by: Xianting Tian <[email protected]>
  • Loading branch information
Xianting Tian authored and k-hagio committed Dec 22, 2022
1 parent 12c3156 commit e7119d2
Show file tree
Hide file tree
Showing 3 changed files with 1,101 additions and 0 deletions.
97 changes: 97 additions & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3496,6 +3496,85 @@ struct arm64_stackframe {
#define _64BIT_
#define MACHINE_TYPE "RISCV64"

typedef struct { ulong pgd; } pgd_t;
typedef struct { ulong p4d; } p4d_t;
typedef struct { ulong pud; } pud_t;
typedef struct { ulong pmd; } pmd_t;
typedef struct { ulong pte; } pte_t;
typedef signed int s32;

/* arch/riscv/include/asm/pgtable-64.h */
#define PGD_SHIFT_L3 (30)
#define PGD_SHIFT_L4 (39)
#define PGD_SHIFT_L5 (48)

#define P4D_SHIFT (39)
#define PUD_SHIFT (30)
#define PMD_SHIFT (21)

#define PTRS_PER_PGD (512)
#define PTRS_PER_P4D (512)
#define PTRS_PER_PUD (512)
#define PTRS_PER_PMD (512)
#define PTRS_PER_PTE (512)

/*
* Mask for bit 0~53(PROT and PPN) of PTE
* 63 6261 60 54 53 10 9 8 7 6 5 4 3 2 1 0
* N PBMT Reserved P P N RSW D A G U X W R V
*/
#define PTE_PFN_PROT_MASK 0x3FFFFFFFFFFFFF

/*
* 3-levels / 4K pages
*
* sv39
* PGD | PMD | PTE | OFFSET |
* 9 | 9 | 9 | 12 |
*/
#define pgd_index_l3_4k(addr) (((addr) >> PGD_SHIFT_L3) & (PTRS_PER_PGD - 1))
#define pmd_index_l3_4k(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
#define pte_index_l3_4k(addr) (((addr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))

/*
* 4-levels / 4K pages
*
* sv48
* PGD | PUD | PMD | PTE | OFFSET |
* 9 | 9 | 9 | 9 | 12 |
*/
#define pgd_index_l4_4k(addr) (((addr) >> PGD_SHIFT_L4) & (PTRS_PER_PGD - 1))
#define pud_index_l4_4k(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
#define pmd_index_l4_4k(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
#define pte_index_l4_4k(addr) (((addr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))

/*
* 5-levels / 4K pages
*
* sv57
* PGD | P4D | PUD | PMD | PTE | OFFSET |
* 9 | 9 | 9 | 9 | 9 | 12 |
*/
#define pgd_index_l5_4k(addr) (((addr) >> PGD_SHIFT_L5) & (PTRS_PER_PGD - 1))
#define p4d_index_l5_4k(addr) (((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
#define pud_index_l5_4k(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
#define pmd_index_l5_4k(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
#define pte_index_l5_4k(addr) (((addr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))

#define VM_L3_4K (0x2)
#define VM_L3_2M (0x4)
#define VM_L3_1G (0x8)
#define VM_L4_4K (0x10)
#define VM_L4_2M (0x20)
#define VM_L4_1G (0x40)
#define VM_L5_4K (0x80)
#define VM_L5_2M (0x100)
#define VM_L5_1G (0x200)

#define VM_FLAGS (VM_L3_4K | VM_L3_2M | VM_L3_1G | \
VM_L4_4K | VM_L4_2M | VM_L4_1G | \
VM_L5_4K | VM_L5_2M | VM_L5_1G)

/*
* Direct memory mapping
*/
Expand Down Expand Up @@ -3547,6 +3626,14 @@ struct arm64_stackframe {
#define PHYS_MASK_SHIFT _MAX_PHYSMEM_BITS
#define PHYS_MASK (((1UL) << PHYS_MASK_SHIFT) - 1)

#define IS_LAST_P4D_READ(p4d) ((ulong)(p4d) == machdep->machspec->last_p4d_read)
#define FILL_P4D(P4D, TYPE, SIZE) \
if (!IS_LAST_P4D_READ(P4D)) { \
readmem((ulonglong)((ulong)(P4D)), TYPE, machdep->machspec->p4d, \
SIZE, "p4d page", FAULT_ON_ERROR); \
machdep->machspec->last_p4d_read = (ulong)(P4D); \
}

#endif /* RISCV64 */

#ifdef X86
Expand Down Expand Up @@ -6834,6 +6921,10 @@ struct machine_specific {
ulong _page_soft;

ulong _pfn_shift;
ulong va_bits;
char *p4d;
ulong last_p4d_read;
ulong struct_page_size;

struct riscv64_register *crash_task_regs;
};
Expand All @@ -6857,6 +6948,12 @@ struct machine_specific {
#define _PAGE_PROT_NONE _PAGE_READ
#define _PAGE_PFN_SHIFT 10

/* from 'struct pt_regs' definitions of RISC-V arch */
#define RISCV64_REGS_EPC 0
#define RISCV64_REGS_RA 1
#define RISCV64_REGS_SP 2
#define RISCV64_REGS_FP 8

#endif /* RISCV64 */

/*
Expand Down
10 changes: 10 additions & 0 deletions diskdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,12 @@ get_diskdump_regs_mips(struct bt_info *bt, ulong *eip, ulong *esp)
machdep->get_stack_frame(bt, eip, esp);
}

static void
get_diskdump_regs_riscv64(struct bt_info *bt, ulong *eip, ulong *esp)
{
machdep->get_stack_frame(bt, eip, esp);
}

static void
get_diskdump_regs_sparc64(struct bt_info *bt, ulong *eip, ulong *esp)
{
Expand Down Expand Up @@ -1610,6 +1616,10 @@ get_diskdump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
get_diskdump_regs_sparc64(bt, eip, esp);
break;

case EM_RISCV:
get_diskdump_regs_riscv64(bt, eip, esp);
break;

default:
error(FATAL, "%s: unsupported machine type: %s\n",
DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
Expand Down
Loading

0 comments on commit e7119d2

Please sign in to comment.