If a given vmcore object has VMCORE_2ND_KERNEL type, target data is in the buffer on 2nd kernel. Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com> --- fs/proc/vmcore.c | 64 ++++++++++++++++++++++++++---------------------------- 1 files changed, 31 insertions(+), 33 deletions(-) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 77e0a0e..4125a65 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -146,8 +146,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, { ssize_t acc = 0, tmp; size_t tsz; - u64 start, nr_bytes; - struct vmcore *curr_m = NULL; + struct vmcore *m; if (buflen == 0 || *fpos >= vmcore_size) return 0; @@ -173,39 +172,38 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, return acc; } - start = map_offset_to_paddr(*fpos, &vmcore_list, &curr_m); - if (!curr_m) - return -EINVAL; - if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) - tsz = buflen; - - /* Calculate left bytes in current memory segment. */ - nr_bytes = (curr_m->size - (start - curr_m->paddr)); - if (tsz > nr_bytes) - tsz = nr_bytes; - - while (buflen) { - tmp = read_from_oldmem(buffer, tsz, &start, 1); - if (tmp < 0) - return tmp; - buflen -= tsz; - *fpos += tsz; - buffer += tsz; - acc += tsz; - if (start >= (curr_m->paddr + curr_m->size)) { - if (curr_m->list.next == &vmcore_list) - return acc; /*EOF*/ - curr_m = list_entry(curr_m->list.next, - struct vmcore, list); - start = curr_m->paddr; + list_for_each_entry(m, &vmcore_list, list) { + if (*fpos < m->offset + m->size) { + tsz = m->offset + m->size - *fpos; + if (buflen < tsz) + tsz = buflen; + switch (m->type) { + case VMCORE_OLD_MEMORY: { + u64 paddr = m->paddr + *fpos - m->offset; + + tmp = read_from_oldmem(buffer, tsz, &paddr, 1); + if (tmp < 0) + return tmp; + break; + } + case VMCORE_2ND_KERNEL: + if (copy_to_user(buffer, + m->buf + (*fpos - m->offset), + tsz)) + return -EFAULT; + break; + } + buflen -= tsz; + *fpos += tsz; + buffer += tsz; + acc += tsz; + + /* leave now if filled buffer already */ + if (buflen == 0) + return acc; } - if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) - tsz = buflen; - /* Calculate left bytes in current memory segment. */ - nr_bytes = (curr_m->size - (start - curr_m->paddr)); - if (tsz > nr_bytes) - tsz = nr_bytes; } + return acc; }