[RFC Patch 6/6] Crash: Recognise slim coredumps and process new elf-note sections
by K.Prasad
Crash: Recognise slim coredumps and process new elf-note sections
The Linux kernel will begin to support SlimDump for certain types of crashes
and the 'crash' tool needs to recognise them. For these types of coredumps, it
need not lookout for usual elf-structures and start gdb. Also process new
elf-note sections that contain additional information about the crash.
Signed-off-by: K.Prasad <prasad(a)linux.vnet.ibm.com>
---
diskdump.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netdump.c | 8 +++++
x86.h | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 183 insertions(+)
Index: crash-5.1.5.slim_kdump/x86.h
===================================================================
--- /dev/null
+++ crash-5.1.5.slim_kdump/x86.h
@@ -0,0 +1,91 @@
+/*
+ * x86.h - x86 Architecture specific definitions
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2011
+ *
+ * Author: K.Prasad <prasad(a)linux.vnet.ibm.com>
+ */
+
+typedef unsigned long long u64;
+typedef unsigned int u32;
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+#define __u64 u64
+#define __u32 u32
+#define __u16 u16
+#define __u8 u8
+
+/* Mask for finding the address mode in IA32_MCi_MISC[8:6] register */
+#define MCI_MISC_ADDR_MODE 0X1C0
+/* Number of bits to shift the IA32_MCi_MISC to read the address-mode bits */
+#define MISC_ADDR_MODE_POS 6
+
+/* Address Modes in IA32_MCi_MISC[8:6] */
+#define MCM_ADDR_SEGOFF 0 /* segment offset */
+#define MCM_ADDR_LINEAR 1 /* linear address */
+#define MCM_ADDR_PHYS 2 /* physical address */
+#define MCM_ADDR_MEM 3 /* memory address */
+#define MCM_ADDR_GENERIC 7 /* generic */
+
+#define MCI_STATUS_MISCV (1ULL<<59) /* misc error reg. valid */
+#define MCI_STATUS_ADDRV (1ULL<<58) /* addr reg. valid */
+
+#define PAGE_SHIFT 12
+
+static const char *mce_addr_mode[] =
+{
+ "Segment offset", /* MCM_ADDR_SEGOFF */
+ "Linear address", /* MCM_ADDR_LINEAR */
+ "Physical address", /* MCM_ADDR_PHYS */
+ "Memory address", /* MCM_ADDR_MEM */
+ "", /* reserved */
+ "", /* reserved */
+ "", /* reserved */
+ "Generic" /* MCM_ADDR_GENERIC */
+};
+
+/*
+ * kernel structure: Keep this in sync with the definition in
+ * arch/x86/include/asm/mce.h of linux source code.
+ *
+ * Fields are zero when not available
+ *
+ */
+struct mce {
+ __u64 status;
+ __u64 misc;
+ __u64 addr;
+ __u64 mcgstatus;
+ __u64 ip;
+ __u64 tsc; /* cpu time stamp counter */
+ __u64 time; /* wall time_t when error was detected */
+ __u8 cpuvendor; /* cpu vendor as encoded in system.h */
+ __u8 pad1;
+ __u16 pad2;
+ __u32 cpuid; /* CPUID 1 EAX */
+ __u8 cs; /* code segment */
+ __u8 bank; /* machine check bank */
+ __u8 cpu; /* cpu number; obsolete; use extcpu now */
+ __u8 finished; /* entry is valid */
+ __u32 extcpu; /* linux cpu number that detected the error */
+ __u32 socketid; /* CPU socket ID */
+ __u32 apicid; /* CPU initial apic ID */
+ __u64 mcgcap; /* MCGCAP MSR: machine check capabilities of CPU */
+ __u64 aux0;
+ __u64 aux1;
+};
Index: crash-5.1.5.slim_kdump/netdump.c
===================================================================
--- crash-5.1.5.slim_kdump.orig/netdump.c
+++ crash-5.1.5.slim_kdump/netdump.c
@@ -331,6 +331,10 @@ is_netdump(char *file, ulong source_quer
}
nd->notes32 = (Elf32_Phdr *)
&nd->elf_header[sizeof(Elf32_Ehdr)];
+ if (machdep->process_elf_notes)
+ machdep->process_elf_notes((char *)nd->elf32 +
+ nd->notes32->p_offset,
+ nd->notes32->p_filesz);
nd->load32 = (Elf32_Phdr *)
&nd->elf_header[sizeof(Elf32_Ehdr)+sizeof(Elf32_Phdr)];
if (DUMPFILE_FORMAT(nd->flags) == NETDUMP_ELF32)
@@ -360,6 +364,10 @@ is_netdump(char *file, ulong source_quer
}
nd->notes64 = (Elf64_Phdr *)
&nd->elf_header[sizeof(Elf64_Ehdr)];
+ if (machdep->process_elf_notes)
+ machdep->process_elf_notes((char *)nd->elf64 +
+ nd->notes64->p_offset,
+ nd->notes64->p_filesz);
nd->load64 = (Elf64_Phdr *)
&nd->elf_header[sizeof(Elf64_Ehdr)+sizeof(Elf64_Phdr)];
if (DUMPFILE_FORMAT(nd->flags) == NETDUMP_ELF64)
Index: crash-5.1.5.slim_kdump/diskdump.c
===================================================================
--- crash-5.1.5.slim_kdump.orig/diskdump.c
+++ crash-5.1.5.slim_kdump/diskdump.c
@@ -231,6 +231,27 @@ open_dump_file(char *file)
dd->dfd = fd;
return TRUE;
}
+#if defined(X86_64) || defined(X86)
+#include "x86.h"
+
+/*
+ * Check if the address reported by the CPU is in a format we can parse.
+ * It would be possible to add code for most other cases, but all would
+ * be somewhat complicated (e.g. segment offset would require an instruction
+ * parser). So only support physical addresses up to page granuality for now.
+ *
+ * Function derived from arch/x86/kernel/cpu/mcheck/mce.c in Linux source
+ *
+ */
+static int mce_usable_address(struct mce *m)
+{
+ if (!(m->status & MCI_STATUS_MISCV) || !(m->status & MCI_STATUS_ADDRV))
+ return 0;
+ if ((m->misc & 0x3f) > PAGE_SHIFT)
+ return 0;
+ return 1;
+}
+#endif /* defined(X86_64) || defined(X86) */
void
x86_process_elf_notes(void *note_ptr, unsigned long size_note)
@@ -239,10 +260,43 @@ x86_process_elf_notes(void *note_ptr, un
Elf64_Nhdr *note64 = NULL;
size_t tot, len = 0;
int num = 0;
+#if defined(X86_64) || defined(X86)
+ struct mce *mce;
+ ushort addr_mode;
+#endif /* defined(X86_64) || defined(X86) */
for (tot = 0; tot < size_note; tot += len) {
if (machine_type("X86_64")) {
note64 = note_ptr + tot;
+#ifdef X86_64
+ /*
+ * If vmcore is generated due to fatal Machine Check
+ * Exception, we only have a 'slim' crashdump. Don't
+ * analyse further, inform the user about it and exit.
+ */
+ if (note64->n_type == NT_MCE) {
+ fprintf(fp, "\"System crashed due to a hardware"
+ " memory error. No coredump"
+ " available.\"\n");
+
+ /* Do we have a copy of 'struct mce'? */
+ if (note64->n_descsz == 0)
+ goto exit;
+
+ mce = (struct mce *)((char *)note64 +
+ sizeof(Elf64_Nhdr) + note64->n_namesz);
+ if (!mce_usable_address(mce))
+ goto exit;
+
+ addr_mode = (mce->misc >> MISC_ADDR_MODE_POS) &
+ MCI_MISC_ADDR_MODE;
+ fprintf(fp, "Memory error occured at %llx "
+ "(address type: %s\n)", mce->addr,
+ mce_addr_mode[addr_mode]);
+exit:
+ clean_exit(0);
+ }
+#endif /* X86_64 */
if (note64->n_type == NT_PRSTATUS) {
dd->nt_prstatus_percpu[num] = note64;
@@ -255,6 +309,36 @@ x86_process_elf_notes(void *note_ptr, un
} else if (machine_type("X86")) {
note32 = note_ptr + tot;
+#ifdef X86
+ /*
+ * If vmcore is generated due to fatal Machine Check
+ * Exception, we only have a 'slim' crashdump. Don't
+ * analyse further, inform the user about it and exit.
+ */
+ if (note32->n_type == NT_MCE) {
+ fprintf(fp, "\"System crashed due to a hardware"
+ " memory error. No coredump"
+ " available.\"\n");
+
+ /* Do we have a copy of 'struct mce'? */
+ if (note32->n_descsz == 0)
+ goto exit;
+
+ mce = (struct mce *)((char *)note32 +
+ sizeof(Elf32_Nhdr) + note32->n_namesz);
+ if (!mce_usable_address(mce))
+ goto exit;
+
+ addr_mode = (mce->misc >> MISC_ADDR_MODE_POS) &
+ MCI_MISC_ADDR_MODE;
+ fprintf(fp, "Memory error occured at %llx "
+ "(address type: %s\n)", mce->addr,
+ mce_addr_mode[addr_mode]);
+exit:
+ clean_exit(0);
+ }
+#endif /* X86 */
+
if (note32->n_type == NT_PRSTATUS) {
dd->nt_prstatus_percpu[num] = note32;
num++;
13 years, 6 months
Re: [Crash-utility] ARM support for CONFIG_SPARSEMEM:(was Re:DDimage)
by takuo.koguchi.sw@hitachi.com
Dave, Mika,
memory.h I am using is probably the same as this,
https://www.codeaurora.org/gitweb/quic/la/?p=kernel/msm.git;a=blob;f=arch...
19 /* physical offset of RAM */
20 #define PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) <-- 0x00200000
21
22 #define MAX_PHYSMEM_BITS 32
23 #define SECTION_SIZE_BITS 28
24
25 /* Certain configurations of MSM7x30 have multiple memory banks.
26 * One or more of these banks can contain holes in the memory map as well.
27 * These macros define appropriate conversion routines between the physical
28 * and virtual address domains for supporting these configurations using
29 * SPARSEMEM and a 3G/1G VM split.
30 */
31
32 #if defined(CONFIG_ARCH_MSM7X30)
33
34 #define EBI0_PHYS_OFFSET PHYS_OFFSET
35 #define EBI0_PAGE_OFFSET PAGE_OFFSET
36 #define EBI0_SIZE 0x10000000
37
38 #define EBI1_PHYS_OFFSET 0x40000000
39 #define EBI1_PAGE_OFFSET (EBI0_PAGE_OFFSET + EBI0_SIZE)
40
41 #if (defined(CONFIG_SPARSEMEM) && defined(CONFIG_VMSPLIT_3G))
42
43 #define __phys_to_virt(phys) \
44 ((phys) >= EBI1_PHYS_OFFSET ? \
45 (phys) - EBI1_PHYS_OFFSET + EBI1_PAGE_OFFSET : \
46 (phys) - EBI0_PHYS_OFFSET + EBI0_PAGE_OFFSET)
47
48 #define __virt_to_phys(virt) \
49 ((virt) >= EBI1_PAGE_OFFSET ? \
50 (virt) - EBI1_PAGE_OFFSET + EBI1_PHYS_OFFSET : \
51 (virt) - EBI0_PAGE_OFFSET + EBI0_PHYS_OFFSET)
52
53 #endif
54
55 #endif
So my previous description of actual memory mapping was not correct.
The correct description is,
Virtual 0xc0000000-0xcfdfffff -> Physical 0x00200000-0x0fffffff
and
Virtual 0xd0000000-0xdfffffff -> Physical 0x40000000-0x4fffffff
Tomorrow I will check if vmcore with the following header is recognized by crash.
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
NOTE 0x000094 0x00000000 0x00000000 0x00000 0x00000 0
LOAD 0x000094 0xc0000000 0x00200000 0x0fe00000 0x0fe00000 RWE
LOAD 0x0fe00094 0xc0000000 0x40000000 0x10000000 0x10000000 RWE
And I guess VTOP/PTOV needs modification in accordance with __phys_to_virt and __virt_to_phys.
For your information,
The vmcore file with the following header is recognized by crash and many commands works fine,
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
NOTE 0x000074 0x00000000 0x00000000 0x00000 0x00000 0
LOAD 0x000074 0xc0000000 0x00000000 0x20000000 0x20000000 RWE
if the patches for unwind_arm.c, arm.c and defs.h posted in this ML thread applied and readmem error_handle for FILL_PTBL is change to RETURN_ON_ERROR.
Without the last modification above crash exits when readmem fails at FILL_PTBL before reaching the first prompt.
Best Regards,
Takuo Koguchi
>
>
>----- Original Message -----
>> On Thu, May 26, 2011 at 11:53 AM, <takuo.koguchi.sw(a)hitachi.com> wrote:
>
>> > It might come form my vmcore file's incorrectness.
>> > Currently my vmcore contains the following,
>> > Program Headers:
>> > Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
>> > NOTE 0x000074 0x00000000 0x00000000 0x00000 0x00000 0
>> > LOAD 0x000074 0xc0000000 0x00000000 0x20000000 0x20000000 RWE 0
>> >
>> > But actual mapping is,
>> > Virtual 0xc0000000-0xcfffffff corresponds Physical 0x00000000-0x0fffffff
>> > and
>> > Virtual 0xd0000000-0xdfffffff corresponds Physical 0x40000000-0x4fffffff
>> >
>> > Then I tried to prepend the following header instead,
>> > Program Headers:
>> > Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
>> > NOTE 0x000094 0x00000000 0x00000000 0x00000 0x00000 0
>> > LOAD 0x000094 0xc0000000 0x00000000 0x10000000 0x10000000 RWE 0
>> > LOAD 0x10000094 0xd0000000 0x40000000 0x10000000 0x10000000 RWE 0
>> >
>> > This time crash does not recognize the vmcore file.
>> >
>> > Perhaps I have to change VTOP/PTOV macros accordingly?
>>
>> It should be enough if you have machdep->machspec->phys_base set to
>> correct value, which is 0 in your case. You can see this by running
>> 'crash -d1 ...'. Also if possible, can you post the full output here
>> so that we can analyze it further.
>
>Hey guys,
>
>Pardon my confusion/interruption, but the "actual mapping" above would
>be unique for unity-mapping. The 0xc0000000-0xcfffffff segment is
>"traditionally" unity-mapped, where VTOP() would strip off the kvbase,
>and then apply a physical base if appropriate. But then the second
>0xd0000000-0xdfffffff segment could not use the same logic.
>
>Looking at the upstream ARM sources, __pa() is:
>
> #define __pa(x) __virt_to_phys((unsigned long)(x))
>
>where __virt_to_phys() does something different if CONFIG_ARM_PATCH_PHYS_VIRT
>is configured:
>
> #ifdef CONFIG_ARM_PATCH_PHYS_VIRT
>
> /*
> * Constants used to force the right instruction encodings and shifts
> * so that all we need to do is modify the 8-bit constant field.
> */
> #define __PV_BITS_31_24 0x81000000
> #define __PV_BITS_23_16 0x00810000
>
> extern unsigned long __pv_phys_offset;
> #define PHYS_OFFSET __pv_phys_offset
>
> #define __pv_stub(from,to,instr,type) \
> __asm__("@ __pv_stub\n" \
> "1: " instr " %0, %1, %2\n" \
> " .pushsection .pv_table,\"a\"\n" \
> " .long 1b\n" \
> " .popsection\n" \
> : "=r" (to) \
> : "r" (from), "I" (type))
>
> static inline unsigned long __virt_to_phys(unsigned long x)
> {
> unsigned long t;
> __pv_stub(x, t, "add", __PV_BITS_31_24);
> #ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
> __pv_stub(t, t, "add", __PV_BITS_23_16);
> #endif
> return t;
> }
>
> static inline unsigned long __phys_to_virt(unsigned long x)
> {
> unsigned long t;
> __pv_stub(x, t, "sub", __PV_BITS_31_24);
> #ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
> __pv_stub(t, t, "sub", __PV_BITS_23_16);
> #endif
> return t;
> }
> #else
> #define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
> #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
> #endif
>
>Is that what's happening here? I don't understand the __pv_stub()
>stuff, but if the virtual-to-physical unity-mapping is as Takuo
>described, then there would have to be a change to the ARM VTOP/PTOV
>macros.
>
>Anyway, as to why crash doesn't recognize the vmcore with the second
>PT_LOAD segment added, you'll have to debug why is_netdump() is
>rejecting it.
>
>Dave
>
>--
>Crash-utility mailing list
>Crash-utility(a)redhat.com
>https://www.redhat.com/mailman/listinfo/crash-utility
>
13 years, 6 months
Re: [Crash-utility] ARM support for CONFIG_SPARSEMEM:(wasRe:DDimage)
by takuo.koguchi.sw@hitachi.com
>> LOAD 0x000094 0xc0000000 0x00200000 0x0fe00000 0x0fe00000 RWE
>> LOAD 0x0fe00094 0xc0000000 0x40000000 0x10000000 0x10000000 RWE
>
>Shouldn't the second PT_LOAD segment have a p_vaddr of 0xc0000000?
Sorry. It's my typo as this was not real output of readelf. The second start from 0xd0000000.
>> LOAD 0x0fe00094 0xd0000000 0x40000000 0x10000000 0x10000000 RWE
Takuo
>
>
>----- Original Message -----
>> Dave, Mika,
>> memory.h I am using is probably the same as this,
>> https://www.codeaurora.org/gitweb/quic/la/?p=kernel/msm.git;a=blob;f=arch...
>>
>> 19 /* physical offset of RAM */
>> 20 #define PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) <-- 0x00200000
>> 21
>> 22 #define MAX_PHYSMEM_BITS 32
>> 23 #define SECTION_SIZE_BITS 28
>> 24
>> 25 /* Certain configurations of MSM7x30 have multiple memory banks.
>> 26 * One or more of these banks can contain holes in the memory map as well.
>> 27 * These macros define appropriate conversion routines between the physical
>> 28 * and virtual address domains for supporting these configurations using
>> 29 * SPARSEMEM and a 3G/1G VM split.
>> 30 */
>> 31
>> 32 #if defined(CONFIG_ARCH_MSM7X30)
>> 33
>> 34 #define EBI0_PHYS_OFFSET PHYS_OFFSET
>> 35 #define EBI0_PAGE_OFFSET PAGE_OFFSET
>> 36 #define EBI0_SIZE 0x10000000
>> 37
>> 38 #define EBI1_PHYS_OFFSET 0x40000000
>> 39 #define EBI1_PAGE_OFFSET (EBI0_PAGE_OFFSET + EBI0_SIZE)
>> 40
>> 41 #if (defined(CONFIG_SPARSEMEM) && defined(CONFIG_VMSPLIT_3G))
>> 42
>> 43 #define __phys_to_virt(phys) \
>> 44 ((phys) >= EBI1_PHYS_OFFSET ? \
>> 45 (phys) - EBI1_PHYS_OFFSET + EBI1_PAGE_OFFSET : \
>> 46 (phys) - EBI0_PHYS_OFFSET + EBI0_PAGE_OFFSET)
>> 47
>> 48 #define __virt_to_phys(virt) \
>> 49 ((virt) >= EBI1_PAGE_OFFSET ? \
>> 50 (virt) - EBI1_PAGE_OFFSET + EBI1_PHYS_OFFSET : \
>> 51 (virt) - EBI0_PAGE_OFFSET + EBI0_PHYS_OFFSET)
>> 52
>> 53 #endif
>> 54
>> 55 #endif
>>
>>
>> So my previous description of actual memory mapping was not correct.
>> The correct description is,
>> Virtual 0xc0000000-0xcfdfffff -> Physical 0x00200000-0x0fffffff
>> and
>> Virtual 0xd0000000-0xdfffffff -> Physical 0x40000000-0x4fffffff
>> Tomorrow I will check if vmcore with the following header is
>> recognized by crash.
>> Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
>> NOTE 0x000094 0x00000000 0x00000000 0x00000 0x00000 0
>> LOAD 0x000094 0xc0000000 0x00200000 0x0fe00000 0x0fe00000 RWE
>> LOAD 0x0fe00094 0xc0000000 0x40000000 0x10000000 0x10000000 RWE
>
>Shouldn't the second PT_LOAD segment have a p_vaddr of 0xc0000000?
>
>Although, in the case of ARM, I believe that the p_vaddr field
>is not used by the crash utility, as it is only interested in the
>p_paddr and p_memsz/p_filesz fields. But I presume you meant
>0xd0000000 for the second one.
>
>>
>> And I guess VTOP/PTOV needs modification in accordance with
>> __phys_to_virt and __virt_to_phys.
>
>Right...
>
>Ultimately it will be advisable to extract the ARM VTOP() and PTOV()
>macros into machine-dependent functions, i.e., similar to the X86_64
>and IA64 architectures. And in those functions, intelligence will
>have to be applied to determine how to handle the various ARM types.
>
>>
>> For your information,
>> The vmcore file with the following header is recognized by crash and
>> many commands works fine,
>> Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
>> NOTE 0x000074 0x00000000 0x00000000 0x00000 0x00000 0
>> LOAD 0x000074 0xc0000000 0x00000000 0x20000000 0x20000000 RWE
>> if the patches for unwind_arm.c, arm.c and defs.h posted in this ML
>> thread applied and readmem error_handle for FILL_PTBL is change to
>> RETURN_ON_ERROR.
>> Without the last modification above crash exits when readmem fails at
>> FILL_PTBL before reaching the first prompt.
>
>But I'm thinking that if the VTOP/PTOV issue is resolved, then you won't
>see that readmem() error in FILL_PTBL(), because the address that was
>failing was generated by PTOV():
>
> /*
> * pte_offset_map(pmd, vaddr)
> */
> page_table = (ulong *)PTOV(pmd_page_addr(pmd_pte)) + PTE_OFFSET(vaddr);
>
> FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE());
>
>Dave
>
>
>--
>Crash-utility mailing list
>Crash-utility(a)redhat.com
>https://www.redhat.com/mailman/listinfo/crash-utility
>
13 years, 6 months
Re: [Crash-utility] ARM support for CONFIG_SPARSEMEM: (was Re: DDimage)
by takuo.koguchi.sw@hitachi.com
>... But I got another error later, which I will report later.
Now I set _SECTION_SIZE_BITS 22 and see what happens next.
I found that readmem for "page table" failed while excuting init_unwind_tables() in unwind_arm.c and crash exited.
crash: invalid kernel virtual address: f67f000 type: "page table"
Instead of investigating this issue, I continue by skipping init_unwind_tables for a while.
Because crash gives me a prompt now and I am quite interested in whether it gives me some useful information or not.
Takuo
>Thanks Dave, MW, Jan,
>
>I tried the patch which set machdep->section_size_bits and machdep->max_physmem_bits.
>
>When _SECTION_SIZE_BITS is 28, I got the following error, and failed in sparse_mem_init()
>PAGESIZE=4096
>mem_section_size = 0
>NR_SECTION_ROOTS = 0
>NR_MEM_SECTIONS = 16
>SECTIONS_PER_ROOT = 512
>SECTION_ROOT_MASK = 0x1ff
>PAGES_PER_SECTION = 65536
>crash: invalid size request: 0 type: "memory section root table"
>
>
>And when _SECTION_SIZE_BITS is 22, I got the following and sparse_mem_init() returns with out error.
>
>PAGESIZE=4096
>mem_section_size = 8
>NR_SECTION_ROOTS = 2
>NR_MEM_SECTIONS = 1024
>SECTIONS_PER_ROOT = 512
>SECTION_ROOT_MASK = 0x1ff
>PAGES_PER_SECTION = 1024
>
>... But I got another error later, which I will report later.
>
>
>In memory.c:sparse_mem_init(),
> vt->mem_sec is malloced as mem_section_size bytes block and readmem is called.
>I suppose the mem_section_size should not be zero. I do not know _SECTION_SIZE_BITS 22 is correct or not,
>but the following caliculation of NR_SECTION_ROOTS() looks suspicious to me.
>#define NR_SECTION_ROOTS() (NR_MEM_SECTIONS() / SECTIONS_PER_ROOT())
>
>Something like (((NR_MEM_SECTIONS() - 1)/ SECTIONS_PER_ROOT()) + 1) ?
>
>
>Best Regard,
>
>Takuo
>
>
>
>>[ dropped my Nokia address from the CC list, since I'm not working for Nokia
>> anymore ]
>>
>>On Tue, May 24, 2011 at 09:58:48AM -0400, Dave Anderson wrote:
>>>
>>> BTW, I await any patches from the ARM folks to set these bits
>>> appropriately. Currently there is this for ARM in defs.h:
>>>
>>> #ifdef ARM
>>> ... [ cut ] ...
>>>
>>> #define _SECTION_SIZE_BITS 28
>>> #define _MAX_PHYSMEM_BITS 32
>>>
>>> #endif /* ARM */
>>>
>>> Yet you state above that you're using 22 for _SECTION_SIZE_BITS.
>>
>>This varies between different SoCs and it is not used by others. Since it is
>>not stored in a crashdump IIRC, we really cannot set that value dynamically.
>>
>>So I see two options:
>>
>> 1) leave it as is and make crash to complain when it detects such
>> situation or
>> 2) guess the values and try to do the right thing (TM)
>>
>>My preference goes with 2) provided that we can get it working on majority of
>>the ARM SoCs.
>>
>>We could try to stick with _SECTION_SIZE_BITS=28, as it seems to be largest
>>currently used section size amongst different ARM SoCs, and hope that it works
>>with others where this is smaller.
>>
>>Jan, Takuo: maybe you could try whether following patch works? I don't have
>>any hardware which use SPARSEMEM so I'm unable to test it.
>>
>>Regards,
>>MW
>>
>>diff --git a/arm.c b/arm.c
>>index 0347166..9d4afcc 100644
>>--- a/arm.c
>>+++ b/arm.c
>>@@ -260,6 +260,9 @@ arm_init(int when)
>> STRUCT_EXISTS("pteval_t"))
>> machdep->flags |= PGTABLE_V2;
>>
>>+ machdep->section_size_bits = _SECTION_SIZE_BITS;
>>+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
>>+
>> if (symbol_exists("irq_desc"))
>> ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
>> "irq_desc", NULL, 0);
>>
>>--
>>Crash-utility mailing list
>>Crash-utility(a)redhat.com
>>https://www.redhat.com/mailman/listinfo/crash-utility
>>
>
13 years, 6 months
Re: [Crash-utility] ARM support for CONFIG_SPARSEMEM: (was Re: DDimage)
by takuo.koguchi.sw@hitachi.com
Hi Dave,
>but the following caliculation of NR_SECTION_ROOTS() looks suspicious to me.
>#define NR_SECTION_ROOTS() (NR_MEM_SECTIONS() / SECTIONS_PER_ROOT())
>
>Something like (((NR_MEM_SECTIONS() - 1)/ SECTIONS_PER_ROOT()) + 1) ?
Now I am quite sure the definition of NR_SECTION_ROOTS() is wrong.
In the upstream kernel, I found the following
include/linux/mmzone.h
...
994 #define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT)
995 #define NR_SECTION_ROOTS DIV_ROUND_UP(NR_MEM_SECTIONS, SECTIONS_PER_ROOT)
996 #define SECTION_ROOT_MASK (SECTIONS_PER_ROOT - 1)
and
include/kernel.h DIV_ROUND_UP is defined as follows,
58 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
I hope you can take care of this.
By the way, I think _SECTION_SIZE_BITS issue is a separate issue.
Best Regard,
Takuo
>Thanks Dave, MW, Jan,
>
>I tried the patch which set machdep->section_size_bits and machdep->max_physmem_bits.
>
>When _SECTION_SIZE_BITS is 28, I got the following error, and failed in sparse_mem_init()
>PAGESIZE=4096
>mem_section_size = 0
>NR_SECTION_ROOTS = 0
>NR_MEM_SECTIONS = 16
>SECTIONS_PER_ROOT = 512
>SECTION_ROOT_MASK = 0x1ff
>PAGES_PER_SECTION = 65536
>crash: invalid size request: 0 type: "memory section root table"
>
>
>And when _SECTION_SIZE_BITS is 22, I got the following and sparse_mem_init() returns with out error.
>
>PAGESIZE=4096
>mem_section_size = 8
>NR_SECTION_ROOTS = 2
>NR_MEM_SECTIONS = 1024
>SECTIONS_PER_ROOT = 512
>SECTION_ROOT_MASK = 0x1ff
>PAGES_PER_SECTION = 1024
>
>... But I got another error later, which I will report later.
>
>
>In memory.c:sparse_mem_init(),
> vt->mem_sec is malloced as mem_section_size bytes block and readmem is called.
>I suppose the mem_section_size should not be zero. I do not know _SECTION_SIZE_BITS 22 is correct or not,
>but the following caliculation of NR_SECTION_ROOTS() looks suspicious to me.
>#define NR_SECTION_ROOTS() (NR_MEM_SECTIONS() / SECTIONS_PER_ROOT())
>
>Something like (((NR_MEM_SECTIONS() - 1)/ SECTIONS_PER_ROOT()) + 1) ?
>
>
>Best Regard,
>
>Takuo
>
>
>
>>[ dropped my Nokia address from the CC list, since I'm not working for Nokia
>> anymore ]
>>
>>On Tue, May 24, 2011 at 09:58:48AM -0400, Dave Anderson wrote:
>>>
>>> BTW, I await any patches from the ARM folks to set these bits
>>> appropriately. Currently there is this for ARM in defs.h:
>>>
>>> #ifdef ARM
>>> ... [ cut ] ...
>>>
>>> #define _SECTION_SIZE_BITS 28
>>> #define _MAX_PHYSMEM_BITS 32
>>>
>>> #endif /* ARM */
>>>
>>> Yet you state above that you're using 22 for _SECTION_SIZE_BITS.
>>
>>This varies between different SoCs and it is not used by others. Since it is
>>not stored in a crashdump IIRC, we really cannot set that value dynamically.
>>
>>So I see two options:
>>
>> 1) leave it as is and make crash to complain when it detects such
>> situation or
>> 2) guess the values and try to do the right thing (TM)
>>
>>My preference goes with 2) provided that we can get it working on majority of
>>the ARM SoCs.
>>
>>We could try to stick with _SECTION_SIZE_BITS=28, as it seems to be largest
>>currently used section size amongst different ARM SoCs, and hope that it works
>>with others where this is smaller.
>>
>>Jan, Takuo: maybe you could try whether following patch works? I don't have
>>any hardware which use SPARSEMEM so I'm unable to test it.
>>
>>Regards,
>>MW
>>
>>diff --git a/arm.c b/arm.c
>>index 0347166..9d4afcc 100644
>>--- a/arm.c
>>+++ b/arm.c
>>@@ -260,6 +260,9 @@ arm_init(int when)
>> STRUCT_EXISTS("pteval_t"))
>> machdep->flags |= PGTABLE_V2;
>>
>>+ machdep->section_size_bits = _SECTION_SIZE_BITS;
>>+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
>>+
>> if (symbol_exists("irq_desc"))
>> ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
>> "irq_desc", NULL, 0);
>>
>>--
>>Crash-utility mailing list
>>Crash-utility(a)redhat.com
>>https://www.redhat.com/mailman/listinfo/crash-utility
>>
>
13 years, 6 months
Re: [Crash-utility] DD image
by takuo.koguchi.sw@hitachi.com
Hello Dave,
>On the other hand, it would also be fairly easy to create
>a small utility function that simply pre-pends an ELF header
>to the dumpfile -- one which has a single PT_LOAD section
>that describes the physical memory as one large chunk.
>For this simple format, you could take the snap.c extension
>module's generate_elf_header() function, have it create a
>an ELF header with just one PT_LOAD segment, and fold it
>into a standalone program. It has support for x86, x86_64,
>ppc64 and ia64.
I have chosen this way for my arm target. Though snap.c told me how to create an elf header,
it is too difficult for me to modify it to support ELF32 of ARM in addition to existing ELF64 support. So
I just prepend a fixed ELF header which generate_elf_header would create.
(1) I tried "an ELF header with just one PT_LOAD segment" vmcore file as you suggested and got the following,
---------------------
$ ./crash vmlinux vmcore
crash 5.1.5
Copyright (C) 2002-2011 Red Hat, Inc.
...
This program has absolutely no warranty. Enter "help warranty" for details.
crash: vmcore: not a supported file format
Usage:
crash [OPTION]... NAMELIST MEMORY-IMAGE (dumpfile form)
crash [OPTION]... [NAMELIST] (live system form)
Enter "crash -h" for details.
----------------------
The following is information of the file got by readelf command. Is there something wrong?
$ arm-eabi-readelf -a vmcore
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: CORE (Core file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 0 (bytes)
Number of section headers: 0
Section header string table index: 0 <corrupt: out of range>
There are no sections in this file.
There are no sections in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000054 0xc0000000 0x00000000 0x20000000 0x20000000 RWE 0
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
No version information found in this file.
------------------------------------------------
(2) Next I tried "an ELF header with an empty PT_NOTE segment and just one PT_LOAD segment"
This time readelf command shows
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
NOTE 0x000074 0x00000000 0x00000000 0x00000 0x00000 0
LOAD 0x000074 0xc0000000 0x00000000 0x20000000 0x20000000 RWE 0
And I could use this file as a core file for "arm-eabi-gdb vmlinux vmcore"
For example "show init_task" works normally.
Is this an expected behavior?
(3) Above vmcore file works for gdb, but it does not work for crash(5.1.5).
I got the following message and the crash command just exited.
crash: CONFIG_SPARSEMEM kernels not supported for this architecture
Would you please tell me how to support CONFIG_SPARSEMEM?
I tried to add "machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;" in arm.c and made some progress.
But still I cannot reach the crash prompt.
I will appreciate any suggestion.
Best Regard,
Takuo Koguchi
>
>----- Original Message -----
>> Hi Dave,
>>
>> Thanks for your feedback , actually what I meant by minimizing the
>> footprint that to not preform any action which requires instillation
>> for any tool in order to image the memory. that to preserve the
>> volatile data and not to overwrite information in memory such as
>> terminated and cached processes. snap.so is good solution for live
>> system but it first requires the instillation of crash in the
>> investigated system which is not forensic sound. dd is small tool that
>> comes with the most modern Linux destructions and forensic toolkits as
>> it does not require instillation. if crash supports dd image then
>> crach utility will be not only debugger but also forensic tool.
>>
>> thanks,
>> Amer
>
>OK, so you *are* suggesting that the dumpfile would be created
>something like this:
>
> $ dd if=/dev/mem of=memory-image bs=<page-size>
>
>What architecture is this for?
>
>And can you confirm that the /dev/mem read_mem() function will
>proceed without any of its error scenarios occurring before the
>last page of physical memory is read?
>
>There are these possible failures:
>
> if (!valid_phys_addr_range(p, count))
> return -EFAULT;
>
> if (!range_is_allowed(p >> PAGE_SHIFT, count))
> return -EPERM;
>
> ptr = xlate_dev_mem_ptr(p);
> if (!ptr)
> return -EFAULT;
>
> remaining = copy_to_user(buf, ptr, sz);
> unxlate_dev_mem_ptr(p, ptr);
> if (remaining)
> return -EFAULT;
>
>First, the valid_phys_addr_range() restricts /dev/mem to
>high_memory, or 896MB maximum on 32-bit architectures.
>The crash utility will still initialize, but several
>commands will fail if memory over that 896MB threshold
>are required.
>
>But more importantly, the xlate_dev_mem_ptr() call is the one
>that could possibly trip you up if the architecture is x86 or x86_64.
>I don't have a machine on-hand to test that because RHEL/Fedora
>kernels apply CONFIG_STRICT_DEVMEM, so /dev/mem is useless for
>that purpose.
>
>In any case, if the output file is page-for-page copy
>of physical memory, then creating support for it would
>be fairly easy. But I really don't want to expend any effort
>creating support for such a file format given the potential
>problems with the use of /dev/mem.
>
>On the other hand, it would also be fairly easy to create
>a small utility function that simply pre-pends an ELF header
>to the dumpfile -- one which has a single PT_LOAD section
>that describes the physical memory as one large chunk.
>For this simple format, you could take the snap.c extension
>module's generate_elf_header() function, have it create a
>an ELF header with just one PT_LOAD segment, and fold it
>into a standalone program. It has support for x86, x86_64,
>ppc64 and ia64.
>
>Dave
>
>--
>Crash-utility mailing list
>Crash-utility(a)redhat.com
>https://www.redhat.com/mailman/listinfo/crash-utility
>
13 years, 6 months
[PATCH] Add support for byte swapping in rd
by Max Matveev
Dave,
I often do analysis on network-releated crashes and often find myself
doing mental byte swapping to convert from host to network and back -
I think crash can do it much better then me, so I wrote a patch to
teach rd how to do this.
I'm only doing byte swapping on 16 and 32 bit types because
64 bit integers don't have a "standard" network representation.
max
13 years, 6 months
[ANNOUNCE] crash version 5.1.5 is available
by Dave Anderson
Download from: http://people.redhat.com/anderson
Changelog:
- Fix to allow a vmlinux.bz2 file to be accepted when it is part of
a relative or absolute pathname. Without the patch, the file is
rejected with the message "crash: <path-to>/vmlinux.bz2: not a
supported file format", although it is still possible to use it with
the "-f" flag.
(d.hatayama(a)jp.fujitsu.com)
- Fix for the usage of a vmlinux.gz or vmlinux.bz2 file if the
relevant gunzip or bunzip2 file is not located in /usr/bin.
Without the patch on an Ubunutu system, the uncompression fails
because those binaries are only located in the /bin directory.
Also fixed the uncompression error message to differentiate
between gunzip and bunzip2.
(anderson(a)redhat.com)
- Created a new exist_regs_in_elf_notes() function for extension
modules to pre-determine whether an ELF note containing registers
exists for a specified task. The function is also used by the
currently-existing get_regs_from_elf_notes() function to clean up
redundant code in the various get_<arch>_regs_from_elf_notes()
functions that it calls.
(d.hatayama(a)jp.fujitsu.com)
- Exported the formerly static x86_64_exception_frame() function
to extension modules, and created a new EFRAME_INIT flags argument
that directs the function to fill in the x86_64 pt_regs offset table
and return any errors encountered in doing so.
(anderson(a)redhat.com)
- Created and exported a new get_kvm_register_set() interface for
extension modules to get a copy of the per-cpu registers stored in
the kvmdump header.
(anderson(a)redhat.com)
- Fix for the handling of x86_64 compressed kdump dumpfiles where
the crashing system contained more than 454 cpus. Without the
patch, the crash session fails during initialization with the error
message "crash: compressed kdump: invalid nr_cpus value: <cpus>"
followed by "crash: vmcore: not a supported file format".
(tindoh(a)redhat.com, tachibana(a)mxm.nes.nec.co.jp)
- Fix for the "uvtop" and "vm -p" commands when run on tasks that
have performed an mprotect(PROT_NONE) on a user-space page. Because
the PAGE_PRESENT bit is not set in that case, the page was presumed
to be swapped out. Without the patch the "vtop <address>" command
fails with the error message "vtop: cannot determine swap location",
and "vm -p" indicates "SWAP: (unknown swap location)" when iterating
over the page.
(d.hatayama(a)jp.fujitsu.com)
- Fix for the use of the "-g vmlinux" command line option by non-root
users if the /dev/crash module has been preloaded. Without the
patch, after the vmlinux file's debugging information has been
shown, the error messages "ERROR: Removing 'crash': Operation not
permitted" and "NOTE: cleanup_memory_driver failed" are displayed.
(anderson(a)redhat.com)
- Fix for the s390x "bt" command to handle a program check interrupt
while operating on the process stack. Without the patch, the
backtrace stops prematurely upon reaching the pgm_check_handler()
interrupt handler.
(holzheu(a)linux.vnet.ibm.com)
- Long overdue rewrite of the crash.8 man page and the associated
"crash -h" built-in usage display. The crash.8 man page clarifies
the required invocation options, adds all of the rarely-used
command line options that have proliferated over the years, and
updates the ENVIRONMENT variables section. The "crash -h" output
closely mimics the relevant parts of the crash.8 man page.
(anderson(a)redhat.com)
- Fix for the embedded gdb module to determine member offsets of the
pglist_data structure when the kernel was compiled with gcc 4.6.0.
Without the patch, the system MEMORY size shown by the initial system
data and by the "sys" command is nonsensical, the "kmem -n" command
shows faulty memory node data, and if the kernel is configure with
CONFIG_SLUB, "kmem -[sS]" will fail with numerous "kmem: page_to_nid:
cannot determine node for pages: <page-address>" errors. There
may be other ramifications given that the pglist_data structure is
crucial to the functionality of the crash utility.
(tromey(a)redhat.com)
- Implemented the capability of using the NT_PRSTATUS ELF note data
that is saved in version 4 compressed kdump headers to determine the
starting stack and instruction pointer hooks for x86 and x86_64
backtraces when they cannot be determined in the traditional manners.
(wang.chao(a)cn.fujitsu.com, wency(a)cn.fujitsu.com)
- Added a new "--osrelease <dumpfile>" command line option that
displays the OSRELEASE vmcoreinfo string from a kdump dumpfile.
(anderson(a)redhat.com)
- Fix to recognize the per-cpu symbol name change from "cpu_info"
to "ia64_cpu_info" in 2.6.33 and later ia64 kernels. Without the
patch, the message "WARNING: cannot find cpuinfo_ia64 location"
would appear during invocation, and the "mach -c" command would
fail in a similar manner, indicating "mach: cannot find cpuinfo_ia64
location".
(anderson(a)redhat.com)
- Fix for "kmem -[sS]" command on 2.6.39 kernels where the original
slab structure members have been moved into an anonymous union.
Without the patch, either command fails immediately with the error
message "kmem: invalid structure member offset: slab_list".
(anderson(a)redhat.com)
13 years, 6 months
Crash kmem error
by Qiannan Cui
Hi,
When I used crash based off of a mainline kernel to run kmem, it failed. For your information, the detailed description of the problem is as follows.
Version-Release number of selected component:
# uname -a
Linux hp-rx8640-02.rhts.eng.bos.redhat.com 2.6.39-rc6+ #2 SMP Mon May 9 23:05:14 EDT 2011 ia64 ia64 ia64 GNU/Linux
Steps to Reproduce:
1、update the old kernel to the mainline kernel 2.6.39-rc6+
2、install crash
3、# crash <where the mainline kernel tree is>/vmlinux
4、crash> kmem -s
CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE
kmem: invalid structure member offset: slab_list
FILE: memory.c LINE: 9588 FUNCTION: verify_slab_v2()
[/usr/bin/crash] error trace: 40000000000db7c0 => 40000000000ca450 => 40000000000c8ea0 => 40000000001c74a0
40000000001c74a0: OFFSET_verify+224
40000000000c8ea0: verify_slab_v2+448
40000000000ca450: do_slab_chain_percpu_v2_nodes+4208
40000000000db7c0: dump_kmem_cache_percpu_v2+3536
kmem: invalid structure member offset: slab_list
FILE: memory.c LINE: 9588 FUNCTION: verify_slab_v2()
Best Regards,
Qiannan Cui
13 years, 6 months