vmcore: disable mmap_vmcore() if CONFIG_MMU is not defined
Subsystems (4)
PATCH 1/1 vmcore: disable mmap_vmcore() if CONFIG_MMU is not defined
Hello,
This patch fixes the issue reported by Amd on an overlook of no-MMU configuration.
This patch is made on top of v3.10-rc4-mmotm-2013-06-06-16-19.
I tested this on x86_64 and x86 with 1GB and 5GB memory.
I build this on arm without CONFIG_MMU configuration.
Thanks.
HATAYAMA, Daisuke
Quoted 1 line
From
e2f067a497872a9c60002c56ea550e4600072166Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <[email protected]>
Date: Sat, 8 Jun 2013 20:46:57 +0900
Subject: [PATCH] vmcore: disable mmap_vmcore() if CONFIG_MMU is not defined
Quoted 1 line
From Amd's report of a link-time build error in
vmcore.c, it turned
out that mmap_vmcore() work overlooked no-MMU configuraiton.
In the current design, it's impossible to implement mmap_vmcore() for no-MMU configuration since MMU is essential in order to map physically non-contiguous objects (ELF header, ELF note segment and memory regions in the 1st kernel pointed to by PT_LOAD entries) into virtually contiguous user-space in ELF layout.
Hence, this patch disables mmap_vmcore() if CONFIG_MMU is not defined, returning -ENOSYS.
Another change is to fix the build error by using vmalloc_user() instead of calling vzalloc() and find_vm_area() in order, by which we no longer need to call find_vm_area() in vmcore.c that has no counterpart on non-MMU configuration.
Also, on no-MMU configuration, because we don't export buffer for ELF note segment to user-space, we use vzalloc() to allocate the buffer. Therefore, we use differnet functions to allocate the buffer for ELF note segment. To avoid code duplication, introduce a helper alloc_elfnotes_buf().
--- fs/proc/vmcore.c | 57 +++++++++++++++++++++++++++++++++++------------------ 1 files changed, 37 insertions(+), 20 deletions(-)
fs/proc/vmcore.c +37 -20
@@ -195,6 +195,35 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,return acc; } +/** +* alloc_elfnotes_buf - allocate buffer for ELF note segment in +* vmalloc memory +* +* @notes_sz: size of buffer +* +* If CONFIG_MMU is defined, use vmalloc_user() to allow users to mmap +* the buffer to user-space by means of remap_vmalloc_range(). +* +* If CONFIG_MMU is not defined, use vzalloc() since mmap_vmcore() is +* disabled and there's no need to allow users to mmap the buffer. +*/ +static inline char *alloc_elfnotes_buf (size_t notes_sz) +{ +#ifdef CONFIG_MMU +return vmalloc_user (notes_sz); +#else +return vzalloc (notes_sz); +#endif +} + +/* +* Disable mmap_vmcore() if CONFIG_MMU is not defined. MMU is +* essential for mmap_vmcore() in order to map physically +* non-contiguous objects (ELF header, ELF note segment and memory +* regions in the 1st kernel pointed to by PT_LOAD entries) into +* virtually contiguous user-space in ELF layout. +*/ +#ifdef CONFIG_MMU static int mmap_vmcore (struct file *file,struct vm_area_struct *vma) {size_t size = vma->vm_end - vma->vm_start;
@@ -271,6 +300,12 @@ fail:do_munmap (vma->vm_mm, vma->vm_start, len);return -EAGAIN ; } +#else +static int mmap_vmcore (struct file *file,struct vm_area_struct *vma) +{ +return -ENOSYS ; +} +#endif static const struct file_operations proc_vmcore_operations = { .read = read_vmcore,
@@ -427,7 +462,6 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,Elf64_Ehdr *ehdr_ptr;Elf64_Phdr phdr;u64 phdr_sz =0 , note_off; -struct vm_struct *vm; ehdr_ptr = (Elf64_Ehdr *)elfptr;
@@ -440,18 +474,10 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,return rc; *notes_sz =roundup (phdr_sz,PAGE_SIZE ); - *notes_buf =vzalloc (*notes_sz); + *notes_buf =alloc_elfnotes_buf (*notes_sz);if (!*notes_buf)return -ENOMEM ; -/* -* Allow users to remap ELF note segment buffer on vmalloc memory using -* remap_vmalloc_range.() -*/ - vm =find_vm_area (*notes_buf); -BUG_ON (!vm); - vm->flags |=VM_USERMAP ; - rc =copy_notes_elf64 (ehdr_ptr, *notes_buf);if (rc <0 )return rc;
@@ -615,7 +641,6 @@ static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,Elf32_Ehdr *ehdr_ptr;Elf32_Phdr phdr;u64 phdr_sz =0 , note_off; -struct vm_struct *vm; ehdr_ptr = (Elf32_Ehdr *)elfptr;
@@ -628,18 +653,10 @@ static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,return rc; *notes_sz =roundup (phdr_sz,PAGE_SIZE ); - *notes_buf =vzalloc (*notes_sz); + *notes_buf =alloc_elfnotes_buf (*notes_sz);if (!*notes_buf)return -ENOMEM ; -/* -* Allow users to remap ELF note segment buffer on vmalloc memory using -* remap_vmalloc_range() -*/ - vm =find_vm_area (*notes_buf); -BUG_ON (!vm); - vm->flags |=VM_USERMAP ; - rc =copy_notes_elf32 (ehdr_ptr, *notes_buf);if (rc <0 )return rc;
Signature · 1 line
1.7.7.6
Quoted 27 lines · HATAYAMA Daisuke
Hello,
This patch fixes the issue reported by Amd on an overlook of no-MMU configuration.
This patch is made on top of v3.10-rc4-mmotm-2013-06-06-16-19.
I tested this on
x86_64and x86 with 1GB and 5GB memory.I build this on arm without
CONFIG_MMUconfiguration.Thanks.
HATAYAMA, DaisukeQuoted 1 line
From
e2f067a497872a9c60002c56ea550e4600072166Mon Sep 17 00:00:00 2001From: HATAYAMA Daisuke <[email protected]>
Date: Sat, 8 Jun 2013 20:46:57 +0900
Subject: [PATCH] vmcore: disablemmap_vmcore()ifCONFIG_MMUis not definedQuoted 1 line
From Amd's report of a link-time build error in
vmcore.c, it turnedout that
mmap_vmcore()work overlooked no-MMU configuraiton.In the current design, it's impossible to implement
mmap_vmcore()for no-MMU configuration since MMU is essential in order to map physically non-contiguous objects (ELF header, ELF note segment and memory regions in the 1st kernel pointed to byPT_LOADentries) into virtually contiguous user-space in ELF layout.
Quoted 4 lines
Hence, this patch disables
mmap_vmcore()ifCONFIG_MMUis not defined, returning-ENOSYS.Another change is to fix the build error by using
vmalloc_user()
Yeah, I think this change makes code more clear by hiding vmcore-irrelevant details.
Quoted 125 lines
instead of calling
vzalloc()andfind_vm_area()in order, by which we no longer need to callfind_vm_area()invmcore.cthat has no counterpart on non-MMU configuration.Also, on no-MMU configuration, because we don't export buffer for ELF note segment to user-space, we use
vzalloc()to allocate the buffer. Therefore, we use differnet functions to allocate the buffer for ELF note segment. To avoid code duplication, introduce a helperalloc_elfnotes_buf().Reported-by Amd Bergmann <[email protected]>Signed-off-by HATAYAMA Daisuke <[email protected]>--- fs/proc/vmcore.c | 57 +++++++++++++++++++++++++++++++++++------------------ 1 files changed, 37 insertions(+), 20 deletions(-)fs/proc/vmcore.c +37
-20@@ -195,6 +195,35 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,return acc; } +/** +* alloc_elfnotes_buf - allocate buffer for ELF note segment in +* vmalloc memory +* +* @notes_sz: size of buffer +* +* If CONFIG_MMU is defined, use vmalloc_user() to allow users to mmap +* the buffer to user-space by means of remap_vmalloc_range(). +* +* If CONFIG_MMU is not defined, use vzalloc() since mmap_vmcore() is +* disabled and there's no need to allow users to mmap the buffer. +*/ +static inline char *alloc_elfnotes_buf (size_t notes_sz) +{ +#ifdef CONFIG_MMU +return vmalloc_user (notes_sz); +#else +return vzalloc (notes_sz); +#endif +} + +/* +* Disable mmap_vmcore() if CONFIG_MMU is not defined. MMU is +* essential for mmap_vmcore() in order to map physically +* non-contiguous objects (ELF header, ELF note segment and memory +* regions in the 1st kernel pointed to by PT_LOAD entries) into +* virtually contiguous user-space in ELF layout. +*/ +#ifdef CONFIG_MMU static int mmap_vmcore (struct file *file,struct vm_area_struct *vma) {size_t size = vma->vm_end - vma->vm_start;@@ -271,6 +300,12 @@ fail:do_munmap (vma->vm_mm, vma->vm_start, len);return -EAGAIN ; } +#else +static int mmap_vmcore (struct file *file,struct vm_area_struct *vma) +{ +return -ENOSYS ; +} +#endif static const struct file_operations proc_vmcore_operations = { .read = read_vmcore,@@ -427,7 +462,6 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,Elf64_Ehdr *ehdr_ptr;Elf64_Phdr phdr;u64 phdr_sz =0 , note_off; -struct vm_struct *vm; ehdr_ptr = (Elf64_Ehdr *)elfptr;@@ -440,18 +474,10 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,return rc; *notes_sz =roundup (phdr_sz,PAGE_SIZE ); - *notes_buf =vzalloc (*notes_sz); + *notes_buf =alloc_elfnotes_buf (*notes_sz);if (!*notes_buf)return -ENOMEM ; -/* -* Allow users to remap ELF note segment buffer on vmalloc memory using -* remap_vmalloc_range.() -*/ - vm =find_vm_area (*notes_buf); -BUG_ON (!vm); - vm->flags |=VM_USERMAP ; - rc =copy_notes_elf64 (ehdr_ptr, *notes_buf);if (rc <0 )return rc;@@ -615,7 +641,6 @@ static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,Elf32_Ehdr *ehdr_ptr;Elf32_Phdr phdr;u64 phdr_sz =0 , note_off; -struct vm_struct *vm; ehdr_ptr = (Elf32_Ehdr *)elfptr;@@ -628,18 +653,10 @@ static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,return rc; *notes_sz =roundup (phdr_sz,PAGE_SIZE ); - *notes_buf =vzalloc (*notes_sz); + *notes_buf =alloc_elfnotes_buf (*notes_sz);if (!*notes_buf)return -ENOMEM ; -/* -* Allow users to remap ELF note segment buffer on vmalloc memory using -* remap_vmalloc_range() -*/ - vm =find_vm_area (*notes_buf); -BUG_ON (!vm); - vm->flags |=VM_USERMAP ; - rc =copy_notes_elf32 (ehdr_ptr, *notes_buf);if (rc <0 )return rc;
Signature · 2 lines
Thanks. Zhang Yanfei
Quoted 8 lines · HATAYAMA Daisuke
Also, on no-MMU configuration, because we don't export buffer for ELF note segment to user-space, we use
vzalloc()to allocate the buffer. Therefore, we use differnet functions to allocate the buffer for ELF note segment. To avoid code duplication, introduce a helperalloc_elfnotes_buf().Reported-by Amd Bergmann <[email protected]>Signed-off-by HATAYAMA Daisuke <[email protected]>
Thanks
Note that my name is Arnd not Amd, otherwise