* Copyright 2010-2017 Intel Corporation.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
* 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.
* Disclaimer: The codes contained in these modules may be specific to
* the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
* fs/proc/vmcore.c Interface for accessing the crash
* dump from the system's previous life.
* Heavily borrowed from fs/proc/kcore.c
* Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
* Copyright (C) IBM Corporation, 2004. All rights reserved
#include <linux/version.h>
#include <linux/proc_fs.h>
#include <linux/elfcore.h>
#include <linux/highmem.h>
#include <linux/bootmem.h>
#include <linux/crash_dump.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
extern struct proc_dir_entry
*vmcore_dir
;
/* Stores the physical address of elf header of crash image. */
unsigned long long elfcorehdr_addr
= 0x50e9000;
* mic_copy_oldmem_page - copy one page from "oldmem"
* @pfn: page frame number to be copied
* @buf: target memory address for the copy; this can be in kernel address
* space or user address space (see @userbuf)
* @csize: number of bytes to copy
* @offset: offset in bytes into the page (based on pfn) to begin the copy
* @userbuf: if set, @buf is in user address space, use copy_to_user(),
* otherwise @buf is in kernel address space, use memcpy().
* Copy a page from "oldmem". For this page, there is no pte mapped
* in the current kernel. We stitch up a pte, similar to kmap_atomic.
ssize_t
mic_copy_oldmem_page(mic_ctx_t
*mic_ctx
,
unsigned long pfn
, char *buf
,
size_t csize
, unsigned long offset
, int userbuf
)
struct dma_channel
*dma_chan
;
dma_addr_t mic_dst_phys_addr
;
vaddr
= mic_ctx
->aper
.va
+ (pfn
<< PAGE_SHIFT
);
if (csize
== PAGE_SIZE
&& !offset
) {
if (!(tmp
= (void*)__get_free_pages(GFP_KERNEL
, get_order(PAGE_SIZE
)))) {
printk(KERN_ERR
"%s: tmp buffer allocation failed\n", __func__
);
mic_dst_phys_addr
= mic_ctx_map_single(mic_ctx
, tmp
, csize
);
if (mic_map_error(mic_dst_phys_addr
)) {
printk(KERN_ERR
"%s: mic_ctx_map_single failed\n", __func__
);
free_pages((unsigned long)tmp
, get_order(PAGE_SIZE
));
if ((allocate_dma_channel(mic_ctx
->dma_handle
, &dma_chan
))) {
printk(KERN_ERR
"%s: allocate_dma_channel failed\n", __func__
);
mic_ctx_unmap_single(mic_ctx
, mic_dst_phys_addr
, csize
);
free_pages((unsigned long)tmp
, get_order(PAGE_SIZE
));
printk(KERN_ERR
"DMA do_dma err %s %d err %d src 0x%lx "
"dst 0x%llx csize 0x%lx\n",
__func__
, __LINE__
, err
, pfn
<< PAGE_SHIFT
,
mic_dst_phys_addr
, csize
);
free_dma_channel(dma_chan
);
mic_ctx_unmap_single(mic_ctx
, mic_dst_phys_addr
, csize
);
free_pages((unsigned long)tmp
, get_order(PAGE_SIZE
));
free_dma_channel(dma_chan
);
err
= drain_dma_poll(dma_chan
);
printk(KERN_ERR
"DMA poll err %s %d err %d src 0x%lx i"
"dst 0x%llx csize 0x%lx\n",
__func__
, __LINE__
, err
, pfn
<< PAGE_SHIFT
,
mic_dst_phys_addr
, csize
);
mic_ctx_unmap_single(mic_ctx
, mic_dst_phys_addr
, csize
);
free_pages((unsigned long)tmp
, get_order(PAGE_SIZE
));
if (copy_to_user(buf
, tmp
, csize
)) {
mic_ctx_unmap_single(mic_ctx
, mic_dst_phys_addr
, csize
);
free_pages((unsigned long)tmp
, get_order(PAGE_SIZE
));
mic_ctx_unmap_single(mic_ctx
, mic_dst_phys_addr
, csize
);
free_pages((unsigned long)tmp
, get_order(PAGE_SIZE
));
if (copy_to_user(buf
, vaddr
+ offset
, csize
))
memcpy_fromio(buf
, vaddr
+ offset
, csize
);
/* Reads a page from the oldmem device from given offset. */
static ssize_t
read_from_oldmem(mic_ctx_t
*mic_ctx
,
unsigned long pfn
, offset
;
offset
= (unsigned long)(*ppos
% PAGE_SIZE
);
pfn
= (unsigned long)(*ppos
/ PAGE_SIZE
);
if (count
> (PAGE_SIZE
- offset
))
nr_bytes
= PAGE_SIZE
- offset
;
tmp
= mic_copy_oldmem_page(mic_ctx
, pfn
, buf
, nr_bytes
, offset
, userbuf
);
/* Maps vmcore file offset to respective physical address in memroy. */
static u64
map_offset_to_paddr(loff_t offset
, struct list_head
*vc_list
,
list_for_each_entry(m
, vc_list
, list
) {
end
= m
->offset
+ m
->size
- 1;
if (offset
>= start
&& offset
<= end
) {
paddr
= m
->paddr
+ offset
- start
;
/* Read from the ELF header and then the crash dump. On error, negative value is
* returned otherwise number of bytes read are returned.
static ssize_t
read_vmcore(struct file
*file
, char __user
*buffer
,
size_t buflen
, loff_t
*fpos
)
struct vmcore
*curr_m
= NULL
;
struct inode
*inode
= file
->f_path
.dentry
->d_inode
;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
mic_ctx_t
*mic_ctx
= PDE_DATA(inode
);
struct proc_dir_entry
*entry
= PDE(inode
);
mic_ctx_t
*mic_ctx
= entry
->data
;
if (buflen
== 0 || *fpos
>= mic_ctx
->vmcore_size
)
/* trim buflen to not go beyond EOF */
if (buflen
> mic_ctx
->vmcore_size
- *fpos
)
buflen
= mic_ctx
->vmcore_size
- *fpos
;
/* Read ELF core header */
if (*fpos
< mic_ctx
->elfcorebuf_sz
) {
tsz
= mic_ctx
->elfcorebuf_sz
- *fpos
;
if (copy_to_user(buffer
, mic_ctx
->elfcorebuf
+ *fpos
, tsz
))
/* leave now if filled buffer already */
start
= map_offset_to_paddr(*fpos
, &mic_ctx
->vmcore_list
, &curr_m
);
if ((tsz
= (PAGE_SIZE
- (start
& ~PAGE_MASK
))) > buflen
)
/* Calculate left bytes in current memory segment. */
nr_bytes
= (curr_m
->size
- (start
- curr_m
->paddr
));
tmp
= read_from_oldmem(mic_ctx
,buffer
, tsz
, &start
, 1);
if (start
>= (curr_m
->paddr
+ curr_m
->size
)) {
if (curr_m
->list
.next
== &mic_ctx
->vmcore_list
)
curr_m
= list_entry(curr_m
->list
.next
,
if ((tsz
= (PAGE_SIZE
- (start
& ~PAGE_MASK
))) > buflen
)
/* Calculate left bytes in current memory segment. */
nr_bytes
= (curr_m
->size
- (start
- curr_m
->paddr
));
static const struct file_operations proc_vmcore_operations
= {
static struct vmcore
* get_new_element(void)
return kzalloc(sizeof(struct vmcore
), GFP_KERNEL
);
static u64
get_vmcore_size_elf64(char *elfptr
)
ehdr_ptr
= (Elf64_Ehdr
*)elfptr
;
phdr_ptr
= (Elf64_Phdr
*)(elfptr
+ sizeof(Elf64_Ehdr
));
size
= sizeof(Elf64_Ehdr
) + ((ehdr_ptr
->e_phnum
) * sizeof(Elf64_Phdr
));
for (i
= 0; i
< ehdr_ptr
->e_phnum
; i
++) {
size
+= phdr_ptr
->p_memsz
;
static u64
get_vmcore_size_elf32(char *elfptr
)
ehdr_ptr
= (Elf32_Ehdr
*)elfptr
;
phdr_ptr
= (Elf32_Phdr
*)(elfptr
+ sizeof(Elf32_Ehdr
));
size
= sizeof(Elf32_Ehdr
) + ((ehdr_ptr
->e_phnum
) * sizeof(Elf32_Phdr
));
for (i
= 0; i
< ehdr_ptr
->e_phnum
; i
++) {
size
+= phdr_ptr
->p_memsz
;
/* Merges all the PT_NOTE headers into one. */
static int merge_note_headers_elf64(mic_ctx_t
*mic_ctx
,
char *elfptr
, size_t *elfsz
,
struct list_head
*vc_list
)
int i
, nr_ptnote
=0, rc
=0;
Elf64_Phdr phdr
, *phdr_ptr
;
u64 phdr_sz
= 0, note_off
;
ehdr_ptr
= (Elf64_Ehdr
*)elfptr
;
phdr_ptr
= (Elf64_Phdr
*)(elfptr
+ sizeof(Elf64_Ehdr
));
for (i
= 0; i
< ehdr_ptr
->e_phnum
; i
++, phdr_ptr
++) {
u64 offset
, max_sz
, sz
, real_sz
= 0;
if (phdr_ptr
->p_type
!= PT_NOTE
)
max_sz
= phdr_ptr
->p_memsz
;
offset
= phdr_ptr
->p_offset
;
notes_section
= kmalloc(max_sz
, GFP_KERNEL
);
rc
= read_from_oldmem(mic_ctx
, notes_section
, max_sz
, &offset
, 0);
nhdr_ptr
= notes_section
;
for (j
= 0; j
< max_sz
; j
+= sz
) {
if (nhdr_ptr
->n_namesz
== 0)
sz
= sizeof(Elf64_Nhdr
) +
((nhdr_ptr
->n_namesz
+ 3) & ~3) +
((nhdr_ptr
->n_descsz
+ 3) & ~3);
nhdr_ptr
= (Elf64_Nhdr
*)((char*)nhdr_ptr
+ sz
);
/* Add this contiguous chunk of notes section to vmcore list.*/
new->paddr
= phdr_ptr
->p_offset
;
list_add_tail(&new->list
, vc_list
);
/* Prepare merged PT_NOTE program header. */
note_off
= sizeof(Elf64_Ehdr
) +
(ehdr_ptr
->e_phnum
- nr_ptnote
+1) * sizeof(Elf64_Phdr
);
phdr
.p_offset
= note_off
;
phdr
.p_vaddr
= phdr
.p_paddr
= 0;
phdr
.p_filesz
= phdr
.p_memsz
= phdr_sz
;
/* Add merged PT_NOTE program header*/
tmp
= elfptr
+ sizeof(Elf64_Ehdr
);
memcpy(tmp
, &phdr
, sizeof(phdr
));
/* Remove unwanted PT_NOTE program headers. */
i
= (nr_ptnote
- 1) * sizeof(Elf64_Phdr
);
memmove(tmp
, tmp
+i
, ((*elfsz
)-sizeof(Elf64_Ehdr
)-sizeof(Elf64_Phdr
)));
/* Modify e_phnum to reflect merged headers. */
ehdr_ptr
->e_phnum
= ehdr_ptr
->e_phnum
- nr_ptnote
+ 1;
/* Merges all the PT_NOTE headers into one. */
static int merge_note_headers_elf32(mic_ctx_t
*mic_ctx
,
char *elfptr
, size_t *elfsz
,
struct list_head
*vc_list
)
int i
, nr_ptnote
=0, rc
=0;
Elf32_Phdr phdr
, *phdr_ptr
;
u64 phdr_sz
= 0, note_off
;
ehdr_ptr
= (Elf32_Ehdr
*)elfptr
;
phdr_ptr
= (Elf32_Phdr
*)(elfptr
+ sizeof(Elf32_Ehdr
));
for (i
= 0; i
< ehdr_ptr
->e_phnum
; i
++, phdr_ptr
++) {
u64 offset
, max_sz
, sz
, real_sz
= 0;
if (phdr_ptr
->p_type
!= PT_NOTE
)
max_sz
= phdr_ptr
->p_memsz
;
offset
= phdr_ptr
->p_offset
;
notes_section
= kmalloc(max_sz
, GFP_KERNEL
);
rc
= read_from_oldmem(mic_ctx
, notes_section
, max_sz
, &offset
, 0);
nhdr_ptr
= notes_section
;
for (j
= 0; j
< max_sz
; j
+= sz
) {
if (nhdr_ptr
->n_namesz
== 0)
sz
= sizeof(Elf32_Nhdr
) +
((nhdr_ptr
->n_namesz
+ 3) & ~3) +
((nhdr_ptr
->n_descsz
+ 3) & ~3);
nhdr_ptr
= (Elf32_Nhdr
*)((char*)nhdr_ptr
+ sz
);
/* Add this contiguous chunk of notes section to vmcore list.*/
new->paddr
= phdr_ptr
->p_offset
;
list_add_tail(&new->list
, vc_list
);
/* Prepare merged PT_NOTE program header. */
note_off
= sizeof(Elf32_Ehdr
) +
(ehdr_ptr
->e_phnum
- nr_ptnote
+1) * sizeof(Elf32_Phdr
);
phdr
.p_offset
= note_off
;
phdr
.p_vaddr
= phdr
.p_paddr
= 0;
phdr
.p_filesz
= phdr
.p_memsz
= phdr_sz
;
/* Add merged PT_NOTE program header*/
tmp
= elfptr
+ sizeof(Elf32_Ehdr
);
memcpy(tmp
, &phdr
, sizeof(phdr
));
/* Remove unwanted PT_NOTE program headers. */
i
= (nr_ptnote
- 1) * sizeof(Elf32_Phdr
);
memmove(tmp
, tmp
+i
, ((*elfsz
)-sizeof(Elf32_Ehdr
)-sizeof(Elf32_Phdr
)));
/* Modify e_phnum to reflect merged headers. */
ehdr_ptr
->e_phnum
= ehdr_ptr
->e_phnum
- nr_ptnote
+ 1;
/* Add memory chunks represented by program headers to vmcore list. Also update
* the new offset fields of exported program headers. */
static int process_ptload_program_headers_elf64(char *elfptr
,
struct list_head
*vc_list
)
ehdr_ptr
= (Elf64_Ehdr
*)elfptr
;
phdr_ptr
= (Elf64_Phdr
*)(elfptr
+ sizeof(Elf64_Ehdr
)); /* PT_NOTE hdr */
/* First program header is PT_NOTE header. */
vmcore_off
= sizeof(Elf64_Ehdr
) +
(ehdr_ptr
->e_phnum
) * sizeof(Elf64_Phdr
) +
phdr_ptr
->p_memsz
; /* Note sections */
for (i
= 0; i
< ehdr_ptr
->e_phnum
; i
++, phdr_ptr
++) {
if (phdr_ptr
->p_type
!= PT_LOAD
)
/* Add this contiguous chunk of memory to vmcore list.*/
new->paddr
= phdr_ptr
->p_offset
;
new->size
= phdr_ptr
->p_memsz
;
list_add_tail(&new->list
, vc_list
);
/* Update the program header offset. */
phdr_ptr
->p_offset
= vmcore_off
;
vmcore_off
= vmcore_off
+ phdr_ptr
->p_memsz
;
static int process_ptload_program_headers_elf32(char *elfptr
,
struct list_head
*vc_list
)
ehdr_ptr
= (Elf32_Ehdr
*)elfptr
;
phdr_ptr
= (Elf32_Phdr
*)(elfptr
+ sizeof(Elf32_Ehdr
)); /* PT_NOTE hdr */
/* First program header is PT_NOTE header. */
vmcore_off
= sizeof(Elf32_Ehdr
) +
(ehdr_ptr
->e_phnum
) * sizeof(Elf32_Phdr
) +
phdr_ptr
->p_memsz
; /* Note sections */
for (i
= 0; i
< ehdr_ptr
->e_phnum
; i
++, phdr_ptr
++) {
if (phdr_ptr
->p_type
!= PT_LOAD
)
/* Add this contiguous chunk of memory to vmcore list.*/
new->paddr
= phdr_ptr
->p_offset
;
new->size
= phdr_ptr
->p_memsz
;
list_add_tail(&new->list
, vc_list
);
/* Update the program header offset */
phdr_ptr
->p_offset
= vmcore_off
;
vmcore_off
= vmcore_off
+ phdr_ptr
->p_memsz
;
/* Sets offset fields of vmcore elements. */
static void set_vmcore_list_offsets_elf64(char *elfptr
,
struct list_head
*vc_list
)
ehdr_ptr
= (Elf64_Ehdr
*)elfptr
;
/* Skip Elf header and program headers. */
vmcore_off
= sizeof(Elf64_Ehdr
) +
(ehdr_ptr
->e_phnum
) * sizeof(Elf64_Phdr
);
list_for_each_entry(m
, vc_list
, list
) {
/* Sets offset fields of vmcore elements. */
static void set_vmcore_list_offsets_elf32(char *elfptr
,
struct list_head
*vc_list
)
ehdr_ptr
= (Elf32_Ehdr
*)elfptr
;
/* Skip Elf header and program headers. */
vmcore_off
= sizeof(Elf32_Ehdr
) +
(ehdr_ptr
->e_phnum
) * sizeof(Elf32_Phdr
);
list_for_each_entry(m
, vc_list
, list
) {
static int parse_crash_elf64_headers(mic_ctx_t
*mic_ctx
)
rc
= read_from_oldmem(mic_ctx
, (char*)&ehdr
, sizeof(Elf64_Ehdr
), &addr
, 0);
/* Do some basic Verification. */
if (memcmp(ehdr
.e_ident
, ELFMAG
, SELFMAG
) != 0 ||
(ehdr
.e_type
!= ET_CORE
) ||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36))
!vmcore_elf64_check_arch(&ehdr
) ||
!vmcore_elf_check_arch(&ehdr
) ||
!elf_check_arch(&ehdr
) ||
ehdr
.e_ident
[EI_CLASS
] != ELFCLASS64
||
ehdr
.e_ident
[EI_VERSION
] != EV_CURRENT
||
ehdr
.e_version
!= EV_CURRENT
||
ehdr
.e_ehsize
!= sizeof(Elf64_Ehdr
) ||
ehdr
.e_phentsize
!= sizeof(Elf64_Phdr
) ||
printk(KERN_WARNING
"Warning: Core image elf header is not"
WARN_ON(mic_ctx
->elfcorebuf
);
/* Read in all elf headers. */
mic_ctx
->elfcorebuf_sz
= sizeof(Elf64_Ehdr
) + ehdr
.e_phnum
* sizeof(Elf64_Phdr
);
mic_ctx
->elfcorebuf
= kmalloc(mic_ctx
->elfcorebuf_sz
, GFP_KERNEL
);
if (!mic_ctx
->elfcorebuf
)
rc
= read_from_oldmem(mic_ctx
, mic_ctx
->elfcorebuf
, mic_ctx
->elfcorebuf_sz
, &addr
, 0);
kfree(mic_ctx
->elfcorebuf
);
mic_ctx
->elfcorebuf
= NULL
;
/* Merge all PT_NOTE headers into one. */
rc
= merge_note_headers_elf64(mic_ctx
, mic_ctx
->elfcorebuf
, &mic_ctx
->elfcorebuf_sz
, &mic_ctx
->vmcore_list
);
kfree(mic_ctx
->elfcorebuf
);
mic_ctx
->elfcorebuf
= NULL
;
rc
= process_ptload_program_headers_elf64(mic_ctx
->elfcorebuf
, mic_ctx
->elfcorebuf_sz
,
kfree(mic_ctx
->elfcorebuf
);
mic_ctx
->elfcorebuf
= NULL
;
set_vmcore_list_offsets_elf64(mic_ctx
->elfcorebuf
, &mic_ctx
->vmcore_list
);
static int parse_crash_elf32_headers(mic_ctx_t
*mic_ctx
)
rc
= read_from_oldmem(mic_ctx
, (char*)&ehdr
, sizeof(Elf32_Ehdr
), &addr
, 0);
/* Do some basic Verification. */
if (memcmp(ehdr
.e_ident
, ELFMAG
, SELFMAG
) != 0 ||
(ehdr
.e_type
!= ET_CORE
) ||
!elf_check_arch(&ehdr
) ||
ehdr
.e_ident
[EI_CLASS
] != ELFCLASS32
||
ehdr
.e_ident
[EI_VERSION
] != EV_CURRENT
||
ehdr
.e_version
!= EV_CURRENT
||
ehdr
.e_ehsize
!= sizeof(Elf32_Ehdr
) ||
ehdr
.e_phentsize
!= sizeof(Elf32_Phdr
) ||
printk(KERN_WARNING
"Warning: Core image elf header is not"
WARN_ON(mic_ctx
->elfcorebuf
);
/* Read in all elf headers. */
mic_ctx
->elfcorebuf_sz
= sizeof(Elf32_Ehdr
) + ehdr
.e_phnum
* sizeof(Elf32_Phdr
);
mic_ctx
->elfcorebuf
= kmalloc(mic_ctx
->elfcorebuf_sz
, GFP_KERNEL
);
if (!mic_ctx
->elfcorebuf
)
rc
= read_from_oldmem(mic_ctx
, mic_ctx
->elfcorebuf
, mic_ctx
->elfcorebuf_sz
, &addr
, 0);
kfree(mic_ctx
->elfcorebuf
);
mic_ctx
->elfcorebuf
= NULL
;
/* Merge all PT_NOTE headers into one. */
rc
= merge_note_headers_elf32(mic_ctx
, mic_ctx
->elfcorebuf
, &mic_ctx
->elfcorebuf_sz
, &mic_ctx
->vmcore_list
);
kfree(mic_ctx
->elfcorebuf
);
mic_ctx
->elfcorebuf
= NULL
;
rc
= process_ptload_program_headers_elf32(mic_ctx
->elfcorebuf
, mic_ctx
->elfcorebuf_sz
,
kfree(mic_ctx
->elfcorebuf
);
mic_ctx
->elfcorebuf
= NULL
;
set_vmcore_list_offsets_elf32(mic_ctx
->elfcorebuf
, &mic_ctx
->vmcore_list
);
static int parse_crash_elf_headers(mic_ctx_t
*mic_ctx
)
unsigned char e_ident
[EI_NIDENT
];
rc
= read_from_oldmem(mic_ctx
, e_ident
, EI_NIDENT
, &addr
, 0);
if (memcmp(e_ident
, ELFMAG
, SELFMAG
) != 0) {
printk(KERN_WARNING
"Warning: Core image elf header"
if (e_ident
[EI_CLASS
] == ELFCLASS64
) {
rc
= parse_crash_elf64_headers(mic_ctx
);
/* Determine vmcore size. */
mic_ctx
->vmcore_size
= get_vmcore_size_elf64(mic_ctx
->elfcorebuf
);
} else if (e_ident
[EI_CLASS
] == ELFCLASS32
) {
rc
= parse_crash_elf32_headers(mic_ctx
);
/* Determine vmcore size. */
mic_ctx
->vmcore_size
= get_vmcore_size_elf32(mic_ctx
->elfcorebuf
);
printk(KERN_WARNING
"Warning: Core image elf header is not"
/* Init function for vmcore module. */
int vmcore_create(mic_ctx_t
*mic_ctx
)
INIT_LIST_HEAD(&mic_ctx
->vmcore_list
);
rc
= parse_crash_elf_headers(mic_ctx
);
printk(KERN_WARNING
"Kdump: vmcore not initialized\n");
if (mic_ctx
->vmcore_dir
) {
remove_proc_entry(name
, vmcore_dir
);
mic_ctx
->vmcore_dir
= NULL
;
snprintf(name
, 64, "mic%d", mic_ctx
->bi_id
);
if (!mic_ctx
->vmcore_dir
) {
mic_ctx
->vmcore_dir
= proc_create_data(name
, S_IRUSR
,
vmcore_dir
, &proc_vmcore_operations
, mic_ctx
);
if (!mic_ctx
->vmcore_dir
) {
printk(KERN_WARNING
"Kdump: proc creation for %s failed\n", name
);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
mic_ctx
->vmcore_dir
->size
= mic_ctx
->vmcore_size
;