[Devel] [PATCH 09/11] ms/x86/mm: Make mmap(MAP_32BIT) work correctly
Dmitry Safonov
dsafonov at virtuozzo.com
Thu May 18 11:39:48 PDT 2017
mmap(MAP_32BIT) is broken due to the dependency on the TIF_ADDR32 thread
flag.
For 64bit applications MAP_32BIT will force legacy bottom-up allocations and
the 1GB address space restriction even if the application issued a compat
syscall, which should not be subject of these restrictions.
For 32bit applications, which issue 64bit syscalls the newly introduced
mmap base separation into 64-bit and compat bases changed the behaviour
because now a 64-bit mapping is returned, but due to the TIF_ADDR32
dependency MAP_32BIT is ignored. Before the separation a 32-bit mapping was
returned, so the MAP_32BIT handling was irrelevant.
Replace the check for TIF_ADDR32 with a check for the compat syscall. That
solves both the 64-bit issuing a compat syscall and the 32-bit issuing a
64-bit syscall problems.
[ tglx: Massaged changelog ]
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
Cc: 0x7f454c46 at gmail.com
Cc: linux-mm at kvack.org
Cc: Andy Lutomirski <luto at kernel.org>
Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Cc: Borislav Petkov <bp at suse.de>
Cc: "Kirill A. Shutemov" <kirill.shutemov at linux.intel.com>
Link: http://lkml.kernel.org/r/20170306141721.9188-5-dsafonov@virtuozzo.com
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
[peeked from ms commit 3e6ef9c80946]
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
arch/x86/kernel/sys_x86_64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 7c6498908838..ffe8b8903fd8 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -114,7 +114,7 @@ static unsigned long get_mmap_base(int is_legacy)
static void find_start_end(unsigned long flags, unsigned long *begin,
unsigned long *end)
{
- if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT)) {
+ if (!in_compat_syscall() && (flags & MAP_32BIT)) {
unsigned long new_begin;
/* This is usually used needed to map code in small
model, so it needs to be in the first 31bit. Limit
@@ -193,7 +193,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
/* for MAP_32BIT mappings we force the legacy mmap base */
- if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT))
+ if (!in_compat_syscall() && (flags & MAP_32BIT))
goto bottomup;
/* requesting a specific address */
--
2.12.2
More information about the Devel
mailing list