From patchwork Sun Jul 17 04:29:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920431 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 08DC5C433EF for ; Sun, 17 Jul 2022 04:30:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=gVx/lxYYY0fkpkuS3BoAafXAEACCFIheOkgGNjzBlWM=; b=R2xfTk4sPClV/0 4xO2bBo1V6CD6zBkjuZN36TI86Q3FzAnkcLL4ZFXzPcxY+dOms1Zx4OTgcAE0zHDTsxfjlzt5JZsF A0DwSEHJFqeYrKvDSqb7temKKte8gw9fJ+AjQwbOwcH+8N6lsZzcEwmw4hJOCLG5zWqWlHJDOm6XS tzjUzTdOPRrthKqiUfyjKAY8DQLXJPyAQXhtP+OqXTEAAAdrP43cu6jeQTb2Tj6zHcw8wrpT7BG1R NHOcGH0E6X03qHXWdFrWE1hu8vb7yXV6VIQfbGNYenZPJRb9dx7HxwuoUJfgjloqCqDMZRcnwSWb5 MHJo4cPkwnVYFt2akK7g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvun-0040IX-ML; Sun, 17 Jul 2022 04:29:57 +0000 Received: from out30-54.freemail.mail.aliyun.com ([115.124.30.54]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvuY-00404x-Po for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:48 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R201e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046049;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWzC9n_1658032172; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWzC9n_1658032172) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:33 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 1/8] Add RISCV64 framework code support Date: Sun, 17 Jul 2022 12:29:22 +0800 Message-Id: <20220717042929.370022-2-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212943_856369_B76DCB6F X-CRM114-Status: GOOD ( 20.14 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org This patch mainly added some environment configurations, macro definitions, specific architecture structures and some function declarations supported by the RISCV64 architecture. We can use the build command to get the simplest version crash tool: make target=RISCV64 -j2 Signed-off-by: Xianting Tian --- Makefile | 7 +- README | 2 +- configure.c | 39 ++++++++++- defs.h | 155 +++++++++++++++++++++++++++++++++++++++++++- diskdump.c | 11 +++- help.c | 2 +- lkcd_vmdump_v2_v3.h | 2 +- netdump.c | 9 ++- ramdump.c | 2 + riscv64.c | 56 ++++++++++++++++ symbols.c | 10 +++ 11 files changed, 285 insertions(+), 10 deletions(-) create mode 100644 riscv64.c diff --git a/Makefile b/Makefile index 162c2ba..54ebb43 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \ kernel.c test.c gdb_interface.c configure.c net.c dev.c bpf.c \ printk.c \ alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \ - arm.c arm64.c mips.c mips64.c sparc64.c \ + arm.c arm64.c mips.c mips64.c riscv64.c sparc64.c \ extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \ lkcd_common.c lkcd_v1.c lkcd_v2_v3.c lkcd_v5.c lkcd_v7.c lkcd_v8.c\ lkcd_fix_mem.c s390_dump.c lkcd_x86_trace.c \ @@ -84,7 +84,7 @@ OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \ build_data.o kernel.o test.o gdb_interface.o net.o dev.o bpf.o \ printk.o \ alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \ - arm.o arm64.o mips.o mips64.o sparc64.o \ + arm.o arm64.o mips.o mips64.o riscv64.o sparc64.o \ extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \ lkcd_common.o lkcd_v1.o lkcd_v2_v3.o lkcd_v5.o lkcd_v7.o lkcd_v8.o \ lkcd_fix_mem.o s390_dump.o netdump.o diskdump.o makedumpfile.o xendump.o \ @@ -438,6 +438,9 @@ mips.o: ${GENERIC_HFILES} ${REDHAT_HFILES} mips.c mips64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} mips64.c ${CC} -c ${CRASH_CFLAGS} mips64.c ${WARNING_OPTIONS} ${WARNING_ERROR} +riscv64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} riscv64.c + ${CC} -c ${CRASH_CFLAGS} riscv64.c ${WARNING_OPTIONS} ${WARNING_ERROR} + sparc64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} sparc64.c ${CC} -c ${CRASH_CFLAGS} sparc64.c ${WARNING_OPTIONS} ${WARNING_ERROR} diff --git a/README b/README index 5abbce1..5ac5b60 100644 --- a/README +++ b/README @@ -37,7 +37,7 @@ These are the current prerequisites: o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips, - mips64, s390 and s390x-based kernels are supported. Other architectures + mips64, riscv64, s390 and s390x-based kernels are supported. Other architectures may be addressed in the future. o One size fits all -- the utility can be run on any Linux kernel version diff --git a/configure.c b/configure.c index 5188851..0d216d1 100644 --- a/configure.c +++ b/configure.c @@ -107,6 +107,7 @@ void add_extra_lib(char *); #undef MIPS #undef SPARC64 #undef MIPS64 +#undef RISCV64 #define UNKNOWN 0 #define X86 1 @@ -122,6 +123,7 @@ void add_extra_lib(char *); #define MIPS 11 #define SPARC64 12 #define MIPS64 13 +#define RISCV64 14 #define TARGET_X86 "TARGET=X86" #define TARGET_ALPHA "TARGET=ALPHA" @@ -136,6 +138,7 @@ void add_extra_lib(char *); #define TARGET_MIPS "TARGET=MIPS" #define TARGET_MIPS64 "TARGET=MIPS64" #define TARGET_SPARC64 "TARGET=SPARC64" +#define TARGET_RISCV64 "TARGET=RISCV64" #define TARGET_CFLAGS_X86 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64" #define TARGET_CFLAGS_ALPHA "TARGET_CFLAGS=" @@ -158,6 +161,8 @@ void add_extra_lib(char *); #define TARGET_CFLAGS_MIPS_ON_X86_64 "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITS=64" #define TARGET_CFLAGS_MIPS64 "TARGET_CFLAGS=" #define TARGET_CFLAGS_SPARC64 "TARGET_CFLAGS=" +#define TARGET_CFLAGS_RISCV64 "TARGET_CFLAGS=" +#define TARGET_CFLAGS_RISCV64_ON_X86_64 "TARGET_CFLAGS=" #define GDB_TARGET_DEFAULT "GDB_CONF_FLAGS=" #define GDB_TARGET_ARM_ON_X86 "GDB_CONF_FLAGS=--target=arm-elf-linux" @@ -168,6 +173,7 @@ void add_extra_lib(char *); #define GDB_TARGET_PPC64_ON_X86_64 "GDB_CONF_FLAGS=--target=powerpc64le-unknown-linux-gnu" #define GDB_TARGET_MIPS_ON_X86 "GDB_CONF_FLAGS=--target=mipsel-elf-linux" #define GDB_TARGET_MIPS_ON_X86_64 "GDB_CONF_FLAGS=--target=mipsel-elf-linux CFLAGS=-m32 CXXFLAGS=-m32" +#define GDB_TARGET_RISCV64_ON_X86_64 "GDB_CONF_FLAGS=--target=riscv64-unknown-linux-gnu" /* * The original plan was to allow the use of a particular version @@ -404,6 +410,9 @@ get_current_configuration(struct supported_gdb_version *sp) #ifdef __sparc_v9__ target_data.target = SPARC64; #endif +#ifdef __riscv64__ + target_data.target = RISCV64; +#endif set_initial_target(sp); @@ -457,6 +466,12 @@ get_current_configuration(struct supported_gdb_version *sp) if ((target_data.initial_gdb_target != UNKNOWN) && (target_data.host != target_data.initial_gdb_target)) arch_mismatch(sp); + } else if ((target_data.target == X86_64) && + (name_to_target((char *)target_data.target_as_param) == RISCV64)) { + /* + * Build an RISCV64 crash binary on an X86_64 host. + */ + target_data.target = RISCV64; } else { fprintf(stderr, "\ntarget=%s is not supported on the %s host architecture\n\n", @@ -497,6 +512,10 @@ get_current_configuration(struct supported_gdb_version *sp) (target_data.target != MIPS64)) arch_mismatch(sp); + if ((target_data.initial_gdb_target == RISCV64) && + (target_data.target != RISCV64)) + arch_mismatch(sp); + if ((target_data.initial_gdb_target == X86) && (target_data.target != X86)) { if (target_data.target == X86_64) @@ -660,6 +679,9 @@ show_configuration(void) case SPARC64: printf("TARGET: SPARC64\n"); break; + case RISCV64: + printf("TARGET: RISCV64\n"); + break; } if (strlen(target_data.program)) { @@ -777,6 +799,14 @@ build_configure(struct supported_gdb_version *sp) target = TARGET_SPARC64; target_CFLAGS = TARGET_CFLAGS_SPARC64; break; + case RISCV64: + target = TARGET_RISCV64; + if (target_data.host == X86_64) { + target_CFLAGS = TARGET_CFLAGS_RISCV64_ON_X86_64; + gdb_conf_flags = GDB_TARGET_RISCV64_ON_X86_64; + } else + target_CFLAGS = TARGET_CFLAGS_RISCV64; + break; } ldflags = get_extra_flags("LDFLAGS.extra", NULL); @@ -1374,7 +1404,7 @@ make_spec_file(struct supported_gdb_version *sp) printf("Vendor: Red Hat, Inc.\n"); printf("Packager: Dave Anderson \n"); printf("ExclusiveOS: Linux\n"); - printf("ExclusiveArch: %%{ix86} alpha ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64 s390 s390x arm aarch64 ppc64le mips mipsel mips64el sparc64\n"); + printf("ExclusiveArch: %%{ix86} alpha ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64 s390 s390x arm aarch64 ppc64le mips mipsel mips64el sparc64 riscv64\n"); printf("Buildroot: %%{_tmppath}/%%{name}-root\n"); printf("BuildRequires: ncurses-devel zlib-devel bison\n"); printf("Requires: binutils\n"); @@ -1613,6 +1643,8 @@ set_initial_target(struct supported_gdb_version *sp) target_data.initial_gdb_target = MIPS; else if (strncmp(buf, "SPARC64", strlen("SPARC64")) == 0) target_data.initial_gdb_target = SPARC64; + else if (strncmp(buf, "RISCV64", strlen("RISCV64")) == 0) + target_data.initial_gdb_target = RISCV64; } char * @@ -1633,6 +1665,7 @@ target_to_name(int target) case MIPS: return("MIPS"); case MIPS64: return("MIPS64"); case SPARC64: return("SPARC64"); + case RISCV64: return("RISCV64"); } return "UNKNOWN"; @@ -1697,6 +1730,10 @@ name_to_target(char *name) return MIPS64; else if (strncmp(name, "sparc64", strlen("sparc64")) == 0) return SPARC64; + else if (strncmp(name, "RISCV64", strlen("RISCV64")) == 0) + return RISCV64; + else if (strncmp(name, "riscv64", strlen("riscv64")) == 0) + return RISCV64; return UNKNOWN; } diff --git a/defs.h b/defs.h index 9b1b69a..42ffba3 100644 --- a/defs.h +++ b/defs.h @@ -76,7 +76,7 @@ #if !defined(X86) && !defined(X86_64) && !defined(ALPHA) && !defined(PPC) && \ !defined(IA64) && !defined(PPC64) && !defined(S390) && !defined(S390X) && \ !defined(ARM) && !defined(ARM64) && !defined(MIPS) && !defined(MIPS64) && \ - !defined(SPARC64) + !defined(RISCV64) && !defined(SPARC64) #ifdef __alpha__ #define ALPHA #endif @@ -118,6 +118,9 @@ #ifdef __sparc_v9__ #define SPARC64 #endif +#ifdef __riscv64__ +#define RISCV64 +#endif #endif #ifdef X86 @@ -159,6 +162,9 @@ #ifdef SPARC64 #define NR_CPUS (4096) #endif +#ifdef RISCV64 +#define NR_CPUS (256) +#endif #define NR_DEVICE_DUMPS (64) @@ -3484,6 +3490,63 @@ struct arm64_stackframe { #define _MAX_PHYSMEM_BITS 48 #endif /* MIPS64 */ +#ifdef RISCV64 +#define _64BIT_ +#define MACHINE_TYPE "RISCV64" + +/* + * Direct memory mapping + */ +#define PTOV(X) \ + (((unsigned long)(X)+(machdep->kvbase)) - machdep->machspec->phys_base) +#define VTOP(X) ({ \ + ulong _X = X; \ + (THIS_KERNEL_VERSION >= 0x50D00 && \ + (_X) >= machdep->machspec->kernel_link_addr) ? \ + (((unsigned long)(_X)-(machdep->machspec->kernel_link_addr)) + \ + machdep->machspec->phys_base): \ + (((unsigned long)(_X)-(machdep->kvbase)) + \ + machdep->machspec->phys_base); \ + }) +#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask) + +/* + * Stack size order + */ +#define THREAD_SIZE_ORDER 2 + +#define PAGE_OFFSET (machdep->machspec->page_offset) +#define VMALLOC_START (machdep->machspec->vmalloc_start_addr) +#define VMALLOC_END (machdep->machspec->vmalloc_end) +#define VMEMMAP_VADDR (machdep->machspec->vmemmap_vaddr) +#define VMEMMAP_END (machdep->machspec->vmemmap_end) +#define MODULES_VADDR (machdep->machspec->modules_vaddr) +#define MODULES_END (machdep->machspec->modules_end) +#define IS_VMALLOC_ADDR(X) riscv64_IS_VMALLOC_ADDR((ulong)(X)) + +/* from arch/riscv/include/asm/pgtable.h */ +#define __SWP_TYPE_SHIFT 6 +#define __SWP_TYPE_BITS 5 +#define __SWP_TYPE_MASK ((1UL << __SWP_TYPE_BITS) - 1) +#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) + +#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS) + +#define SWP_TYPE(entry) (((entry) >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) +#define SWP_OFFSET(entry) ((entry) >> __SWP_OFFSET_SHIFT) +#define __swp_type(entry) SWP_TYPE(entry) +#define __swp_offset(entry) SWP_OFFSET(entry) + +#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2) + +/* from arch/riscv/include/asm/sparsemem.h */ +#define _SECTION_SIZE_BITS 27 +#define _MAX_PHYSMEM_BITS 56 /* 56-bit physical address supported */ +#define PHYS_MASK_SHIFT _MAX_PHYSMEM_BITS +#define PHYS_MASK (((1UL) << PHYS_MASK_SHIFT) - 1) + +#endif /* RISCV64 */ + #ifdef X86 #define _32BIT_ #define MACHINE_TYPE "X86" @@ -4532,6 +4595,10 @@ struct machine_specific { #define MAX_HEXADDR_STRLEN (16) #define UVADDR_PRLEN (16) #endif +#ifdef RISCV64 +#define MAX_HEXADDR_STRLEN (16) +#define UVADDR_PRLEN (16) +#endif #define BADADDR ((ulong)(-1)) #define BADVAL ((ulong)(-1)) @@ -5126,6 +5193,9 @@ void dump_build_data(void); #ifdef MIPS64 #define machdep_init(X) mips64_init(X) #endif +#ifdef RISCV64 +#define machdep_init(X) riscv64_init(X) +#endif #ifdef SPARC64 #define machdep_init(X) sparc64_init(X) #endif @@ -5606,6 +5676,9 @@ void display_help_screen(char *); #ifdef SPARC64 #define dump_machdep_table(X) sparc64_dump_machdep_table(X) #endif +#ifdef RISCV64 +#define dump_machdep_table(X) riscv64_dump_machdep_table(X) +#endif extern char *help_pointer[]; extern char *help_alias[]; extern char *help_ascii[]; @@ -6682,6 +6755,86 @@ struct machine_specific { #endif /* MIPS64 */ +/* + * riscv64.c + */ +void riscv64_display_regs_from_elf_notes(int, FILE *); + +#ifdef RISCV64 +void riscv64_init(int); +void riscv64_dump_machdep_table(ulong); +int riscv64_IS_VMALLOC_ADDR(ulong); + +#define display_idt_table() \ + error(FATAL, "-d option is not applicable to RISCV64 architecture\n") + +/* from arch/riscv/include/asm/ptrace.h */ +struct riscv64_register { + ulong regs[36]; +}; + +struct riscv64_pt_regs { + ulong badvaddr; + ulong cause; + ulong epc; +}; + +struct riscv64_unwind_frame { + ulong fp; + ulong sp; + ulong pc; +}; + +#define KSYMS_START (0x1) + +struct machine_specific { + ulong phys_base; + ulong page_offset; + ulong vmalloc_start_addr; + ulong vmalloc_end; + ulong vmemmap_vaddr; + ulong vmemmap_end; + ulong modules_vaddr; + ulong modules_end; + ulong kernel_link_addr; + ulong address_space_end; + + ulong _page_present; + ulong _page_read; + ulong _page_write; + ulong _page_exec; + ulong _page_user; + ulong _page_global; + ulong _page_accessed; + ulong _page_dirty; + ulong _page_soft; + + ulong _pfn_shift; + + struct riscv64_register *crash_task_regs; +}; +/* from arch/riscv/include/asm/pgtable-bits.h */ +#define _PAGE_PRESENT (machdep->machspec->_page_present) +#define _PAGE_READ (machdep->machspec->_page_read) +#define _PAGE_WRITE (machdep->machspec->_page_write) +#define _PAGE_EXEC (machdep->machspec->_page_exec) +#define _PAGE_USER (machdep->machspec->_page_user) +#define _PAGE_GLOBAL (machdep->machspec->_page_global) +#define _PAGE_ACCESSED (machdep->machspec->_page_accessed) +#define _PAGE_DIRTY (machdep->machspec->_page_dirty) +#define _PAGE_SOFT (machdep->machspec->_page_soft) +#define _PAGE_SEC (machdep->machspec->_page_sec) +#define _PAGE_SHARE (machdep->machspec->_page_share) +#define _PAGE_BUF (machdep->machspec->_page_buf) +#define _PAGE_CACHE (machdep->machspec->_page_cache) +#define _PAGE_SO (machdep->machspec->_page_so) +#define _PAGE_SPECIAL _PAGE_SOFT +#define _PAGE_TABLE _PAGE_PRESENT +#define _PAGE_PROT_NONE _PAGE_READ +#define _PAGE_PFN_SHIFT 10 + +#endif /* RISCV64 */ + /* * sparc64.c */ diff --git a/diskdump.c b/diskdump.c index 2c1f9be..28503bc 100644 --- a/diskdump.c +++ b/diskdump.c @@ -622,6 +622,9 @@ restart: else if (STRNEQ(header->utsname.machine, "aarch64") && machine_type_mismatch(file, "ARM64", NULL, 0)) goto err; + else if (STRNEQ(header->utsname.machine, "riscv64") && + machine_type_mismatch(file, "RISCV64", NULL, 0)) + goto err; if (header->block_size != block_size) { block_size = header->block_size; @@ -780,6 +783,8 @@ restart: dd->machine_type = EM_AARCH64; else if (machine_type("SPARC64")) dd->machine_type = EM_SPARCV9; + else if (machine_type("RISCV64")) + dd->machine_type = EM_RISCV; else { error(INFO, "%s: unsupported machine type: %s\n", DISKDUMP_VALID() ? "diskdump" : "compressed kdump", @@ -1751,7 +1756,8 @@ dump_note_offsets(FILE *fp) qemu = FALSE; if (machine_type("X86_64") || machine_type("S390X") || machine_type("ARM64") || machine_type("PPC64") || - machine_type("SPARC64") || machine_type("MIPS64")) { + machine_type("SPARC64") || machine_type("MIPS64") || + machine_type("RISCV64")) { note64 = (void *)dd->notes_buf + tot; len = sizeof(Elf64_Nhdr); if (STRNEQ((char *)note64 + len, "QEMU")) @@ -2558,7 +2564,8 @@ dump_registers_for_compressed_kdump(void) if (!KDUMP_CMPRS_VALID() || (dd->header->header_version < 4) || !(machine_type("X86") || machine_type("X86_64") || machine_type("ARM64") || machine_type("PPC64") || - machine_type("MIPS") || machine_type("MIPS64"))) + machine_type("MIPS") || machine_type("MIPS64") || + machine_type("RISCV64"))) error(FATAL, "-r option not supported for this dumpfile\n"); if (machine_type("ARM64") && (kt->cpus != dd->num_prstatus_notes)) diff --git a/help.c b/help.c index 99214c1..253c71b 100644 --- a/help.c +++ b/help.c @@ -9512,7 +9512,7 @@ char *README[] = { " These are the current prerequisites: ", "", " o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips,", -" mips64, s390 and s390x-based kernels are supported. Other architectures", +" mips64, riscv64, s390 and s390x-based kernels are supported. Other architectures", " may be addressed in the future.", "", " o One size fits all -- the utility can be run on any Linux kernel version", diff --git a/lkcd_vmdump_v2_v3.h b/lkcd_vmdump_v2_v3.h index 984c2c2..7fa70b9 100644 --- a/lkcd_vmdump_v2_v3.h +++ b/lkcd_vmdump_v2_v3.h @@ -37,7 +37,7 @@ #if defined(ARM) || defined(X86) || defined(PPC) || defined(S390) || \ defined(S390X) || defined(ARM64) || defined(MIPS) || \ - defined(MIPS64) || defined(SPARC64) + defined(MIPS64) || defined(SPARC64) || defined(RISCV64) /* * Kernel header file for Linux crash dumps. diff --git a/netdump.c b/netdump.c index ff273b4..4ec12a0 100644 --- a/netdump.c +++ b/netdump.c @@ -300,6 +300,12 @@ is_netdump(char *file, ulong source_query) goto bailout; break; + case EM_RISCV: + if (machine_type_mismatch(file, "RISCV64", NULL, + source_query)) + goto bailout; + break; + default: if (machine_type_mismatch(file, "(unknown)", NULL, source_query)) @@ -2935,7 +2941,8 @@ dump_registers_for_elf_dumpfiles(void) if (!(machine_type("X86") || machine_type("X86_64") || machine_type("ARM64") || machine_type("PPC64") || - machine_type("MIPS") || machine_type("MIPS64"))) + machine_type("MIPS") || machine_type("MIPS64") || + machine_type("RISCV64"))) error(FATAL, "-r option not supported for this dumpfile\n"); if (NETDUMP_DUMPFILE()) { diff --git a/ramdump.c b/ramdump.c index a206fcb..d2bd7ff 100644 --- a/ramdump.c +++ b/ramdump.c @@ -188,6 +188,8 @@ char *ramdump_to_elf(void) e_machine = EM_MIPS; else if (machine_type("X86_64")) e_machine = EM_X86_64; + else if (machine_type("RISCV64")) + e_machine = EM_RISCV; else error(FATAL, "ramdump: unsupported machine type: %s\n", MACHINE_TYPE); diff --git a/riscv64.c b/riscv64.c new file mode 100644 index 0000000..c7df857 --- /dev/null +++ b/riscv64.c @@ -0,0 +1,56 @@ +/* riscv64.c - core analysis suite + * + * Copyright (C) 2022 Alibaba Group Holding Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifdef RISCV64 + +#include +#include "defs.h" + +void +riscv64_dump_machdep_table(ulong arg) +{ +} + +/* + * Include both vmalloc'd and module address space as VMALLOC space. + */ +int +riscv64_IS_VMALLOC_ADDR(ulong vaddr) +{ + return ((vaddr >= VMALLOC_START && vaddr <= VMALLOC_END) || + (vaddr >= VMEMMAP_VADDR && vaddr <= VMEMMAP_END) || + (vaddr >= MODULES_VADDR && vaddr <= MODULES_END)); +} + +void +riscv64_init(int when) +{ +} + +void +riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp) +{ +} + +#else /* !RISCV64 */ + +#include "defs.h" + +void +riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp) +{ + return; +} + +#endif /* !RISCV64 */ diff --git a/symbols.c b/symbols.c index bee1faf..ea9e83e 100644 --- a/symbols.c +++ b/symbols.c @@ -3743,6 +3743,11 @@ is_kernel(char *file) goto bailout; break; + case EM_RISCV: + if (machine_type_mismatch(file, "RISCV64", NULL, 0)) + goto bailout; + break; + default: if (machine_type_mismatch(file, "(unknown)", NULL, 0)) goto bailout; @@ -4002,6 +4007,11 @@ is_shared_object(char *file) if (machine_type("MIPS64")) return TRUE; break; + + case EM_RISCV: + if (machine_type("RISCV64")) + return TRUE; + break; } if (CRASHDEBUG(1)) From patchwork Sun Jul 17 04:29:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920429 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3847DC433EF for ; Sun, 17 Jul 2022 04:30:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=grjTjkZdLMQ2WiQe15ArMSpWQSoQdJM99XrMbe0zC3w=; b=w4cys/KIi946Vg BlVogdC8hLLdtwxxMB/i8x4jT87fCYbcJ3MeX9C5jzB6x0Zi4DLQe/vn49zv88eKAv4ka9SG4jdjX oNYC9gAbLAYs7qemAMNblPZDcqhzQfMWdDKcw+RiLmEGIajwlN/alQP5E5G2u+8hA2ezeaUY+TP0F 0zhfQYOItd063dNooniLQnsW37C6XFnHNr0Mv9i6JhUJfpUu42t1IsDHsT91wq4RghhUub2XFCO5J IgYcgmXYn1q9daS9ne0/tlVdhIGwRw0S4LnJerKUgSgVW7VWWhCKAF1R7ILCSC92puU/LYKfPyONx PIv2+M5Y4RO7y7W2IZvQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvui-0040Dh-QW; Sun, 17 Jul 2022 04:29:52 +0000 Received: from out30-132.freemail.mail.aliyun.com ([115.124.30.132]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvuY-00404z-8z for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:47 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045170;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWzxBU_1658032173; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWzxBU_1658032173) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:34 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 2/8] RISCV64: Make crash tool enter command line and support some commands Date: Sun, 17 Jul 2022 12:29:23 +0800 Message-Id: <20220717042929.370022-3-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212942_750795_E7662106 X-CRM114-Status: GOOD ( 20.42 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org 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. 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 send a Linux kernel patch to export these configurations, which can simplify the development of crash tool. The Linux patch: https://patchwork.kernel.org/project/linux-riscv/patch/20220714113300.367854-2-xianting.tian@linux.alibaba.com/ 5. Add riscv64_get_smp_cpus() implementation, get the number of online 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 env 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 Signed-off-by: Xianting Tian --- defs.h | 93 +++++ diskdump.c | 10 + riscv64.c | 983 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1086 insertions(+) diff --git a/defs.h b/defs.h index 42ffba3..be4db94 100644 --- a/defs.h +++ b/defs.h @@ -3494,6 +3494,81 @@ 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 PPN and PROT bit53~0 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 + * + * sv48 + * 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) + /* * Direct memory mapping */ @@ -3545,6 +3620,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 @@ -6810,6 +6893,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; }; @@ -6833,6 +6920,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 */ /* diff --git a/diskdump.c b/diskdump.c index 28503bc..cf5f5d9 100644 --- a/diskdump.c +++ b/diskdump.c @@ -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) { @@ -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", diff --git a/riscv64.c b/riscv64.c index c7df857..9d40297 100644 --- a/riscv64.c +++ b/riscv64.c @@ -16,10 +16,304 @@ #include #include "defs.h" +#include + +static ulong riscv64_get_page_size(void); +static int riscv64_vtop_3level_4k(ulong *pgd, ulong vaddr, + physaddr_t *paddr, int verbose); +static int riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, + physaddr_t *paddr, int verbose); +static int riscv64_vtop_5level_4k(ulong *pgd, ulong vaddr, + physaddr_t *paddr, int verbose); +static void riscv64_page_type_init(void); +static int riscv64_is_kvaddr(ulong vaddr); +static int riscv64_is_uvaddr(ulong vaddr, struct task_context *tc); +static int riscv64_uvtop(struct task_context *tc, ulong vaddr, + physaddr_t *paddr, int verbose); +static int riscv64_kvtop(struct task_context *tc, ulong kvaddr, + physaddr_t *paddr, int verbose); +static void riscv64_cmd_mach(void); +static int riscv64_translate_pte(ulong, void *, ulonglong); +static int riscv64_init_active_task_regs(void); +static int riscv64_get_crash_notes(void); +static int riscv64_get_elf_notes(void); +static void riscv64_get_va_range(struct machine_specific *ms); +static void riscv64_get_struct_page_size(struct machine_specific *ms); + +#define REG_FMT "%016lx" +#define SZ_2G 0x80000000 + +/* + * Holds registers during the crash. + */ +static struct riscv64_register *panic_task_regs; + +/* from arch/riscv/include/asm/stacktrace.h */ +struct stackframe { + ulong fp; + ulong ra; +}; + +static struct machine_specific riscv64_machine_specific = { + ._page_present = (1 << 0), + ._page_read = (1 << 1), + ._page_write = (1 << 2), + ._page_exec = (1 << 3), + ._page_user = (1 << 4), + ._page_global = (1 << 5), + ._page_accessed = (1 << 6), + ._page_dirty = (1 << 7), + ._page_soft = (1 << 8), + + .va_bits = 0, + .struct_page_size = 0, +}; + +static void +pt_level_alloc(char **lvl, char *name) +{ + size_t sz = PAGESIZE(); + void *pointer = malloc(sz); + + if (!pointer) + error(FATAL, name); + *lvl = pointer; +} + +static void +riscv64_get_phys_ram_base(struct machine_specific *ms) +{ + char *string; + + if ((string = pc->read_vmcoreinfo("NUMBER(phys_ram_base)"))) { + ms->phys_base = atol(string); + free(string); + } else + /* + * It can't continue without phys_ram_base. As for qemu rv64 + * env and hardware platform, phys_ram_base may different. + */ + error(FATAL, "cannot read phys_ram_base\n"); +} + +static ulong +riscv64_get_page_size(void) +{ + return memory_page_size(); +} + +static ulong +riscv64_vmalloc_start(void) +{ + return ((ulong)VMALLOC_START); +} + +/* Get the size of struct page {} */ +static void riscv64_get_struct_page_size(struct machine_specific *ms) +{ + char *string; + + string = pc->read_vmcoreinfo("SIZE(page)"); + if (string) + ms->struct_page_size = atol(string); + free(string); +} + +/* + * Get the max shift of the size of struct page. + * Most of the time, it is 64 bytes, but not sure. +*/ +static int riscv64_get_struct_page_max_shift(struct machine_specific *ms) +{ + return (int)ceil(log2(ms->struct_page_size)); +} + +static void +riscv64_cmd_mach(void) +{ + /* TODO: */ +} + +static int +riscv64_verify_symbol(const char *name, ulong value, char type) +{ + /* TODO: */ + return TRUE; +} void riscv64_dump_machdep_table(ulong arg) { + /* TODO: */ +} + +static ulong +riscv64_processor_speed(void) +{ + /* TODO: */ + return 0; +} + +static unsigned long riscv64_get_kernel_version(void) +{ + char *string; + char buf[BUFSIZE]; + char *p1, *p2; + + if (THIS_KERNEL_VERSION) + return THIS_KERNEL_VERSION; + + string = pc->read_vmcoreinfo("OSRELEASE"); + if (string) { + strcpy(buf, string); + + p1 = p2 = buf; + while (*p2 != '.') + p2++; + *p2 = NULLCHAR; + kt->kernel_version[0] = atoi(p1); + + p1 = ++p2; + while (*p2 != '.') + p2++; + *p2 = NULLCHAR; + kt->kernel_version[1] = atoi(p1); + + p1 = ++p2; + while ((*p2 >= '0') && (*p2 <= '9')) + p2++; + *p2 = NULLCHAR; + kt->kernel_version[2] = atoi(p1); + } + free(string); + return THIS_KERNEL_VERSION; +} + +static void riscv64_get_va_range(struct machine_specific *ms) +{ + unsigned long kernel_version = riscv64_get_kernel_version(); + char *string; + + if ((string = pc->read_vmcoreinfo("NUMBER(VA_BITS)"))) { + ms->va_bits = atol(string); + free(string); + } else + goto error; + if ((string = pc->read_vmcoreinfo("NUMBER(PAGE_OFFSET)"))) { + ms->page_offset = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + if ((string = pc->read_vmcoreinfo("NUMBER(VMALLOC_START)"))) { + ms->vmalloc_start_addr = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + if ((string = pc->read_vmcoreinfo("NUMBER(VMALLOC_END)"))) { + ms->vmalloc_end = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + if ((string = pc->read_vmcoreinfo("NUMBER(VMEMMAP_START)"))) { + ms->vmemmap_vaddr = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + if ((string = pc->read_vmcoreinfo("NUMBER(VMEMMAP_END)"))) { + ms->vmemmap_end = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + if ((string = pc->read_vmcoreinfo("NUMBER(KERNEL_LINK_ADDR)"))) { + ms->kernel_link_addr = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + if ((string = pc->read_vmcoreinfo("NUMBER(ADDRESS_SPACE_END)"))) { + ms->address_space_end = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + /* + * From Linux 5.13, the kernel mapping is moved to the last 2GB + * of the address space, modules use the 2GB memory range right + * before the kernel. Before Linux 5.13, modules area is embedded + * in vmalloc area. + * + * 5.13 = 0x5 << 16 | 0xD << 8 + */ + if (kernel_version >= 0x50D00) { + if ((string = pc->read_vmcoreinfo("NUMBER(MODULES_VADDR)"))) { + ms->modules_vaddr = htol(string, QUIET, NULL); + free(string); + } else + goto error; + + if ((string = pc->read_vmcoreinfo("NUMBER(MODULES_END)"))) { + ms->modules_end = htol(string, QUIET, NULL); + free(string); + } else + goto error; + } else { + ms->modules_vaddr = ms->vmalloc_start_addr; + ms->modules_end = ms->vmalloc_end; + } + + if (CRASHDEBUG(8)) { + fprintf(fp, "va_bits : %ld\n", ms->va_bits); + fprintf(fp, "vmemmap : 0x%lx - 0x%lx\n", + ms->vmemmap_vaddr, ms->vmemmap_end); + fprintf(fp, "vmalloc : 0x%lx - 0x%lx\n", + ms->vmalloc_start_addr, ms->vmalloc_end); + fprintf(fp, "lowmem : 0x%lx -\n", ms->page_offset); + fprintf(fp, "mudules : 0x%lx - 0x%lx\n", + ms->modules_vaddr, ms->modules_end); + fprintf(fp, "kernel : 0x%lx - 0x%lx\n", + ms->kernel_link_addr, ms->address_space_end); + } + return; +error: + error(FATAL, "cannot get vm layout\n"); +} + +static int +riscv64_is_kvaddr(ulong vaddr) +{ + if (IS_VMALLOC_ADDR(vaddr)) + return TRUE; + + return (vaddr >= machdep->kvbase); +} + +static int +riscv64_is_uvaddr(ulong vaddr, struct task_context *unused) +{ + if (IS_VMALLOC_ADDR(vaddr)) + return FALSE; + + return (vaddr < machdep->kvbase); +} + +static int +riscv64_is_task_addr(ulong task) +{ + if (tt->flags & THREAD_INFO) + return IS_KVADDR(task); + + return (IS_KVADDR(task) && ALIGNED_STACK_OFFSET(task) == 0); +} + +static int +riscv64_get_smp_cpus(void) +{ + return (get_cpus_online() > 0) ? get_cpus_online() : kt->cpus; } /* @@ -33,11 +327,700 @@ riscv64_IS_VMALLOC_ADDR(ulong vaddr) (vaddr >= MODULES_VADDR && vaddr <= MODULES_END)); } +/* + * Translate a PTE, returning TRUE if the page is present. + * If a physaddr pointer is passed in, don't print anything. + */ +static int +riscv64_translate_pte(ulong pte, void *physaddr, ulonglong unused) +{ + char ptebuf[BUFSIZE]; + char physbuf[BUFSIZE]; + char buf[BUFSIZE]; + int page_present; + int len1, len2, others; + ulong paddr; + + paddr = PTOB(pte >> _PAGE_PFN_SHIFT); + page_present = !!(pte & _PAGE_PRESENT); + + if (physaddr) { + *(ulong *)physaddr = paddr; + return page_present; + } + + sprintf(ptebuf, "%lx", pte); + len1 = MAX(strlen(ptebuf), strlen("PTE")); + fprintf(fp, "%s ", mkstring(buf, len1, CENTER | LJUST, "PTE")); + + if (!page_present) + return page_present; + + sprintf(physbuf, "%lx", paddr); + len2 = MAX(strlen(physbuf), strlen("PHYSICAL")); + fprintf(fp, "%s ", mkstring(buf, len2, CENTER | LJUST, "PHYSICAL")); + + fprintf(fp, "FLAGS\n"); + fprintf(fp, "%s %s ", + mkstring(ptebuf, len1, CENTER | RJUST, NULL), + mkstring(physbuf, len2, CENTER | RJUST, NULL)); + + fprintf(fp, "("); + others = 0; + +#define CHECK_PAGE_FLAG(flag) \ + if ((_PAGE_##flag) && (pte & _PAGE_##flag)) \ + fprintf(fp, "%s" #flag, others++ ? "|" : "") + if (pte) { + CHECK_PAGE_FLAG(PRESENT); + CHECK_PAGE_FLAG(READ); + CHECK_PAGE_FLAG(WRITE); + CHECK_PAGE_FLAG(EXEC); + CHECK_PAGE_FLAG(USER); + CHECK_PAGE_FLAG(GLOBAL); + CHECK_PAGE_FLAG(ACCESSED); + CHECK_PAGE_FLAG(DIRTY); + CHECK_PAGE_FLAG(SOFT); + } else { + fprintf(fp, "no mapping"); + } + + fprintf(fp, ")\n"); + + return page_present; +} + +static void +riscv64_page_type_init(void) +{ + ulong va_bits = machdep->machspec->va_bits; + + /* + * For RISCV64 arch, any level of PTE may be a leaf PTE, + * so in addition to 4KiB pages, + * Sv39 supports 2 MiB megapages, 1 GiB gigapages; + * Sv48 supports 2 MiB megapages, 1 GiB gigapages, 512 GiB terapages; + * Sv57 supports 2 MiB megapages, 1 GiB gigapages, 512 GiB terapages, and 256 TiB petapages. + * + * refs to riscv-privileged spec. + * + * We just support 4KiB, 2MiB, 1GiB now. + */ + switch (machdep->pagesize) + { + case 0x1000: // 4 KiB + machdep->flags |= (va_bits == 57 ? VM_L5_4K : + (va_bits == 48 ? VM_L4_4K : VM_L3_4K)); + break; + case 0x200000: // 2 MiB + /* TODO: */ + case 0x40000000: // 1 GiB + /* TODO: */ + default: + if (machdep->pagesize) + error(FATAL, "invalid/unsupported page size: %d\n", + machdep->pagesize); + else + error(FATAL, "cannot determine page size\n"); + } +} + +static int +riscv64_vtop_3level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose) +{ + ulong *pgd_ptr, pgd_val; + ulong *pmd_ptr, pmd_val; + ulong *pte_ptr, pte_val, pte_pfn; + ulong pt_phys; + + /* PGD */ + pgd_ptr = pgd + pgd_index_l3_4k(vaddr); + FILL_PGD(pgd, KVADDR, PAGESIZE()); + pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr)); + if (verbose) + fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val); + if (!pgd_val) + goto no_page; + pgd_val &= PTE_PFN_PROT_MASK; + pt_phys = (pgd_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PMD */ + FILL_PMD(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pmd_val = ULONG(machdep->pmd + PAGEOFFSET(sizeof(pmd_t) * + pmd_index_l3_4k(vaddr))); + if (verbose) + fprintf(fp, " PMD: %016lx => %016lx\n", (ulong)pmd_ptr, pmd_val); + if (!pmd_val) + goto no_page; + pmd_val &= PTE_PFN_PROT_MASK; + pt_phys = (pmd_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PTE */ + FILL_PTBL(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pte_val = ULONG(machdep->ptbl + PAGEOFFSET(sizeof(pte_t) * + pte_index_l3_4k(vaddr))); + if (verbose) + fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr, pte_val); + if (!pte_val) + goto no_page; + pte_val &= PTE_PFN_PROT_MASK; + pte_pfn = pte_val >> _PAGE_PFN_SHIFT; + + if (!(pte_val & _PAGE_PRESENT)) { + if (verbose) { + fprintf(fp, "\n"); + riscv64_translate_pte((ulong)pte_val, 0, 0); + } + fprintf(fp, " PAGE: %016lx not present\n\n", PAGEBASE(*paddr)); + return FALSE; + } + + *paddr = PTOB(pte_pfn) + PAGEOFFSET(vaddr); + + if (verbose) { + fprintf(fp, " PAGE: %016lx\n\n", PAGEBASE(*paddr)); + riscv64_translate_pte(pte_val, 0, 0); + } + + return TRUE; +no_page: + fprintf(fp, "invalid\n"); + return FALSE; +} + +static int +riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose) +{ + ulong *pgd_ptr, pgd_val; + ulong *pud_ptr, pud_val; + ulong *pmd_ptr, pmd_val; + ulong *pte_ptr, pte_val, pte_pfn; + ulong pt_phys; + + /* PGD */ + pgd_ptr = pgd + pgd_index_l4_4k(vaddr); + FILL_PGD(pgd, KVADDR, PAGESIZE()); + pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr)); + if (verbose) + fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val); + if (!pgd_val) + goto no_page; + pgd_val &= PTE_PFN_PROT_MASK; + pt_phys = (pgd_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PUD */ + FILL_PUD(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pud_val = ULONG(machdep->pud + PAGEOFFSET(sizeof(pud_t) * + pud_index_l4_4k(vaddr))); + if (verbose) + fprintf(fp, " PUD: %016lx => %016lx\n", (ulong)pud_ptr, pud_val); + if (!pud_val) + goto no_page; + pud_val &= PTE_PFN_PROT_MASK; + pt_phys = (pud_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PMD */ + FILL_PMD(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pmd_val = ULONG(machdep->pmd + PAGEOFFSET(sizeof(pmd_t) * + pmd_index_l4_4k(vaddr))); + if (verbose) + fprintf(fp, " PMD: %016lx => %016lx\n", (ulong)pmd_ptr, pmd_val); + if (!pmd_val) + goto no_page; + pmd_val &= PTE_PFN_PROT_MASK; + pt_phys = (pmd_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PTE */ + FILL_PTBL(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pte_val = ULONG(machdep->ptbl + PAGEOFFSET(sizeof(pte_t) * + pte_index_l4_4k(vaddr))); + if (verbose) + fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr, pte_val); + if (!pte_val) + goto no_page; + pte_val &= PTE_PFN_PROT_MASK; + pte_pfn = pte_val >> _PAGE_PFN_SHIFT; + + if (!(pte_val & _PAGE_PRESENT)) { + if (verbose) { + fprintf(fp, "\n"); + riscv64_translate_pte((ulong)pte_val, 0, 0); + } + fprintf(fp, " PAGE: %016lx not present\n\n", PAGEBASE(*paddr)); + return FALSE; + } + + *paddr = PTOB(pte_pfn) + PAGEOFFSET(vaddr); + + if (verbose) { + fprintf(fp, " PAGE: %016lx\n\n", PAGEBASE(*paddr)); + riscv64_translate_pte(pte_val, 0, 0); + } + + return TRUE; +no_page: + fprintf(fp, "invalid\n"); + return FALSE; +} + +static int +riscv64_vtop_5level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose) +{ + ulong *pgd_ptr, pgd_val; + ulong *p4d_ptr, p4d_val; + ulong *pud_ptr, pud_val; + ulong *pmd_ptr, pmd_val; + ulong *pte_ptr, pte_val, pte_pfn; + ulong pt_phys; + + /* PGD */ + pgd_ptr = pgd + pgd_index_l5_4k(vaddr); + FILL_PGD(pgd, KVADDR, PAGESIZE()); + pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr)); + if (verbose) + fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val); + if (!pgd_val) + goto no_page; + pgd_val &= PTE_PFN_PROT_MASK; + pt_phys = (pgd_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* P4D */ + FILL_P4D(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + p4d_val = ULONG(machdep->machspec->p4d + PAGEOFFSET(sizeof(p4d_t) * + p4d_index_l5_4k(vaddr))); + if (verbose) + fprintf(fp, " P4D: %016lx => %016lx\n", (ulong)p4d_ptr, p4d_val); + if (!p4d_val) + goto no_page; + p4d_val &= PTE_PFN_PROT_MASK; + pt_phys = (p4d_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PUD */ + FILL_PUD(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pud_val = ULONG(machdep->pud + PAGEOFFSET(sizeof(pud_t) * + pud_index_l5_4k(vaddr))); + if (verbose) + fprintf(fp, " PUD: %016lx => %016lx\n", (ulong)pud_ptr, pud_val); + if (!pud_val) + goto no_page; + pud_val &= PTE_PFN_PROT_MASK; + pt_phys = (pud_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PMD */ + FILL_PMD(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pmd_val = ULONG(machdep->pmd + PAGEOFFSET(sizeof(pmd_t) * + pmd_index_l4_4k(vaddr))); + if (verbose) + fprintf(fp, " PMD: %016lx => %016lx\n", (ulong)pmd_ptr, pmd_val); + if (!pmd_val) + goto no_page; + pmd_val &= PTE_PFN_PROT_MASK; + pt_phys = (pmd_val >> _PAGE_PFN_SHIFT) << PAGESHIFT(); + + /* PTE */ + FILL_PTBL(PAGEBASE(pt_phys), PHYSADDR, PAGESIZE()); + pte_val = ULONG(machdep->ptbl + PAGEOFFSET(sizeof(pte_t) * + pte_index_l4_4k(vaddr))); + if (verbose) + fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr, pte_val); + if (!pte_val) + goto no_page; + pte_val &= PTE_PFN_PROT_MASK; + pte_pfn = pte_val >> _PAGE_PFN_SHIFT; + + if (!(pte_val & _PAGE_PRESENT)) { + if (verbose) { + fprintf(fp, "\n"); + riscv64_translate_pte((ulong)pte_val, 0, 0); + } + printf("!_PAGE_PRESENT\n"); + return FALSE; + } + + *paddr = PTOB(pte_pfn) + PAGEOFFSET(vaddr); + + if (verbose) { + fprintf(fp, " PAGE: %016lx\n\n", PAGEBASE(*paddr)); + riscv64_translate_pte(pte_val, 0, 0); + } + + return TRUE; +no_page: + fprintf(fp, "invalid\n"); + return FALSE; +} + +static int +riscv64_init_active_task_regs(void) +{ + int retval; + + retval = riscv64_get_crash_notes(); + if (retval == TRUE) + return retval; + + return riscv64_get_elf_notes(); +} + +/* + * Retrieve task registers for the time of the crash. + */ +static int +riscv64_get_crash_notes(void) +{ + struct machine_specific *ms = machdep->machspec; + ulong crash_notes; + Elf64_Nhdr *note; + ulong offset; + char *buf, *p; + ulong *notes_ptrs; + ulong i; + + /* + * crash_notes contains per cpu memory for storing cpu states + * in case of system crash. + */ + if (!symbol_exists("crash_notes")) + return FALSE; + + crash_notes = symbol_value("crash_notes"); + + notes_ptrs = (ulong *)GETBUF(kt->cpus*sizeof(notes_ptrs[0])); + + /* + * Read crash_notes for the first CPU. crash_notes are in standard ELF + * note format. + */ + if (!readmem(crash_notes, KVADDR, ¬es_ptrs[kt->cpus-1], + sizeof(notes_ptrs[kt->cpus-1]), "crash_notes", + RETURN_ON_ERROR)) { + error(WARNING, "cannot read crash_notes\n"); + FREEBUF(notes_ptrs); + return FALSE; + } + + if (symbol_exists("__per_cpu_offset")) { + + /* + * Add __per_cpu_offset for each cpu to form the pointer to the notes + */ + for (i = 0; i < kt->cpus; i++) + notes_ptrs[i] = notes_ptrs[kt->cpus-1] + kt->__per_cpu_offset[i]; + } + + buf = GETBUF(SIZE(note_buf)); + + if (!(panic_task_regs = calloc((size_t)kt->cpus, sizeof(*panic_task_regs)))) + error(FATAL, "cannot calloc panic_task_regs space\n"); + + for (i = 0; i < kt->cpus; i++) { + + if (!readmem(notes_ptrs[i], KVADDR, buf, SIZE(note_buf), "note_buf_t", + RETURN_ON_ERROR)) { + error(WARNING, + "cannot find NT_PRSTATUS note for cpu: %d\n", i); + goto fail; + } + + /* + * Do some sanity checks for this note before reading registers from it. + */ + note = (Elf64_Nhdr *)buf; + p = buf + sizeof(Elf64_Nhdr); + + /* + * dumpfiles created with qemu won't have crash_notes, but there will + * be elf notes; dumpfiles created by kdump do not create notes for + * offline cpus. + */ + if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE())) { + if (DISKDUMP_DUMPFILE()) + note = diskdump_get_prstatus_percpu(i); + else if (KDUMP_DUMPFILE()) + note = netdump_get_prstatus_percpu(i); + if (note) { + /* + * SIZE(note_buf) accounts for a "final note", which is a + * trailing empty elf note header. + */ + long notesz = SIZE(note_buf) - sizeof(Elf64_Nhdr); + + if (sizeof(Elf64_Nhdr) + roundup(note->n_namesz, 4) + + note->n_descsz == notesz) + BCOPY((char *)note, buf, notesz); + } else { + error(WARNING, + "cannot find NT_PRSTATUS note for cpu: %d\n", i); + continue; + } + } + + /* + * Check the sanity of NT_PRSTATUS note only for each online cpu. + */ + if (note->n_type != NT_PRSTATUS) { + error(WARNING, "invalid NT_PRSTATUS note (n_type != NT_PRSTATUS)\n"); + goto fail; + } + if (!STRNEQ(p, "CORE")) { + error(WARNING, "invalid NT_PRSTATUS note (name != \"CORE\"\n"); + goto fail; + } + + /* + * Find correct location of note data. This contains elf_prstatus + * structure which has registers etc. for the crashed task. + */ + offset = sizeof(Elf64_Nhdr); + offset = roundup(offset + note->n_namesz, 4); + p = buf + offset; /* start of elf_prstatus */ + + BCOPY(p + OFFSET(elf_prstatus_pr_reg), &panic_task_regs[i], + sizeof(panic_task_regs[i])); + } + + /* + * And finally we have the registers for the crashed task. This is + * used later on when dumping backtrace. + */ + ms->crash_task_regs = panic_task_regs; + + FREEBUF(buf); + FREEBUF(notes_ptrs); + return TRUE; + +fail: + FREEBUF(buf); + FREEBUF(notes_ptrs); + free(panic_task_regs); + return FALSE; +} + +static int +riscv64_get_elf_notes(void) +{ + struct machine_specific *ms = machdep->machspec; + int i; + + if (!DISKDUMP_DUMPFILE() && !KDUMP_DUMPFILE()) + return false; + + panic_task_regs = calloc(kt->cpus, sizeof(*panic_task_regs)); + if (!panic_task_regs) + error(FATAL, "cannot calloc panic_task_regs space\n"); + + for (i = 0; i < kt->cpus; i++) { + Elf64_Nhdr *note = NULL; + size_t len; + + if (DISKDUMP_DUMPFILE()) + note = diskdump_get_prstatus_percpu(i); + else if (KDUMP_DUMPFILE()) + note = netdump_get_prstatus_percpu(i); + + if (!note) { + error(WARNING, + "cannot find NT_PRSTATUS note for cpu: %d\n", i); + continue; + } + + len = sizeof(Elf64_Nhdr); + len = roundup(len + note->n_namesz, 4); + + BCOPY((char *)note + len + OFFSET(elf_prstatus_pr_reg), + &panic_task_regs[i], sizeof(panic_task_regs[i])); + } + + ms->crash_task_regs = panic_task_regs; + + return TRUE; +} + +/* + * Translates a user virtual address to its physical address. + */ +static int +riscv64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose) +{ + ulong mm, active_mm; + ulong *pgd; + + if (!tc) + error(FATAL, "current context invalid\n"); + + *paddr = 0; + + if (is_kernel_thread(tc->task) && IS_KVADDR(uvaddr)) { + readmem(tc->task + OFFSET(task_struct_active_mm), + KVADDR, &active_mm, sizeof(void *), + "task active_mm contents", FAULT_ON_ERROR); + + if (!active_mm) + error(FATAL, + "no active_mm for this kernel thread\n"); + + readmem(active_mm + OFFSET(mm_struct_pgd), + KVADDR, &pgd, sizeof(long), + "mm_struct pgd", FAULT_ON_ERROR); + } else { + if ((mm = task_mm(tc->task, TRUE))) + pgd = ULONG_PTR(tt->mm_struct + OFFSET(mm_struct_pgd)); + else + readmem(tc->mm_struct + OFFSET(mm_struct_pgd), + KVADDR, &pgd, sizeof(long), "mm_struct pgd", + FAULT_ON_ERROR); + } + + switch (machdep->flags & (VM_L3_4K | VM_L4_4K | VM_L5_4K)) + { + case VM_L3_4K: + return riscv64_vtop_3level_4k(pgd, uvaddr, paddr, verbose); + case VM_L4_4K: + return riscv64_vtop_4level_4k(pgd, uvaddr, paddr, verbose); + case VM_L5_4K: + return riscv64_vtop_5level_4k(pgd, uvaddr, paddr, verbose); + default: + return FALSE; + } +} + +static int +riscv64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) +{ + ulong kernel_pgd; + + if (!IS_KVADDR(kvaddr)) + return FALSE; + + if (!vt->vmalloc_start) { + *paddr = VTOP(kvaddr); + return TRUE; + } + + if (!IS_VMALLOC_ADDR(kvaddr)) { + *paddr = VTOP(kvaddr); + if (!verbose) + return TRUE; + } + + kernel_pgd = vt->kernel_pgd[0]; + *paddr = 0; + + switch (machdep->flags & (VM_L3_4K | VM_L4_4K | VM_L5_4K)) + { + case VM_L3_4K: + return riscv64_vtop_3level_4k((ulong *)kernel_pgd, kvaddr, paddr, verbose); + case VM_L4_4K: + return riscv64_vtop_4level_4k((ulong *)kernel_pgd, kvaddr, paddr, verbose); + case VM_L5_4K: + return riscv64_vtop_5level_4k((ulong *)kernel_pgd, kvaddr, paddr, verbose); + default: + return FALSE; + } +} + void riscv64_init(int when) { + switch (when) { + case SETUP_ENV: + machdep->process_elf_notes = process_elf64_notes; + break; + + case PRE_SYMTAB: + machdep->verify_symbol = riscv64_verify_symbol; + machdep->machspec = &riscv64_machine_specific; + if (pc->flags & KERNEL_DEBUG_QUERY) + return; + + machdep->verify_paddr = generic_verify_paddr; + machdep->ptrs_per_pgd = PTRS_PER_PGD; + break; + + case PRE_GDB: + machdep->pagesize = riscv64_get_page_size(); + machdep->pageshift = ffs(machdep->pagesize) - 1; + machdep->pageoffset = machdep->pagesize - 1; + machdep->pagemask = ~((ulonglong)machdep->pageoffset); + machdep->stacksize = machdep->pagesize << THREAD_SIZE_ORDER; + + riscv64_get_phys_ram_base(machdep->machspec); + riscv64_get_struct_page_size(machdep->machspec); + riscv64_get_va_range(machdep->machspec); + + pt_level_alloc(&machdep->pgd, "cannot malloc pgd space."); + pt_level_alloc(&machdep->machspec->p4d, "cannot malloc p4d space."); + pt_level_alloc(&machdep->pud, "cannot malloc pud space."); + pt_level_alloc(&machdep->pmd, "cannot malloc pmd space."); + pt_level_alloc(&machdep->ptbl, "cannot malloc ptbl space."); + + machdep->last_pgd_read = 0; + machdep->machspec->last_p4d_read = 0; + machdep->last_pud_read = 0; + machdep->last_pmd_read = 0; + machdep->last_ptbl_read = 0; + + machdep->kvbase = machdep->machspec->page_offset; + machdep->identity_map_base = machdep->kvbase; + machdep->is_kvaddr = riscv64_is_kvaddr; + machdep->is_uvaddr = riscv64_is_uvaddr; + machdep->uvtop = riscv64_uvtop; + machdep->kvtop = riscv64_kvtop; + machdep->cmd_mach = riscv64_cmd_mach; + + machdep->vmalloc_start = riscv64_vmalloc_start; + machdep->processor_speed = riscv64_processor_speed; + machdep->get_stackbase = generic_get_stackbase; + machdep->get_stacktop = generic_get_stacktop; + machdep->translate_pte = riscv64_translate_pte; + machdep->memory_size = generic_memory_size; + machdep->is_task_addr = riscv64_is_task_addr; + machdep->get_smp_cpus = riscv64_get_smp_cpus; + machdep->value_to_symbol = generic_machdep_value_to_symbol; + machdep->show_interrupts = generic_show_interrupts; + machdep->get_irq_affinity = generic_get_irq_affinity; + machdep->init_kernel_pgd = NULL; /* pgd set by symbol_value("swapper_pg_dir") */ + break; + + case POST_GDB: + machdep->section_size_bits = _SECTION_SIZE_BITS; + machdep->max_physmem_bits = _MAX_PHYSMEM_BITS; + riscv64_page_type_init(); + + if (!machdep->hz) + machdep->hz = 250; + + if (symbol_exists("irq_desc")) + ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc, + "irq_desc", NULL, 0); + else if (kernel_symbol_exists("nr_irqs")) + get_symbol_data("nr_irqs", sizeof(unsigned int), + &machdep->nr_irqs); + + MEMBER_OFFSET_INIT(elf_prstatus_pr_reg, "elf_prstatus", + "pr_reg"); + + STRUCT_SIZE_INIT(note_buf, "note_buf_t"); + break; + + case POST_VM: + /* + * crash_notes contains machine specific information about the + * crash. In particular, it contains CPU registers at the time + * of the crash. We need this information to extract correct + * backtraces from the panic task. + */ + if (!ACTIVE() && !riscv64_init_active_task_regs()) + error(WARNING, + "cannot retrieve registers for active task%s\n\n", + kt->cpus > 1 ? "s" : ""); + break; + } } +/* + * 'help -r' command output + */ void riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp) { From patchwork Sun Jul 17 04:29:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920427 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3ABE8CCA47B for ; Sun, 17 Jul 2022 04:30:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=M9gom6Mg5ww/TPhNPaBlHYwx+WT0CXP7pEkBSMgIXSo=; b=RW89XdjMLndwCh AcCdWzpuL6INmg5vlSkYWhy0K6AxeOj4/7yUzF49+67cm7cyUSN3kv12xncqMEQIJM35cKQYR9Q3j 3DDaTSyj0wQOhI+Or4nhLwdmDOO97NMgwFAAsSpvwofeQc0P9JRR66cfdTPc+nQfEK1gSf9H26DIL QDA+RIce9TnFVDBgjvs2oJLcqEszWRGKtoOB/jonfCc6AfUHtoz4nBu1quc9ekUI3w1vPNauglH4O DJVfkIUThQKMbRJ1Fy/wsLb3jL925BJWM8C4WbsnTMcCbhHKRfGYjtOj4ZW35CjlQ/R+D9p4T1J0X e+Li1ZJeL55RhigkJZXA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvug-0040CT-Ad; Sun, 17 Jul 2022 04:29:50 +0000 Received: from out30-42.freemail.mail.aliyun.com ([115.124.30.42]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvuZ-00405g-PG for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:46 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046059;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWzCAY_1658032174; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWzCAY_1658032174) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:35 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 3/8] RISCV64: Add 'dis' command support Date: Sun, 17 Jul 2022 12:29:24 +0800 Message-Id: <20220717042929.370022-4-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212944_044554_CBBB9F2C X-CRM114-Status: UNSURE ( 4.89 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Use generic_dis_filter() function to support dis command implementation. With this patch, we can get the disassembled code, sh> dis __crash_kexec 0xffffffff80088580 <__crash_kexec>: addi sp,sp,-352 0xffffffff80088582 <__crash_kexec+2>: sd s0,336(sp) 0xffffffff80088584 <__crash_kexec+4>: sd s1,328(sp) 0xffffffff80088586 <__crash_kexec+6>: sd s2,320(sp) 0xffffffff80088588 <__crash_kexec+8>: addi s0,sp,352 0xffffffff8008858a <__crash_kexec+10>: sd ra,344(sp) 0xffffffff8008858c <__crash_kexec+12>: sd s3,312(sp) 0xffffffff8008858e <__crash_kexec+14>: sd s4,304(sp) 0xffffffff80088590 <__crash_kexec+16>: auipc s2,0x1057 0xffffffff80088594 <__crash_kexec+20>: addi s2,s2,-1256 0xffffffff80088598 <__crash_kexec+24>: ld a5,0(s2) 0xffffffff8008859c <__crash_kexec+28>: mv s1,a0 0xffffffff8008859e <__crash_kexec+30>: auipc a0,0xfff Signed-off-by: Xianting Tian --- riscv64.c | 1 + 1 file changed, 1 insertion(+) diff --git a/riscv64.c b/riscv64.c index 9d40297..a812635 100644 --- a/riscv64.c +++ b/riscv64.c @@ -977,6 +977,7 @@ riscv64_init(int when) machdep->is_task_addr = riscv64_is_task_addr; machdep->get_smp_cpus = riscv64_get_smp_cpus; machdep->value_to_symbol = generic_machdep_value_to_symbol; + machdep->dis_filter = generic_dis_filter; machdep->show_interrupts = generic_show_interrupts; machdep->get_irq_affinity = generic_get_irq_affinity; machdep->init_kernel_pgd = NULL; /* pgd set by symbol_value("swapper_pg_dir") */ From patchwork Sun Jul 17 04:29:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920430 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8D5B1C43334 for ; Sun, 17 Jul 2022 04:30:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=IF0bhhy+TN6koeIS3cqjCVM+ui/8HJ/nlmdBE0IvLQ8=; b=cS7mHcl57oQEPT 9ITs41Y/TPrnji9V5uvCWPR4gsafZyWZUF0VqrMxpbYccy7x/4yJmpb4y9sjJ7zNEZtNv1LiypEF3 oT8NZLiGXDXXEsJqEBhQZryWdsWN5uSvi4W20jZozBsLDx9rzIfxGC53WMc9v3PbCeUjSR0pkw5o5 5nLvj3nPRNy05ItocU2n3Alh35TRg9SSvnUJRRb75JefThgDvLbHjXuFFSw1fY6QpDWfVbjOYHp7r PD78EqRUr7h8CkXGofgTQkeRtQu6DJkVR0arG87XpwM6wYfvYJnb7vfJEkyMqdDnTChDq9Uixi5W+ IK3mzLTuDzf4ZHpsgZFg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvul-0040GJ-VP; Sun, 17 Jul 2022 04:29:55 +0000 Received: from out30-130.freemail.mail.aliyun.com ([115.124.30.130]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvub-00405h-70 for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:48 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R161e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045170;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWzCAl_1658032175; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWzCAl_1658032175) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:36 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 4/8] RISCV64: Add 'irq' command support Date: Sun, 17 Jul 2022 12:29:25 +0800 Message-Id: <20220717042929.370022-5-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212945_468544_CB78E99D X-CRM114-Status: UNSURE ( 4.70 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org With the patch, we can get the irq info, crash> irq IRQ IRQ_DESC/_DATA IRQACTION NAME 0 (unused) (unused) 1 ff60000001329600 ff60000001d17180 "101000.rtc" 2 ff60000001329800 ff60000001d17680 "ttyS0" 3 ff60000001329a00 ff60000001c33c00 "virtio0" 4 ff60000001329c00 ff60000001c33f80 "virtio1" 5 ff6000000120f400 ff60000001216000 "riscv-timer" Signed-off-by: Xianting Tian --- riscv64.c | 1 + 1 file changed, 1 insertion(+) diff --git a/riscv64.c b/riscv64.c index a812635..465834f 100644 --- a/riscv64.c +++ b/riscv64.c @@ -978,6 +978,7 @@ riscv64_init(int when) machdep->get_smp_cpus = riscv64_get_smp_cpus; machdep->value_to_symbol = generic_machdep_value_to_symbol; machdep->dis_filter = generic_dis_filter; + machdep->dump_irq = generic_dump_irq; machdep->show_interrupts = generic_show_interrupts; machdep->get_irq_affinity = generic_get_irq_affinity; machdep->init_kernel_pgd = NULL; /* pgd set by symbol_value("swapper_pg_dir") */ From patchwork Sun Jul 17 04:29:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920432 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 25BF1C43334 for ; Sun, 17 Jul 2022 04:30:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=yPRt/FUiSV7FGizKWeATNRYMCUeVRI09y91J+i/5RSM=; b=SSYCcmv+WbBDqU jg6OBI/6xHyMRxHpWclHv6exPnxKJFfaQKtQXtkIhU7peLXkcffOqKklkc+TKJ0aE9RHoT2Sq4+MK sHSyhsz+9b8StXg18JuGCVzCLDYVbenZLb7D60OIlixGV2ZXU5K5FYQgG4Rn7nndtczVNtjz0Q2RM LpRdRlNekUDFfRzGPY0CH15OyWOVSqMf3WJAJHJY33U06CqQazNUJX6X8I5IHOW+qMysLGVKxr41s Mp4jGnBk0i8bADb5eQEN3PKJUee4Q2sJs7go2ad3l1lczWo2L7GKvZRsY3DAE4QiPk9fw7z0TU/l5 zwsBVRoU36cU2CkmGq7A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvup-0040K3-0p; Sun, 17 Jul 2022 04:29:59 +0000 Received: from out199-17.us.a.mail.aliyun.com ([47.90.199.17]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvub-00406Q-Vi for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:49 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R151e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045170;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWxqTe_1658032176; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWxqTe_1658032176) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:37 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 5/8] RISCV64: Add 'bt' command support Date: Sun, 17 Jul 2022 12:29:26 +0800 Message-Id: <20220717042929.370022-6-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212946_351330_AB87B310 X-CRM114-Status: GOOD ( 16.26 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org 1, Add the implementation to get stack frame from active & inactive task's stack. 2, Add 'bt -l' command support get a line number associated with a current pc address. 3, Add 'bt -f' command support to display all stack data contained in a frame With the patch, we can get the backtrace, crash> bt PID: 113 TASK: ff6000000226c200 CPU: 0 COMMAND: "sh" #0 [ff20000010333b90] riscv_crash_save_regs at ffffffff800078f8 #1 [ff20000010333cf0] panic at ffffffff806578c6 #2 [ff20000010333d50] sysrq_reset_seq_param_set at ffffffff8038c03c #3 [ff20000010333da0] __handle_sysrq at ffffffff8038c604 #4 [ff20000010333e00] write_sysrq_trigger at ffffffff8038cae4 #5 [ff20000010333e20] proc_reg_write at ffffffff801b7ee8 #6 [ff20000010333e40] vfs_write at ffffffff80152bb2 #7 [ff20000010333e80] ksys_write at ffffffff80152eda #8 [ff20000010333ed0] sys_write at ffffffff80152f52 crash> bt -l PID: 113 TASK: ff6000000226c200 CPU: 0 COMMAND: "sh" #0 [ff20000010333b90] riscv_crash_save_regs at ffffffff800078f8 /buildroot/qemu_riscv64_virt_defconfig/build/linux-custom/arch/riscv/kernel/crash_save_regs.S: 47 #1 [ff20000010333cf0] panic at ffffffff806578c6 /buildroot/qemu_riscv64_virt_defconfig/build/linux-custom/kernel/panic.c: 276 ... ... crash> bt -f PID: 113 TASK: ff6000000226c200 CPU: 0 COMMAND: "sh" #0 [ff20000010333b90] riscv_crash_save_regs at ffffffff800078f8 [PC: ffffffff800078f8 RA: ffffffff806578c6 SP: ff20000010333b90 SIZE: 352] ff20000010333b90: ff20000010333bb0 ffffffff800078f8 ff20000010333ba0: ffffffff8008862c ff20000010333b90 ff20000010333bb0: ffffffff810dde38 ff6000000226c200 ff20000010333bc0: ffffffff8032be68 0720072007200720 ... ... Signed-off-by: Xianting Tian --- netdump.c | 13 +++ riscv64.c | 283 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) diff --git a/netdump.c b/netdump.c index 4ec12a0..1f418e6 100644 --- a/netdump.c +++ b/netdump.c @@ -42,6 +42,7 @@ static void get_netdump_regs_ppc64(struct bt_info *, ulong *, ulong *); static void get_netdump_regs_arm(struct bt_info *, ulong *, ulong *); static void get_netdump_regs_arm64(struct bt_info *, ulong *, ulong *); static void get_netdump_regs_mips(struct bt_info *, ulong *, ulong *); +static void get_netdump_regs_riscv(struct bt_info *, ulong *, ulong *); static void check_dumpfile_size(char *); static int proc_kcore_init_32(FILE *, int); static int proc_kcore_init_64(FILE *, int); @@ -2675,6 +2676,10 @@ get_netdump_regs(struct bt_info *bt, ulong *eip, ulong *esp) return get_netdump_regs_mips(bt, eip, esp); break; + case EM_RISCV: + return get_netdump_regs_riscv(bt, eip, esp); + break; + default: error(FATAL, "support for ELF machine type %d not available\n", @@ -2931,6 +2936,8 @@ display_regs_from_elf_notes(int cpu, FILE *ofp) mips_display_regs_from_elf_notes(cpu, ofp); } else if (machine_type("MIPS64")) { mips64_display_regs_from_elf_notes(cpu, ofp); + } else if (machine_type("RISCV64")) { + riscv64_display_regs_from_elf_notes(cpu, ofp); } } @@ -3877,6 +3884,12 @@ get_netdump_regs_mips(struct bt_info *bt, ulong *eip, ulong *esp) machdep->get_stack_frame(bt, eip, esp); } +static void +get_netdump_regs_riscv(struct bt_info *bt, ulong *eip, ulong *esp) +{ + machdep->get_stack_frame(bt, eip, esp); +} + int is_partial_netdump(void) { diff --git a/riscv64.c b/riscv64.c index 465834f..c00ce90 100644 --- a/riscv64.c +++ b/riscv64.c @@ -33,6 +33,17 @@ static int riscv64_uvtop(struct task_context *tc, ulong vaddr, static int riscv64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose); static void riscv64_cmd_mach(void); +static void riscv64_stackframe_init(void); +static void riscv64_back_trace_cmd(struct bt_info *bt); +static int riscv64_get_dumpfile_stack_frame(struct bt_info *bt, + ulong *nip, ulong *ksp); +static void riscv64_get_stack_frame(struct bt_info *bt, ulong *pcp, + ulong *spp); +static int riscv64_get_frame(struct bt_info *bt, ulong *pcp, + ulong *spp); +static void riscv64_display_full_frame(struct bt_info *bt, + struct riscv64_unwind_frame *current, + struct riscv64_unwind_frame *previous); static int riscv64_translate_pte(ulong, void *, ulonglong); static int riscv64_init_active_task_regs(void); static int riscv64_get_crash_notes(void); @@ -650,6 +661,275 @@ no_page: return FALSE; } +/* + * 'bt -f' commend output + * Display all stack data contained in a frame + */ +static void +riscv64_display_full_frame(struct bt_info *bt, struct riscv64_unwind_frame *current, + struct riscv64_unwind_frame *previous) +{ + int i, u_idx; + ulong *up; + ulong words, addr; + char buf[BUFSIZE]; + + if (previous->sp < current->sp) + return; + + if (!(INSTACK(previous->sp, bt) && INSTACK(current->sp, bt))) + return; + + words = (previous->sp - current->sp) / sizeof(ulong) + 1; + addr = current->sp; + u_idx = (current->sp - bt->stackbase) / sizeof(ulong); + + for (i = 0; i < words; i++, u_idx++) { + if (!(i & 1)) + fprintf(fp, "%s %lx: ", i ? "\n" : "", addr); + + up = (ulong *)(&bt->stackbuf[u_idx*sizeof(ulong)]); + fprintf(fp, "%s ", format_stack_entry(bt, buf, *up, 0)); + addr += sizeof(ulong); + } + fprintf(fp, "\n"); + + return; +} + +static void +riscv64_stackframe_init(void) +{ + long task_struct_thread = MEMBER_OFFSET("task_struct", "thread"); + + /* from arch/riscv/include/asm/processor.h */ + long thread_reg_ra = MEMBER_OFFSET("thread_struct", "ra"); + long thread_reg_sp = MEMBER_OFFSET("thread_struct", "sp"); + long thread_reg_fp = MEMBER_OFFSET("thread_struct", "s"); + + if ((task_struct_thread == INVALID_OFFSET) || + (thread_reg_ra == INVALID_OFFSET) || + (thread_reg_sp == INVALID_OFFSET) || + (thread_reg_fp == INVALID_OFFSET) ) { + error(FATAL, + "cannot determine thread_struct offsets\n"); + return; + } + + ASSIGN_OFFSET(task_struct_thread_context_pc) = + task_struct_thread + thread_reg_ra; + ASSIGN_OFFSET(task_struct_thread_context_sp) = + task_struct_thread + thread_reg_sp; + ASSIGN_OFFSET(task_struct_thread_context_fp) = + task_struct_thread + thread_reg_fp; +} + +static void +riscv64_dump_backtrace_entry(struct bt_info *bt, struct syment *sym, + struct riscv64_unwind_frame *current, + struct riscv64_unwind_frame *previous, int level) +{ + const char *name = sym ? sym->name : "(invalid)"; + struct load_module *lm; + char *name_plus_offset = NULL; + struct syment *symp; + ulong symbol_offset; + char buf[BUFSIZE]; + + if (bt->flags & BT_SYMBOL_OFFSET) { + symp = value_search(current->pc, &symbol_offset); + + if (symp && symbol_offset) + name_plus_offset = + value_to_symstr(current->pc, buf, bt->radix); + } + + fprintf(fp, "%s#%d [%016lx] %s at %016lx", + level < 10 ? " " : "", + level, + current->sp, + name_plus_offset ? name_plus_offset : name, + current->pc); + + if (module_symbol(current->pc, NULL, &lm, NULL, 0)) + fprintf(fp, " [%s]", lm->mod_name); + + fprintf(fp, "\n"); + + /* + * 'bt -l', get a line number associated with a current pc address. + */ + if (bt->flags & BT_LINE_NUMBERS) { + get_line_number(current->pc, buf, FALSE); + if (strlen(buf)) + fprintf(fp, " %s\n", buf); + } + + /* bt -f */ + if (bt->flags & BT_FULL) { + fprintf(fp, " " + "[PC: %016lx RA: %016lx SP: %016lx SIZE: %ld]\n", + current->pc, + previous->pc, + current->sp, + previous->sp - current->sp); + riscv64_display_full_frame(bt, current, previous); + } +} + +/* + * Unroll a kernel stack. + */ +static void +riscv64_back_trace_cmd(struct bt_info *bt) +{ + struct riscv64_unwind_frame current, previous; + struct stackframe curr_frame; + int level = 0; + + if (bt->flags & BT_REGS_NOT_FOUND) + return; + + current.pc = bt->instptr; + current.sp = bt->stkptr; + current.fp = bt->frameptr; + + if (!INSTACK(current.sp, bt)) + return; + + for (;;) { + struct syment *symbol = NULL; + struct stackframe *frameptr; + ulong low, high; + ulong offset; + + if (CRASHDEBUG(8)) + fprintf(fp, "level %d pc %#lx sp %lx fp 0x%lx\n", + level, current.pc, current.sp, current.fp); + + /* Validate frame pointer */ + low = current.sp + sizeof(struct stackframe); + high = bt->stacktop; + if (current.fp < low || current.fp > high || current.fp & 0x7) { + if (CRASHDEBUG(8)) + fprintf(fp, "fp 0x%lx sp 0x%lx low 0x%lx high 0x%lx\n", + current.fp, current.sp, low, high); + return; + } + + symbol = value_search(current.pc, &offset); + if (!symbol) + return; + + frameptr = (struct stackframe *)current.fp - 1; + if (!readmem((ulong)frameptr, KVADDR, &curr_frame, + sizeof(curr_frame), "get stack frame", RETURN_ON_ERROR)) + return; + + previous.pc = curr_frame.ra; + previous.fp = curr_frame.fp; + previous.sp = current.fp; + + riscv64_dump_backtrace_entry(bt, symbol, ¤t, &previous, level++); + + current.pc = previous.pc; + current.fp = previous.fp; + current.sp = previous.sp; + + if (CRASHDEBUG(8)) + fprintf(fp, "next %d pc %#lx sp %#lx fp %lx\n", + level, current.pc, current.sp, current.fp); + } +} + +/* + * Get a stack frame combination of pc and ra from the most relevant spot. + */ +static void +riscv64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp) +{ + ulong ksp = 0, nip = 0; + int ret = 0; + + if (DUMPFILE() && is_task_active(bt->task)) + ret = riscv64_get_dumpfile_stack_frame(bt, &nip, &ksp); + else + ret = riscv64_get_frame(bt, &nip, &ksp); + + if (pcp) + *pcp = nip; + if (spp) + *spp = ksp; +} + +/* + * Get the starting point for the active cpu in a diskdump. + */ +static int +riscv64_get_dumpfile_stack_frame(struct bt_info *bt, ulong *nip, ulong *ksp) +{ + const struct machine_specific *ms = machdep->machspec; + struct riscv64_register *regs; + ulong epc, sp; + + if (!ms->crash_task_regs) { + bt->flags |= BT_REGS_NOT_FOUND; + return FALSE; + } + + /* + * We got registers for panic task from crash_notes. Just return them. + */ + regs = &ms->crash_task_regs[bt->tc->processor]; + epc = regs->regs[RISCV64_REGS_EPC]; + sp = regs->regs[RISCV64_REGS_SP]; + + /* + * Set stack frame ptr. + */ + bt->frameptr = regs->regs[RISCV64_REGS_FP]; + + if (nip) + *nip = epc; + if (ksp) + *ksp = sp; + + bt->machdep = regs; + + return TRUE; +} + +/* + * Do the work for riscv64_get_stack_frame() for non-active tasks. + * Get SP and PC values for idle tasks. + */ +static int +riscv64_get_frame(struct bt_info *bt, ulong *pcp, ulong *spp) +{ + if (!bt->tc || !(tt->flags & THREAD_INFO)) + return FALSE; + + if (!readmem(bt->task + OFFSET(task_struct_thread_context_pc), + KVADDR, pcp, sizeof(*pcp), + "thread_struct.ra", + RETURN_ON_ERROR)) + return FALSE; + + if (!readmem(bt->task + OFFSET(task_struct_thread_context_sp), + KVADDR, spp, sizeof(*spp), + "thread_struct.sp", + RETURN_ON_ERROR)) + return FALSE; + + if (!readmem(bt->task + OFFSET(task_struct_thread_context_fp), + KVADDR, &bt->frameptr, sizeof(bt->frameptr), + "thread_struct.fp", + RETURN_ON_ERROR)) + return FALSE; + + return TRUE; +} + static int riscv64_init_active_task_regs(void) { @@ -967,6 +1247,8 @@ riscv64_init(int when) machdep->uvtop = riscv64_uvtop; machdep->kvtop = riscv64_kvtop; machdep->cmd_mach = riscv64_cmd_mach; + machdep->get_stack_frame = riscv64_get_stack_frame; + machdep->back_trace = riscv64_back_trace_cmd; machdep->vmalloc_start = riscv64_vmalloc_start; machdep->processor_speed = riscv64_processor_speed; @@ -987,6 +1269,7 @@ riscv64_init(int when) case POST_GDB: machdep->section_size_bits = _SECTION_SIZE_BITS; machdep->max_physmem_bits = _MAX_PHYSMEM_BITS; + riscv64_stackframe_init(); riscv64_page_type_init(); if (!machdep->hz) From patchwork Sun Jul 17 04:29:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920426 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3AC25CCA483 for ; Sun, 17 Jul 2022 04:30:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=9GRGTcYe+VAVmTkwrtZNT8fwjUuD9UxUgNIL+EUgnec=; b=duKvxOHYjtylVu +KrkaphtfcvAvadB3ec36ubxYgXPxF4Hjqk9koJSOEC3J615Uggu2Mu2zjhCHLl9r7CWEU3nThBnL 03yfKF0w5QwFrcWIFd+zPuLdH8BSmUnv4ZE+09Y/PBdkwY1q0StNtmHcK0AqlvWUUd7hMn9qAo/0o Puh+UeEQs16DB1lF4oafQdcrH35w4/bOe8WoSb+f563R9DwU8XmweqHNiEOP9I6RiZH1ZU+xEjNj4 PTFNQci/L2kB2tSX7VFcZIiVmNva7Dp20omKGcPo/HDUgKIyLAVdhPy+CQrL4+YOn9kGWdzinzZNr ricgM2a6ZuQ4e2ppiuPg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvuh-0040D0-Ij; Sun, 17 Jul 2022 04:29:51 +0000 Received: from out30-45.freemail.mail.aliyun.com ([115.124.30.45]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvua-00406P-Ap for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:46 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R551e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046049;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWxqTo_1658032177; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWxqTo_1658032177) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:38 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 6/8] RISCV64: Add 'help -r' command support Date: Sun, 17 Jul 2022 12:29:27 +0800 Message-Id: <20220717042929.370022-7-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212944_566181_9F434DA6 X-CRM114-Status: UNSURE ( 6.36 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Add support form printing out the registers from the dump file. With the patch, we can get the regs, crash> help -r CPU 0: epc : ffffffff800078f8 ra : ffffffff8008862c sp : ff20000010333b90 gp : ffffffff810dde38 tp : ff6000000226c200 t0 : ffffffff8032be68 t1 : 0720072007200720 t2 : 666666666666663c s0 : ff20000010333cf0 s1 : 0000000000000000 a0 : ff20000010333b98 a1 : 0000000000000001 a2 : 0000000000000010 a3 : 0000000000000000 a4 : 0000000000000000 a5 : ff60000001c78000 a6 : 000000000000003c a7 : ffffffff8035c9a4 s2 : ffffffff810df0a8 s3 : ffffffff810df718 s4 : ff20000010333b98 s5 : 0000000000000000 s6 : 0000000000000007 s7 : ffffffff80c4a468 s8 : 00ffffffca281410 s9 : 0000000000000007 s10: 00aaaaaab5bb6700 s11: 0000000000000001 t3 : ff60000001218f00 t4 : ff60000001218f00 t5 : ff60000001218000 t6 : ff20000010333988 Signed-off-by: Xianting Tian --- riscv64.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/riscv64.c b/riscv64.c index c00ce90..475dc98 100644 --- a/riscv64.c +++ b/riscv64.c @@ -1309,6 +1309,44 @@ riscv64_init(int when) void riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp) { + const struct machine_specific *ms = machdep->machspec; + struct riscv64_register *regs; + + if (!ms->crash_task_regs) { + error(INFO, "registers not collected for cpu %d\n", cpu); + return; + } + + regs = &ms->crash_task_regs[cpu]; + if (!regs->regs[RISCV64_REGS_SP] && !regs->regs[RISCV64_REGS_EPC]) { + error(INFO, "registers not collected for cpu %d\n", cpu); + return; + } + + /* Print riscv64 32 regs */ + fprintf(ofp, + "epc : " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n" + " gp : " REG_FMT " tp : " REG_FMT " t0 : " REG_FMT "\n" + " t1 : " REG_FMT " t2 : " REG_FMT " s0 : " REG_FMT "\n" + " s1 : " REG_FMT " a0 : " REG_FMT " a1 : " REG_FMT "\n" + " a2 : " REG_FMT " a3 : " REG_FMT " a4 : " REG_FMT "\n" + " a5 : " REG_FMT " a6 : " REG_FMT " a7 : " REG_FMT "\n" + " s2 : " REG_FMT " s3 : " REG_FMT " s4 : " REG_FMT "\n" + " s5 : " REG_FMT " s6 : " REG_FMT " s7 : " REG_FMT "\n" + " s8 : " REG_FMT " s9 : " REG_FMT " s10: " REG_FMT "\n" + " s11: " REG_FMT " t3 : " REG_FMT " t4 : " REG_FMT "\n" + " t5 : " REG_FMT " t6 : " REG_FMT "\n", + regs->regs[0], regs->regs[1], regs->regs[2], + regs->regs[3], regs->regs[4], regs->regs[5], + regs->regs[6], regs->regs[7], regs->regs[8], + regs->regs[9], regs->regs[10], regs->regs[11], + regs->regs[12], regs->regs[13], regs->regs[14], + regs->regs[15], regs->regs[16], regs->regs[17], + regs->regs[18], regs->regs[19], regs->regs[20], + regs->regs[21], regs->regs[22], regs->regs[23], + regs->regs[24], regs->regs[25], regs->regs[26], + regs->regs[27], regs->regs[28], regs->regs[29], + regs->regs[30], regs->regs[31]); } #else /* !RISCV64 */ From patchwork Sun Jul 17 04:29:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920425 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A8EF2C433EF for ; Sun, 17 Jul 2022 04:29:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=uArLOWj5lUAXQtpn1MPWmtqZ03X3SpeSK2esVCSiG1o=; b=VH69D+Ki8/Uk4p z2tFMLgKVG7aSKD79JlOGaQeT+Y20wSMDkMpQGHHs/MMjCOpixJp6qIkz9xJfDT74VznQI4lP8xO0 +l7jViM742CvYitKBDamnNnaNdyl2oqwvYKHRpt10MDkVOcAaZLH9dht0k24GfF2kc43SbpJgc7Q5 NnOfEkT1PgaRxc5hrOtgtI/ZX9XARUaomsRoZYbParOIPR2/m4gjiV82MYI1tEeRI05WykcuwmHlH TilQoxX23+yYIlhoEh+xGCwpljVuupL0hkh7om2N+RU8Nck7Q07FiH15+GqVsossfk6mKhrxLOoFg z6UffILYkFTDibVJOp2g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvuf-0040Be-00; Sun, 17 Jul 2022 04:29:49 +0000 Received: from out30-130.freemail.mail.aliyun.com ([115.124.30.130]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvuZ-00407U-VM for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:46 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R391e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046060;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWxqTy_1658032179; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWxqTy_1658032179) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:39 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 7/8] RISCV64: Add 'mach' command support Date: Sun, 17 Jul 2022 12:29:28 +0800 Message-Id: <20220717042929.370022-8-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212944_201216_A5D4EE5E X-CRM114-Status: UNSURE ( 8.22 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org With the patch we can get some basic machine state information, crash> mach MACHINE TYPE: riscv64 MEMORY SIZE: 1 GB CPUS: 1 PROCESSOR SPEED: (unknown) HZ: 250 PAGE SIZE: 4096 KERNEL STACK SIZE: 16384 Signed-off-by: Xianting Tian --- riscv64.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/riscv64.c b/riscv64.c index 475dc98..cbf75cf 100644 --- a/riscv64.c +++ b/riscv64.c @@ -139,10 +139,53 @@ static int riscv64_get_struct_page_max_shift(struct machine_specific *ms) return (int)ceil(log2(ms->struct_page_size)); } +/* + * "mach" command output. + */ +static void +riscv64_display_machine_stats(void) +{ + struct new_utsname *uts; + char buf[BUFSIZE]; + ulong mhz; + + uts = &kt->utsname; + + fprintf(fp, " MACHINE TYPE: %s\n", uts->machine); + fprintf(fp, " MEMORY SIZE: %s\n", get_memory_size(buf)); + fprintf(fp, " CPUS: %d\n", get_cpus_to_display()); + fprintf(fp, " PROCESSOR SPEED: "); + if ((mhz = machdep->processor_speed())) + fprintf(fp, "%ld Mhz\n", mhz); + else + fprintf(fp, "(unknown)\n"); + fprintf(fp, " HZ: %d\n", machdep->hz); + fprintf(fp, " PAGE SIZE: %d\n", PAGESIZE()); + fprintf(fp, " KERNEL STACK SIZE: %ld\n", STACKSIZE()); +} + static void riscv64_cmd_mach(void) { - /* TODO: */ + int c; + + while ((c = getopt(argcnt, args, "cmo")) != EOF) { + switch (c) { + case 'c': + case 'm': + case 'o': + option_not_supported(c); + break; + default: + argerrs++; + break; + } + } + + if (argerrs) + cmd_usage(pc->curcmd, SYNOPSIS); + + riscv64_display_machine_stats(); } static int From patchwork Sun Jul 17 04:29:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianting Tian X-Patchwork-Id: 12920428 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BA652C43334 for ; Sun, 17 Jul 2022 04:30:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=oyXsHUMyZ4ne63CUqUIBlxmsnVNnSzgYPrT2FDhwjWU=; b=w8QLixee3RkPHw gv9OswWq/m6QT9BTTXrXSyMkMeMzoylgQHdtoLCcv1AlWawapkeBI84li0E5pBFA5RLiP5F7o8jEM MWVGEp4cvjKU6VuRAmWdfjU6KMOT2zjRVcm7qIB9rnDYrUu9aDDGPnEWAsZhB3mO5G9fZcS/fYcim dYxAYymE154imvWP1hi9PNLqdkgwo/jLS1WLvvnUj8yd7cAcr+O5DPP5IRYc0aikS/1Ftb2fQvWch kwm5t/Vv4a7PRuTRo+kafYB2JnTMT+Xj20IEKKfsR81VWCyOoFicm1phIzfcUghgqdGqX22JEB5az 9lJ+yudNF6nxHarF8TIQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvuk-0040Et-5u; Sun, 17 Jul 2022 04:29:54 +0000 Received: from out30-45.freemail.mail.aliyun.com ([115.124.30.45]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oCvub-004090-Po for linux-riscv@lists.infradead.org; Sun, 17 Jul 2022 04:29:48 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R211e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04400;MF=xianting.tian@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VJWzCBC_1658032180; Received: from localhost(mailfrom:xianting.tian@linux.alibaba.com fp:SMTPD_---0VJWzCBC_1658032180) by smtp.aliyun-inc.com; Sun, 17 Jul 2022 12:29:40 +0800 From: Xianting Tian To: crash-utility@redhat.com, mick@ics.forth.gr, heinrich.schuchardt@canonical.com, guoren@kernel.org, k-hagio-ab@nec.com Cc: linux-riscv@lists.infradead.org, hschauhan@nulltrace.org, huanyi.xj@alibaba-inc.com, Xianting Tian Subject: [PATCH 8/8] RISCV64: Add the implementation of symbol verify Date: Sun, 17 Jul 2022 12:29:29 +0800 Message-Id: <20220717042929.370022-9-xianting.tian@linux.alibaba.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> References: <20220717042929.370022-1-xianting.tian@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220716_212946_449004_FC6287BA X-CRM114-Status: UNSURE ( 7.50 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Verify the symbol to accept or reject a symbol from the kernel namelist. Signed-off-by: Xianting Tian --- riscv64.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/riscv64.c b/riscv64.c index cbf75cf..04064df 100644 --- a/riscv64.c +++ b/riscv64.c @@ -188,11 +188,20 @@ riscv64_cmd_mach(void) riscv64_display_machine_stats(); } +/* + * Accept or reject a symbol from the kernel namelist. + */ static int riscv64_verify_symbol(const char *name, ulong value, char type) { - /* TODO: */ - return TRUE; + if (CRASHDEBUG(8) && name && strlen(name)) + fprintf(fp, "%08lx %s\n", value, name); + + if (STREQ(name, "_text") || STREQ(name, "_stext")) + machdep->flags |= KSYMS_START; + + return (name && strlen(name) && (machdep->flags & KSYMS_START) && + !STRNEQ(name, "__func__.") && !STRNEQ(name, "__crc_")); } void