All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/hugetlb: Use 32/64 mmap bases according to syscall
@ 2017-03-14 11:41 ` Dmitry Safonov
  0 siblings, 0 replies; 6+ messages in thread
From: Dmitry Safonov @ 2017-03-14 11:41 UTC (permalink / raw)
  To: linux-kernel
  Cc: 0x7f454c46, Dmitry Safonov, kernel test robot, Cyrill Gorcunov,
	Borislav Petkov, Kirill A. Shutemov, H. Peter Anvin, linux-mm,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, x86

Commit:
  1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit
mmap()")

introduced two mmap() bases for 32-bit syscalls and for 64-bit syscalls.
After that commit mm->mmap_base has address to base allocations for
64-bit syscalls, while mm->mmap_compat_base - for 32-bit syscalls.
mmap() code was changed accordingly, but hugetlb code was not changed,
which introduced bogus behavior: 32-bit application which mmaps
file on hugetlbfs uses mm->mmap_base and thou tries to allocate
space with 64-bit mmap() base.
Changed x86 hugetlbfs code to use two bases according to calling
syscall, which also will fix any problems with 32-bit syscalls
in 64-bit ELF and vice-versa.

Fixes: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for
32-bit mmap()").
Reported-by: kernel test robot <xiaolong.ye@intel.com>
Cc: 0x7f454c46@gmail.com
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: linux-mm@kvack.org
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
Note: I've tested it on a simple hand-written test, will reply when
got libhugetlbfs tests running in my environment.

 arch/x86/include/asm/elf.h   |  1 +
 arch/x86/kernel/sys_x86_64.c | 12 ------------
 arch/x86/mm/hugetlbpage.c    |  9 ++++++---
 arch/x86/mm/mmap.c           | 13 +++++++++++++
 4 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ac5be5ba8527..d4d3ed456cb7 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -305,6 +305,7 @@ static inline int mmap_is_ia32(void)
 
 extern unsigned long tasksize_32bit(void);
 extern unsigned long tasksize_64bit(void);
+extern unsigned long get_mmap_base(int is_legacy);
 
 #ifdef CONFIG_X86_32
 
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 63e89dfc808a..207b8f2582c7 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -100,18 +100,6 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
 	return error;
 }
 
-static unsigned long get_mmap_base(int is_legacy)
-{
-	struct mm_struct *mm = current->mm;
-
-#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
-	if (in_compat_syscall())
-		return is_legacy ? mm->mmap_compat_legacy_base
-				 : mm->mmap_compat_base;
-#endif
-	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
-}
-
 static void find_start_end(unsigned long flags, unsigned long *begin,
 			   unsigned long *end)
 {
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index c5066a260803..a50f4600a281 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -16,6 +16,8 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
+#include <asm/elf.h>
+#include <asm/compat.h>
 
 #if 0	/* This is just for testing */
 struct page *
@@ -82,8 +84,9 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
 
 	info.flags = 0;
 	info.length = len;
-	info.low_limit = current->mm->mmap_legacy_base;
-	info.high_limit = TASK_SIZE;
+	info.low_limit = get_mmap_base(1);
+	info.high_limit = in_compat_syscall() ?
+		tasksize_32bit() : tasksize_64bit();
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	return vm_unmapped_area(&info);
@@ -100,7 +103,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
 	info.low_limit = PAGE_SIZE;
-	info.high_limit = current->mm->mmap_base;
+	info.high_limit = get_mmap_base(0);
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	addr = vm_unmapped_area(&info);
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 529ab79800af..0fbb5a71b826 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -31,6 +31,7 @@
 #include <linux/sched/signal.h>
 #include <linux/sched/mm.h>
 #include <asm/elf.h>
+#include <asm/compat.h>
 
 struct va_alignment __read_mostly va_align = {
 	.flags = -1,
@@ -153,6 +154,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 #endif
 }
 
+unsigned long get_mmap_base(int is_legacy)
+{
+	struct mm_struct *mm = current->mm;
+
+#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
+	if (in_compat_syscall())
+		return is_legacy ? mm->mmap_compat_legacy_base
+				 : mm->mmap_compat_base;
+#endif
+	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
+}
+
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
 	if (vma->vm_flags & VM_MPX)
-- 
2.11.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH] x86/hugetlb: Use 32/64 mmap bases according to syscall
@ 2017-03-14 11:41 ` Dmitry Safonov
  0 siblings, 0 replies; 6+ messages in thread
From: Dmitry Safonov @ 2017-03-14 11:41 UTC (permalink / raw)
  To: linux-kernel
  Cc: 0x7f454c46, Dmitry Safonov, kernel test robot, Cyrill Gorcunov,
	Borislav Petkov, Kirill A. Shutemov, H. Peter Anvin, linux-mm,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, x86

Commit:
  1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit
mmap()")

introduced two mmap() bases for 32-bit syscalls and for 64-bit syscalls.
After that commit mm->mmap_base has address to base allocations for
64-bit syscalls, while mm->mmap_compat_base - for 32-bit syscalls.
mmap() code was changed accordingly, but hugetlb code was not changed,
which introduced bogus behavior: 32-bit application which mmaps
file on hugetlbfs uses mm->mmap_base and thou tries to allocate
space with 64-bit mmap() base.
Changed x86 hugetlbfs code to use two bases according to calling
syscall, which also will fix any problems with 32-bit syscalls
in 64-bit ELF and vice-versa.

Fixes: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for
32-bit mmap()").
Reported-by: kernel test robot <xiaolong.ye@intel.com>
Cc: 0x7f454c46@gmail.com
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: linux-mm@kvack.org
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
Note: I've tested it on a simple hand-written test, will reply when
got libhugetlbfs tests running in my environment.

 arch/x86/include/asm/elf.h   |  1 +
 arch/x86/kernel/sys_x86_64.c | 12 ------------
 arch/x86/mm/hugetlbpage.c    |  9 ++++++---
 arch/x86/mm/mmap.c           | 13 +++++++++++++
 4 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ac5be5ba8527..d4d3ed456cb7 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -305,6 +305,7 @@ static inline int mmap_is_ia32(void)
 
 extern unsigned long tasksize_32bit(void);
 extern unsigned long tasksize_64bit(void);
+extern unsigned long get_mmap_base(int is_legacy);
 
 #ifdef CONFIG_X86_32
 
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 63e89dfc808a..207b8f2582c7 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -100,18 +100,6 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
 	return error;
 }
 
-static unsigned long get_mmap_base(int is_legacy)
-{
-	struct mm_struct *mm = current->mm;
-
-#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
-	if (in_compat_syscall())
-		return is_legacy ? mm->mmap_compat_legacy_base
-				 : mm->mmap_compat_base;
-#endif
-	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
-}
-
 static void find_start_end(unsigned long flags, unsigned long *begin,
 			   unsigned long *end)
 {
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index c5066a260803..a50f4600a281 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -16,6 +16,8 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
+#include <asm/elf.h>
+#include <asm/compat.h>
 
 #if 0	/* This is just for testing */
 struct page *
@@ -82,8 +84,9 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
 
 	info.flags = 0;
 	info.length = len;
-	info.low_limit = current->mm->mmap_legacy_base;
-	info.high_limit = TASK_SIZE;
+	info.low_limit = get_mmap_base(1);
+	info.high_limit = in_compat_syscall() ?
+		tasksize_32bit() : tasksize_64bit();
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	return vm_unmapped_area(&info);
@@ -100,7 +103,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
 	info.low_limit = PAGE_SIZE;
-	info.high_limit = current->mm->mmap_base;
+	info.high_limit = get_mmap_base(0);
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	addr = vm_unmapped_area(&info);
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 529ab79800af..0fbb5a71b826 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -31,6 +31,7 @@
 #include <linux/sched/signal.h>
 #include <linux/sched/mm.h>
 #include <asm/elf.h>
+#include <asm/compat.h>
 
 struct va_alignment __read_mostly va_align = {
 	.flags = -1,
@@ -153,6 +154,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 #endif
 }
 
+unsigned long get_mmap_base(int is_legacy)
+{
+	struct mm_struct *mm = current->mm;
+
+#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
+	if (in_compat_syscall())
+		return is_legacy ? mm->mmap_compat_legacy_base
+				 : mm->mmap_compat_base;
+#endif
+	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
+}
+
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
 	if (vma->vm_flags & VM_MPX)
-- 
2.11.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/hugetlb: Use 32/64 mmap bases according to syscall
  2017-03-14 11:41 ` Dmitry Safonov
@ 2017-03-14 12:03   ` Dmitry Safonov
  -1 siblings, 0 replies; 6+ messages in thread
From: Dmitry Safonov @ 2017-03-14 12:03 UTC (permalink / raw)
  To: linux-kernel, Thomas Gleixner
  Cc: 0x7f454c46, kernel test robot, Cyrill Gorcunov, Borislav Petkov,
	Kirill A. Shutemov, H. Peter Anvin, linux-mm, Andy Lutomirski,
	Ingo Molnar, x86

On 03/14/2017 02:41 PM, Dmitry Safonov wrote:
> Commit:
>   1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit
> mmap()")
>
> introduced two mmap() bases for 32-bit syscalls and for 64-bit syscalls.
> After that commit mm->mmap_base has address to base allocations for
> 64-bit syscalls, while mm->mmap_compat_base - for 32-bit syscalls.
> mmap() code was changed accordingly, but hugetlb code was not changed,
> which introduced bogus behavior: 32-bit application which mmaps
> file on hugetlbfs uses mm->mmap_base and thou tries to allocate
> space with 64-bit mmap() base.
> Changed x86 hugetlbfs code to use two bases according to calling
> syscall, which also will fix any problems with 32-bit syscalls
> in 64-bit ELF and vice-versa.
>
> Fixes: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for
> 32-bit mmap()").
> Reported-by: kernel test robot <xiaolong.ye@intel.com>
> Cc: 0x7f454c46@gmail.com
> Cc: Cyrill Gorcunov <gorcunov@openvz.org>
> Cc: Borislav Petkov <bp@suse.de>
> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> Cc: H. Peter Anvin <hpa@zytor.com>
> Cc: linux-mm@kvack.org
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: x86@kernel.org
> Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
> ---
> Note: I've tested it on a simple hand-written test, will reply when
> got libhugetlbfs tests running in my environment.

Can confirm: I've tested this on clean fedora-25 with libhugetlbfs
tests, it's fixed.
Sorry for the breaking.

>
>  arch/x86/include/asm/elf.h   |  1 +
>  arch/x86/kernel/sys_x86_64.c | 12 ------------
>  arch/x86/mm/hugetlbpage.c    |  9 ++++++---
>  arch/x86/mm/mmap.c           | 13 +++++++++++++
>  4 files changed, 20 insertions(+), 15 deletions(-)
>
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index ac5be5ba8527..d4d3ed456cb7 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -305,6 +305,7 @@ static inline int mmap_is_ia32(void)
>
>  extern unsigned long tasksize_32bit(void);
>  extern unsigned long tasksize_64bit(void);
> +extern unsigned long get_mmap_base(int is_legacy);
>
>  #ifdef CONFIG_X86_32
>
> diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
> index 63e89dfc808a..207b8f2582c7 100644
> --- a/arch/x86/kernel/sys_x86_64.c
> +++ b/arch/x86/kernel/sys_x86_64.c
> @@ -100,18 +100,6 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
>  	return error;
>  }
>
> -static unsigned long get_mmap_base(int is_legacy)
> -{
> -	struct mm_struct *mm = current->mm;
> -
> -#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
> -	if (in_compat_syscall())
> -		return is_legacy ? mm->mmap_compat_legacy_base
> -				 : mm->mmap_compat_base;
> -#endif
> -	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
> -}
> -
>  static void find_start_end(unsigned long flags, unsigned long *begin,
>  			   unsigned long *end)
>  {
> diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
> index c5066a260803..a50f4600a281 100644
> --- a/arch/x86/mm/hugetlbpage.c
> +++ b/arch/x86/mm/hugetlbpage.c
> @@ -16,6 +16,8 @@
>  #include <asm/tlb.h>
>  #include <asm/tlbflush.h>
>  #include <asm/pgalloc.h>
> +#include <asm/elf.h>
> +#include <asm/compat.h>
>
>  #if 0	/* This is just for testing */
>  struct page *
> @@ -82,8 +84,9 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
>
>  	info.flags = 0;
>  	info.length = len;
> -	info.low_limit = current->mm->mmap_legacy_base;
> -	info.high_limit = TASK_SIZE;
> +	info.low_limit = get_mmap_base(1);
> +	info.high_limit = in_compat_syscall() ?
> +		tasksize_32bit() : tasksize_64bit();
>  	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
>  	info.align_offset = 0;
>  	return vm_unmapped_area(&info);
> @@ -100,7 +103,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
>  	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
>  	info.length = len;
>  	info.low_limit = PAGE_SIZE;
> -	info.high_limit = current->mm->mmap_base;
> +	info.high_limit = get_mmap_base(0);
>  	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
>  	info.align_offset = 0;
>  	addr = vm_unmapped_area(&info);
> diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
> index 529ab79800af..0fbb5a71b826 100644
> --- a/arch/x86/mm/mmap.c
> +++ b/arch/x86/mm/mmap.c
> @@ -31,6 +31,7 @@
>  #include <linux/sched/signal.h>
>  #include <linux/sched/mm.h>
>  #include <asm/elf.h>
> +#include <asm/compat.h>
>
>  struct va_alignment __read_mostly va_align = {
>  	.flags = -1,
> @@ -153,6 +154,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>  #endif
>  }
>
> +unsigned long get_mmap_base(int is_legacy)
> +{
> +	struct mm_struct *mm = current->mm;
> +
> +#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
> +	if (in_compat_syscall())
> +		return is_legacy ? mm->mmap_compat_legacy_base
> +				 : mm->mmap_compat_base;
> +#endif
> +	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
> +}
> +
>  const char *arch_vma_name(struct vm_area_struct *vma)
>  {
>  	if (vma->vm_flags & VM_MPX)
>


-- 
              Dmitry

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/hugetlb: Use 32/64 mmap bases according to syscall
@ 2017-03-14 12:03   ` Dmitry Safonov
  0 siblings, 0 replies; 6+ messages in thread
From: Dmitry Safonov @ 2017-03-14 12:03 UTC (permalink / raw)
  To: linux-kernel, Thomas Gleixner
  Cc: 0x7f454c46, kernel test robot, Cyrill Gorcunov, Borislav Petkov,
	Kirill A. Shutemov, H. Peter Anvin, linux-mm, Andy Lutomirski,
	Ingo Molnar, x86

On 03/14/2017 02:41 PM, Dmitry Safonov wrote:
> Commit:
>   1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit
> mmap()")
>
> introduced two mmap() bases for 32-bit syscalls and for 64-bit syscalls.
> After that commit mm->mmap_base has address to base allocations for
> 64-bit syscalls, while mm->mmap_compat_base - for 32-bit syscalls.
> mmap() code was changed accordingly, but hugetlb code was not changed,
> which introduced bogus behavior: 32-bit application which mmaps
> file on hugetlbfs uses mm->mmap_base and thou tries to allocate
> space with 64-bit mmap() base.
> Changed x86 hugetlbfs code to use two bases according to calling
> syscall, which also will fix any problems with 32-bit syscalls
> in 64-bit ELF and vice-versa.
>
> Fixes: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for
> 32-bit mmap()").
> Reported-by: kernel test robot <xiaolong.ye@intel.com>
> Cc: 0x7f454c46@gmail.com
> Cc: Cyrill Gorcunov <gorcunov@openvz.org>
> Cc: Borislav Petkov <bp@suse.de>
> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> Cc: H. Peter Anvin <hpa@zytor.com>
> Cc: linux-mm@kvack.org
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: x86@kernel.org
> Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
> ---
> Note: I've tested it on a simple hand-written test, will reply when
> got libhugetlbfs tests running in my environment.

Can confirm: I've tested this on clean fedora-25 with libhugetlbfs
tests, it's fixed.
Sorry for the breaking.

>
>  arch/x86/include/asm/elf.h   |  1 +
>  arch/x86/kernel/sys_x86_64.c | 12 ------------
>  arch/x86/mm/hugetlbpage.c    |  9 ++++++---
>  arch/x86/mm/mmap.c           | 13 +++++++++++++
>  4 files changed, 20 insertions(+), 15 deletions(-)
>
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index ac5be5ba8527..d4d3ed456cb7 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -305,6 +305,7 @@ static inline int mmap_is_ia32(void)
>
>  extern unsigned long tasksize_32bit(void);
>  extern unsigned long tasksize_64bit(void);
> +extern unsigned long get_mmap_base(int is_legacy);
>
>  #ifdef CONFIG_X86_32
>
> diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
> index 63e89dfc808a..207b8f2582c7 100644
> --- a/arch/x86/kernel/sys_x86_64.c
> +++ b/arch/x86/kernel/sys_x86_64.c
> @@ -100,18 +100,6 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
>  	return error;
>  }
>
> -static unsigned long get_mmap_base(int is_legacy)
> -{
> -	struct mm_struct *mm = current->mm;
> -
> -#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
> -	if (in_compat_syscall())
> -		return is_legacy ? mm->mmap_compat_legacy_base
> -				 : mm->mmap_compat_base;
> -#endif
> -	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
> -}
> -
>  static void find_start_end(unsigned long flags, unsigned long *begin,
>  			   unsigned long *end)
>  {
> diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
> index c5066a260803..a50f4600a281 100644
> --- a/arch/x86/mm/hugetlbpage.c
> +++ b/arch/x86/mm/hugetlbpage.c
> @@ -16,6 +16,8 @@
>  #include <asm/tlb.h>
>  #include <asm/tlbflush.h>
>  #include <asm/pgalloc.h>
> +#include <asm/elf.h>
> +#include <asm/compat.h>
>
>  #if 0	/* This is just for testing */
>  struct page *
> @@ -82,8 +84,9 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
>
>  	info.flags = 0;
>  	info.length = len;
> -	info.low_limit = current->mm->mmap_legacy_base;
> -	info.high_limit = TASK_SIZE;
> +	info.low_limit = get_mmap_base(1);
> +	info.high_limit = in_compat_syscall() ?
> +		tasksize_32bit() : tasksize_64bit();
>  	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
>  	info.align_offset = 0;
>  	return vm_unmapped_area(&info);
> @@ -100,7 +103,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
>  	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
>  	info.length = len;
>  	info.low_limit = PAGE_SIZE;
> -	info.high_limit = current->mm->mmap_base;
> +	info.high_limit = get_mmap_base(0);
>  	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
>  	info.align_offset = 0;
>  	addr = vm_unmapped_area(&info);
> diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
> index 529ab79800af..0fbb5a71b826 100644
> --- a/arch/x86/mm/mmap.c
> +++ b/arch/x86/mm/mmap.c
> @@ -31,6 +31,7 @@
>  #include <linux/sched/signal.h>
>  #include <linux/sched/mm.h>
>  #include <asm/elf.h>
> +#include <asm/compat.h>
>
>  struct va_alignment __read_mostly va_align = {
>  	.flags = -1,
> @@ -153,6 +154,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>  #endif
>  }
>
> +unsigned long get_mmap_base(int is_legacy)
> +{
> +	struct mm_struct *mm = current->mm;
> +
> +#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
> +	if (in_compat_syscall())
> +		return is_legacy ? mm->mmap_compat_legacy_base
> +				 : mm->mmap_compat_base;
> +#endif
> +	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
> +}
> +
>  const char *arch_vma_name(struct vm_area_struct *vma)
>  {
>  	if (vma->vm_flags & VM_MPX)
>


-- 
              Dmitry

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [tip:x86/mm] x86/hugetlb: Adjust to the new native/compat mmap bases
  2017-03-14 11:41 ` Dmitry Safonov
  (?)
  (?)
@ 2017-03-14 15:16 ` tip-bot for Dmitry Safonov
  -1 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Dmitry Safonov @ 2017-03-14 15:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, mingo, kirill.shutemov, bp, gorcunov, luto, dsafonov,
	linux-kernel, tglx, xiaolong.ye

Commit-ID:  7d5c038a03acfbedeb3ffef9da1814a47191f6f1
Gitweb:     http://git.kernel.org/tip/7d5c038a03acfbedeb3ffef9da1814a47191f6f1
Author:     Dmitry Safonov <dsafonov@virtuozzo.com>
AuthorDate: Tue, 14 Mar 2017 14:41:26 +0300
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 14 Mar 2017 16:11:47 +0100

x86/hugetlb: Adjust to the new native/compat mmap bases

Commit 1b028f784e8c introduced two mmap() bases for 32-bit syscalls and for
64-bit syscalls. The mmap() code in x86 was modified to handle the
separation, but the patch series missed to update the hugetlb code.

As a consequence a 32bit application mapping a file on hugetlbfs uses the
64-bit mmap base for address space allocation, which fails.

Adjust the hugetlb mapping code to use the proper bases depending on the
syscall invocation mode (64-bit or compat).

[ tglx: Massaged changelog ]

Fixes: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: kernel test robot <xiaolong.ye@intel.com>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Cc: 0x7f454c46@gmail.com
Cc: linux-mm@kvack.org
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Link: http://lkml.kernel.org/r/20170314114126.9280-1-dsafonov@virtuozzo.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 arch/x86/include/asm/elf.h   |  1 +
 arch/x86/kernel/sys_x86_64.c | 12 ------------
 arch/x86/mm/hugetlbpage.c    |  9 ++++++---
 arch/x86/mm/mmap.c           | 14 ++++++++++++++
 4 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ac5be5b..d4d3ed4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -305,6 +305,7 @@ static inline int mmap_is_ia32(void)
 
 extern unsigned long tasksize_32bit(void);
 extern unsigned long tasksize_64bit(void);
+extern unsigned long get_mmap_base(int is_legacy);
 
 #ifdef CONFIG_X86_32
 
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 63e89df..207b8f2 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -100,18 +100,6 @@ out:
 	return error;
 }
 
-static unsigned long get_mmap_base(int is_legacy)
-{
-	struct mm_struct *mm = current->mm;
-
-#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
-	if (in_compat_syscall())
-		return is_legacy ? mm->mmap_compat_legacy_base
-				 : mm->mmap_compat_base;
-#endif
-	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
-}
-
 static void find_start_end(unsigned long flags, unsigned long *begin,
 			   unsigned long *end)
 {
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index c5066a2..a50f460 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -16,6 +16,8 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
+#include <asm/elf.h>
+#include <asm/compat.h>
 
 #if 0	/* This is just for testing */
 struct page *
@@ -82,8 +84,9 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
 
 	info.flags = 0;
 	info.length = len;
-	info.low_limit = current->mm->mmap_legacy_base;
-	info.high_limit = TASK_SIZE;
+	info.low_limit = get_mmap_base(1);
+	info.high_limit = in_compat_syscall() ?
+		tasksize_32bit() : tasksize_64bit();
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	return vm_unmapped_area(&info);
@@ -100,7 +103,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
 	info.low_limit = PAGE_SIZE;
-	info.high_limit = current->mm->mmap_base;
+	info.high_limit = get_mmap_base(0);
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	addr = vm_unmapped_area(&info);
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 529ab79..c3ea70f 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -31,6 +31,7 @@
 #include <linux/sched/signal.h>
 #include <linux/sched/mm.h>
 #include <asm/elf.h>
+#include <asm/compat.h>
 
 struct va_alignment __read_mostly va_align = {
 	.flags = -1,
@@ -153,6 +154,19 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 #endif
 }
 
+unsigned long get_mmap_base(int is_legacy)
+{
+	struct mm_struct *mm = current->mm;
+
+#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
+	if (in_compat_syscall()) {
+		return is_legacy ? mm->mmap_compat_legacy_base
+				 : mm->mmap_compat_base;
+	}
+#endif
+	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
+}
+
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
 	if (vma->vm_flags & VM_MPX)

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [tip:x86/mm] x86/hugetlb: Adjust to the new native/compat mmap bases
  2017-03-14 11:41 ` Dmitry Safonov
                   ` (2 preceding siblings ...)
  (?)
@ 2017-03-14 15:33 ` tip-bot for Dmitry Safonov
  -1 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Dmitry Safonov @ 2017-03-14 15:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: bp, mingo, luto, linux-kernel, kirill.shutemov, dsafonov,
	gorcunov, xiaolong.ye, hpa, tglx

Commit-ID:  e13b73dd9c8003993b171173ba803363faf74238
Gitweb:     http://git.kernel.org/tip/e13b73dd9c8003993b171173ba803363faf74238
Author:     Dmitry Safonov <dsafonov@virtuozzo.com>
AuthorDate: Tue, 14 Mar 2017 14:41:26 +0300
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 14 Mar 2017 16:29:16 +0100

x86/hugetlb: Adjust to the new native/compat mmap bases

Commit 1b028f784e8c introduced two mmap() bases for 32-bit syscalls and for
64-bit syscalls. The mmap() code in x86 was modified to handle the
separation, but the patch series missed to update the hugetlb code.

As a consequence a 32bit application mapping a file on hugetlbfs uses the
64-bit mmap base for address space allocation, which fails.

Adjust the hugetlb mapping code to use the proper bases depending on the
syscall invocation mode (64-bit or compat).

[ tglx: Massaged changelog and switched from asm/compat.h to linux/compat.h ]

Fixes: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: kernel test robot <xiaolong.ye@intel.com>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Cc: 0x7f454c46@gmail.com
Cc: linux-mm@kvack.org
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Link: http://lkml.kernel.org/r/20170314114126.9280-1-dsafonov@virtuozzo.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/elf.h   |  1 +
 arch/x86/kernel/sys_x86_64.c | 12 ------------
 arch/x86/mm/hugetlbpage.c    |  9 ++++++---
 arch/x86/mm/mmap.c           | 14 ++++++++++++++
 4 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ac5be5b..d4d3ed4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -305,6 +305,7 @@ static inline int mmap_is_ia32(void)
 
 extern unsigned long tasksize_32bit(void);
 extern unsigned long tasksize_64bit(void);
+extern unsigned long get_mmap_base(int is_legacy);
 
 #ifdef CONFIG_X86_32
 
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 63e89df..207b8f2 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -100,18 +100,6 @@ out:
 	return error;
 }
 
-static unsigned long get_mmap_base(int is_legacy)
-{
-	struct mm_struct *mm = current->mm;
-
-#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
-	if (in_compat_syscall())
-		return is_legacy ? mm->mmap_compat_legacy_base
-				 : mm->mmap_compat_base;
-#endif
-	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
-}
-
 static void find_start_end(unsigned long flags, unsigned long *begin,
 			   unsigned long *end)
 {
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index c5066a2..302f43f 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -12,10 +12,12 @@
 #include <linux/pagemap.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
+#include <linux/compat.h>
 #include <asm/mman.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
+#include <asm/elf.h>
 
 #if 0	/* This is just for testing */
 struct page *
@@ -82,8 +84,9 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
 
 	info.flags = 0;
 	info.length = len;
-	info.low_limit = current->mm->mmap_legacy_base;
-	info.high_limit = TASK_SIZE;
+	info.low_limit = get_mmap_base(1);
+	info.high_limit = in_compat_syscall() ?
+		tasksize_32bit() : tasksize_64bit();
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	return vm_unmapped_area(&info);
@@ -100,7 +103,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
 	info.low_limit = PAGE_SIZE;
-	info.high_limit = current->mm->mmap_base;
+	info.high_limit = get_mmap_base(0);
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	addr = vm_unmapped_area(&info);
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 529ab79..19ad095 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -30,6 +30,7 @@
 #include <linux/limits.h>
 #include <linux/sched/signal.h>
 #include <linux/sched/mm.h>
+#include <linux/compat.h>
 #include <asm/elf.h>
 
 struct va_alignment __read_mostly va_align = {
@@ -153,6 +154,19 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 #endif
 }
 
+unsigned long get_mmap_base(int is_legacy)
+{
+	struct mm_struct *mm = current->mm;
+
+#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
+	if (in_compat_syscall()) {
+		return is_legacy ? mm->mmap_compat_legacy_base
+				 : mm->mmap_compat_base;
+	}
+#endif
+	return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
+}
+
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
 	if (vma->vm_flags & VM_MPX)

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-03-14 15:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-14 11:41 [PATCH] x86/hugetlb: Use 32/64 mmap bases according to syscall Dmitry Safonov
2017-03-14 11:41 ` Dmitry Safonov
2017-03-14 12:03 ` Dmitry Safonov
2017-03-14 12:03   ` Dmitry Safonov
2017-03-14 15:16 ` [tip:x86/mm] x86/hugetlb: Adjust to the new native/compat mmap bases tip-bot for Dmitry Safonov
2017-03-14 15:33 ` tip-bot for Dmitry Safonov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.