lkml.org 
[lkml]   [2011]   [May]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC Patch 5/6] slimdump: Capture slimdump for fatal MCE generated crashes

    slimdump: Capture slimdump for fatal MCE generated crashes

    System crashes resulting from fatal hardware errors (such as MCE) don't need
    all the contents from crashing-kernel's memory. Generate a new 'slimdump' that
    retains only essential information while discarding the old memory.

    Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
    ---
    fs/proc/vmcore.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
    1 file changed, 128 insertions(+), 2 deletions(-)

    Index: linux-2.6.slim_kdump/fs/proc/vmcore.c
    ===================================================================
    --- linux-2.6.slim_kdump.orig/fs/proc/vmcore.c
    +++ linux-2.6.slim_kdump/fs/proc/vmcore.c
    @@ -483,9 +483,60 @@ static void __init set_vmcore_list_offse
    }
    }

    +/*
    + * Check if the crash was due to a fatal Memory Check Exception
    + */
    +static int is_mce_crash64(void)
    +{
    + int i, j, len = 0, rc;
    + Elf64_Ehdr *ehdr_ptr;
    + Elf64_Phdr *phdr_ptr;
    + Elf64_Nhdr *nhdr_ptr;
    +
    + ehdr_ptr = (Elf64_Ehdr *)elfcorebuf;
    + phdr_ptr = (Elf64_Phdr *)(elfcorebuf + sizeof(Elf64_Ehdr));
    +
    + for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
    + void *notes_section;
    + u64 offset, max_sz;
    + if (phdr_ptr->p_type != PT_NOTE)
    + continue;
    + max_sz = phdr_ptr->p_memsz;
    + offset = phdr_ptr->p_offset;
    + notes_section = kmalloc(max_sz, GFP_KERNEL);
    + if (!notes_section)
    + return -ENOMEM;
    + rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
    + if (rc < 0) {
    + kfree(notes_section);
    + return rc;
    + }
    +
    + for (j = 0; j < phdr_ptr->p_filesz; j += len) {
    + nhdr_ptr = notes_section + j;
    + if (nhdr_ptr->n_type == NT_MCE)
    + {
    + kfree(notes_section);
    + return 1;
    + }
    + /*
    + * The elf-64 standard specifies 8-byte alignment while
    + * append_elf_note function does only 4-byte roundup.
    + * Hence this code also does a 4-byte roundup.
    + */
    + len = sizeof(Elf64_Nhdr);
    + len = roundup(len + nhdr_ptr->n_namesz, 4);
    + len = roundup(len + nhdr_ptr->n_descsz, 4);
    + }
    + kfree(notes_section);
    + }
    + return 0;
    +}
    +
    static int __init parse_crash_elf64_headers(void)
    {
    - int rc=0;
    + int i, rc = 0;
    + Elf64_Phdr *phdr_ptr;
    Elf64_Ehdr ehdr;
    u64 addr;

    @@ -523,6 +574,18 @@ static int __init parse_crash_elf64_head
    return rc;
    }

    + phdr_ptr = (Elf64_Phdr *)(elfcorebuf + sizeof(Elf64_Ehdr));
    + if (is_mce_crash64() > 0) {
    + /*
    + * If crash is due to Machine Check exception, don't populate
    + * sections other than elf-notes. Mark their sizes as zero.
    + */
    + for (i = 0; i < ehdr.e_phnum; i++, phdr_ptr++) {
    + if (phdr_ptr->p_type != PT_NOTE)
    + phdr_ptr->p_memsz = phdr_ptr->p_filesz = 0;
    + }
    + }
    +
    /* Merge all PT_NOTE headers into one. */
    rc = merge_note_headers_elf64(elfcorebuf, &elfcorebuf_sz, &vmcore_list);
    if (rc) {
    @@ -539,9 +602,60 @@ static int __init parse_crash_elf64_head
    return 0;
    }

    +/*
    + * Check if the crash was due to a fatal Memory Check Exception
    + */
    +static int is_mce_crash32(void)
    +{
    + int i, j, len = 0, rc;
    + Elf32_Ehdr *ehdr_ptr;
    + Elf32_Phdr *phdr_ptr;
    + Elf32_Nhdr *nhdr_ptr;
    +
    + ehdr_ptr = (Elf32_Ehdr *)elfcorebuf;
    + phdr_ptr = (Elf32_Phdr *)(elfcorebuf + sizeof(Elf32_Ehdr));
    +
    + for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
    + void *notes_section;
    + u64 offset, max_sz;
    + if (phdr_ptr->p_type != PT_NOTE)
    + continue;
    + max_sz = phdr_ptr->p_memsz;
    + offset = phdr_ptr->p_offset;
    + notes_section = kmalloc(max_sz, GFP_KERNEL);
    + if (!notes_section)
    + return -ENOMEM;
    + rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
    + if (rc < 0) {
    + kfree(notes_section);
    + return rc;
    + }
    +
    + for (j = 0; j < phdr_ptr->p_filesz; j += len) {
    + nhdr_ptr = notes_section + j;
    + if (nhdr_ptr->n_type == NT_MCE)
    + {
    + kfree(notes_section);
    + return 1;
    + }
    + /*
    + * The elf-64 standard specifies 8-byte alignment while
    + * append_elf_note function does only 4-byte roundup.
    + * Hence this code also does a 4-byte roundup.
    + */
    + len = sizeof(Elf64_Nhdr);
    + len = roundup(len + nhdr_ptr->n_namesz, 4);
    + len = roundup(len + nhdr_ptr->n_descsz, 4);
    + }
    + kfree(notes_section);
    + }
    + return 0;
    +}
    +
    static int __init parse_crash_elf32_headers(void)
    {
    - int rc=0;
    + int i, rc = 0;
    + Elf32_Phdr *phdr_ptr;
    Elf32_Ehdr ehdr;
    u64 addr;

    @@ -579,6 +693,18 @@ static int __init parse_crash_elf32_head
    return rc;
    }

    + phdr_ptr = (Elf32_Phdr *)(elfcorebuf + sizeof(Elf32_Ehdr));
    + if (is_mce_crash32() > 0) {
    + /*
    + * If crash is due to Machine Check exception, don't populate
    + * sections other than elf-notes. Mark their sizes as zero.
    + */
    + for (i = 0; i < ehdr.e_phnum; i++, phdr_ptr++) {
    + if (phdr_ptr->p_type != PT_NOTE)
    + phdr_ptr->p_memsz = phdr_ptr->p_filesz = 0;
    + }
    + }
    +
    /* Merge all PT_NOTE headers into one. */
    rc = merge_note_headers_elf32(elfcorebuf, &elfcorebuf_sz, &vmcore_list);
    if (rc) {

    \
     
     \ /
      Last update: 2011-05-26 19:25    [W:0.032 / U:59.192 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site