[RFC 2/4] x86/thread_info: kill TIF_ADDR32 in favour of ADDR_LIMIT_32BIT

From: Dmitry Safonov
Date: Fri Dec 30 2016 - 14:34:43 EST


This thread flag is completely x86-specific, consolidate it with
ADDR_LIMIT_32BIT personality which is defined but not used on x86.
It will free one of thread flags and consolidate personality with
other arches.
After this commit ADDR_LIMIT_32BIT is set by the kernel automatically
in COMPAT_SET_PERSONALITY() for 32-bit ELF files and for 32-bit a.out.
It's cleared in SET_PERSONALITY() for 64-bit ELFs.

Signed-off-by: Dmitry Safonov <dsafonov@xxxxxxxxxxxxx>
---
arch/x86/include/asm/elf.h | 7 +++++--
arch/x86/include/asm/processor.h | 2 +-
arch/x86/include/asm/thread_info.h | 4 +---
arch/x86/kernel/process_64.c | 4 ++--
arch/x86/kernel/sys_x86_64.c | 4 ++--
5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index e7f155c3045e..02f39b363e61 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -5,6 +5,8 @@
* ELF register definitions..
*/
#include <linux/thread_info.h>
+#include <linux/personality.h>
+#include <linux/sched.h>

#include <asm/ptrace.h>
#include <asm/user.h>
@@ -295,7 +297,8 @@ do { \
#else /* CONFIG_X86_32 */

/* 1GB for 64bit, 8MB for 32bit */
-#define STACK_RND_MASK (test_thread_flag(TIF_ADDR32) ? 0x7ff : 0x3fffff)
+#define STACK_RND_MASK \
+ ((current->personality & ADDR_LIMIT_32BIT) ? 0x7ff : 0x3fffff)

#define ARCH_DLINFO \
do { \
@@ -346,7 +349,7 @@ static inline int mmap_is_ia32(void)
{
return IS_ENABLED(CONFIG_X86_32) ||
(IS_ENABLED(CONFIG_COMPAT) &&
- test_thread_flag(TIF_ADDR32));
+ (current->personality & ADDR_LIMIT_32BIT));
}

/* Do not change the values. See get_align_mask() */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 090a860b792a..dbc7dec5fa84 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -817,7 +817,7 @@ static inline void spin_lock_prefetch(const void *x)
#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
0xc0000000 : 0xFFFFe000)

-#define TASK_SIZE (test_thread_flag(TIF_ADDR32) ? \
+#define TASK_SIZE (current->personality & ADDR_LIMIT_32BIT ? \
IA32_PAGE_OFFSET : TASK_SIZE_MAX)

#define STACK_TOP TASK_SIZE
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index ad6f5eb07a95..6a5763e6ca1b 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -97,8 +97,7 @@ struct thread_info {
#define TIF_BLOCKSTEP 25 /* set when we want DEBUGCTLMSR_BTF */
#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
#define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */
-#define TIF_ADDR32 29 /* 32-bit address space on 64 bits */
-#define TIF_X32 30 /* 32-bit native x86-64 binary */
+#define TIF_X32 29 /* 32-bit native x86-64 binary */

#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@@ -119,7 +118,6 @@ struct thread_info {
#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
-#define _TIF_ADDR32 (1 << TIF_ADDR32)
#define _TIF_X32 (1 << TIF_X32)

/*
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index a61e141b6891..8ce30d40bb33 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -489,8 +489,8 @@ void set_personality_64bit(void)

/* Make sure to be in 64bit mode */
clear_thread_flag(TIF_IA32);
- clear_thread_flag(TIF_ADDR32);
clear_thread_flag(TIF_X32);
+ current->personality &= ~ADDR_LIMIT_32BIT;

/* Ensure the corresponding mm is not marked. */
if (current->mm)
@@ -508,7 +508,7 @@ void set_personality_ia32(bool x32)
/* inherit personality from parent */

/* Make sure to be in 32bit mode */
- set_thread_flag(TIF_ADDR32);
+ current->personality |= ADDR_LIMIT_32BIT;

/* Mark the associated mm as containing 32-bit tasks. */
if (x32) {
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index a55ed63b9f91..e836a7318f1f 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -100,7 +100,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
static void find_start_end(unsigned long flags, unsigned long *begin,
unsigned long *end)
{
- if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT)) {
+ if (!(current->personality & ADDR_LIMIT_32BIT) && (flags & MAP_32BIT)) {
/* This is usually used needed to map code in small
model, so it needs to be in the first 31bit. Limit
it to that. This means we need to move the
@@ -175,7 +175,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 (!(current->personality & ADDR_LIMIT_32BIT) && (flags & MAP_32BIT))
goto bottomup;

/* requesting a specific address */
--
2.11.0