Now regions represented by vmcore are mapped through direct mapping region. We reads requested memory through direct mapping region instead of using ioremap. Notice that we still keep read_from_oldmem that uses ioremap because we need to use it when reading elf headers to make vmcore_list in vmcore initialization. Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com> --- fs/proc/vmcore.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 44 insertions(+), 1 deletions(-) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index aa14570..1c6259e 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -123,6 +123,49 @@ static ssize_t read_from_oldmem(char *buf, size_t count, return read; } +/* Reads a page from the oldmem device from given offset. */ +static ssize_t read_from_oldmem_noioremap(char *buf, size_t count, + u64 *ppos, int userbuf) +{ + unsigned long pfn, offset; + size_t nr_bytes; + ssize_t read = 0; + + if (!count) + return 0; + + offset = (unsigned long)(*ppos % PAGE_SIZE); + pfn = (unsigned long)(*ppos / PAGE_SIZE); + + do { + if (count > (PAGE_SIZE - offset)) + nr_bytes = PAGE_SIZE - offset; + else + nr_bytes = count; + + /* If pfn is not ram, return zeros for sparse dump files */ + if (pfn_is_ram(pfn) == 0) + memset(buf, 0, nr_bytes); + else { + void *vaddr = pfn_to_kaddr(pfn); + + if (userbuf) { + if (copy_to_user(buf, vaddr + offset, nr_bytes)) + return -EFAULT; + } else + memcpy(buf, vaddr + offset, nr_bytes); + } + *ppos += nr_bytes; + count -= nr_bytes; + buf += nr_bytes; + read += nr_bytes; + ++pfn; + offset = 0; + } while (count); + + return read; +} + /* Maps vmcore file offset to respective physical address in memroy. */ static u64 map_offset_to_paddr(loff_t offset, struct list_head *vc_list, struct vmcore **m_ptr) @@ -553,7 +596,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, tsz = nr_bytes; while (buflen) { - tmp = read_from_oldmem(buffer, tsz, &start, 1); + tmp = read_from_oldmem_noioremap(buffer, tsz, &start, 1); if (tmp < 0) return tmp; buflen -= tsz;