From: HATAYAMA Daisuke Date: Wed, 20 Mar 2013 04:08:38 +0000 (+1100) Subject: vmcore: check if vmcore objects satify mmap()'s page-size boundary requirement X-Git-Tag: next-20130320~2^2~94 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=333775f849bb1ae89df2c9fc8a8715e1ed2a3627;p=karo-tx-linux.git vmcore: check if vmcore objects satify mmap()'s page-size boundary requirement If there's some vmcore object that doesn't satisfy page-size boundary requirement, remap_pfn_range() fails to remap it to user-space. Objects that possibly don't satisfy the requirement are ELF note segments only. The memory chunks corresponding to PT_LOAD entries are guaranteed to satisfy page-size boundary requirement by the copy from old memory to buffer in 2nd kernel done in later patch. This patch doesn't copy each note segment into the 2nd kernel since they amount to so large in total if there are multiple CPUs. For example, current maximum number of CPUs in x86_64 is 5120, where note segments exceed 1MB with NT_PRSTATUS only. Signed-off-by: HATAYAMA Daisuke Cc: Zhang Yanfei Cc: Vivek Goyal Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton --- diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 2a0f8850c05a..0077a9a880ce 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -38,6 +38,8 @@ static u64 vmcore_size; static struct proc_dir_entry *proc_vmcore = NULL; +static bool support_mmap_vmcore; + /* * Returns > 0 for RAM pages, 0 for non-RAM pages, < 0 on error * The called function has to take care of module refcounting. @@ -911,6 +913,7 @@ static int __init parse_crash_elf_headers(void) static int __init vmcore_init(void) { int rc = 0; + struct vmcore *m; /* If elfcorehdr= has been passed in cmdline, then capture the dump.*/ if (!(is_vmcore_usable())) @@ -921,6 +924,25 @@ static int __init vmcore_init(void) return rc; } + /* If some object doesn't satisfy PAGE_SIZE boundary + * requirement, mmap_vmcore() is not exported to + * user-space. */ + support_mmap_vmcore = true; + list_for_each_entry(m, &vmcore_list, list) { + u64 paddr; + + if (m->flag & MEM_TYPE_CURRENT_KERNEL) + paddr = (u64)__pa(m->buf); + else + paddr = m->paddr; + + if ((m->offset & ~PAGE_MASK) || (paddr & ~PAGE_MASK) + || (m->size & ~PAGE_MASK)) { + support_mmap_vmcore = false; + break; + } + } + proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations); if (proc_vmcore) proc_vmcore->size = vmcore_size;