From 6bd330083e0e97b7ddc053459190bf3d5768ca83 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 6 Feb 2012 13:03:09 -0800 Subject: x86: Factor out TIF_IA32 from 32-bit address space Factor out IA32 (compatibility instruction set) from 32-bit address space in the thread_info flags; this is a precondition patch for x32 support. Originally-by: H. J. Lu Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/n/tip-4pr1xnnksprt7t0h3w5fw4rv@git.kernel.org --- arch/x86/kernel/process_64.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/kernel/process_64.c') diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 9b9fe4a85c87..0e900d09e232 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -508,6 +508,7 @@ void set_personality_64bit(void) /* Make sure to be in 64bit mode */ clear_thread_flag(TIF_IA32); + clear_thread_flag(TIF_ADDR32); /* Ensure the corresponding mm is not marked. */ if (current->mm) @@ -526,6 +527,7 @@ void set_personality_ia32(void) /* Make sure to be in 32bit mode */ set_thread_flag(TIF_IA32); + set_thread_flag(TIF_ADDR32); current->personality |= force_personality32; /* Mark the associated mm as containing 32-bit tasks. */ -- cgit v1.2.3 From bb2127240c5595ae4ef7115494f51e973692f64e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 14 Feb 2012 13:56:49 -0800 Subject: x32: Add a thread flag for x32 processes An x32 process is *almost* the same thing as a 64-bit process with a 32-bit address limit, but there are a few minor differences -- in particular core dumps are 32 bits and signal handling is different. Signed-off-by: H. Peter Anvin --- arch/x86/kernel/process_64.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/kernel/process_64.c') diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 0e900d09e232..5fe2fbaa56ba 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -509,6 +509,7 @@ 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); /* Ensure the corresponding mm is not marked. */ if (current->mm) @@ -528,6 +529,7 @@ void set_personality_ia32(void) /* Make sure to be in 32bit mode */ set_thread_flag(TIF_IA32); set_thread_flag(TIF_ADDR32); + clear_thread_flag(TIF_X32); current->personality |= force_personality32; /* Mark the associated mm as containing 32-bit tasks. */ -- cgit v1.2.3 From d1a797f388d6d30fa502915d1b9937ed758b7137 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 19 Feb 2012 10:06:34 -0800 Subject: x32: Handle process creation Allow an x32 process to be started. Originally-by: H. J. Lu Signed-off-by: H. Peter Anvin Cc: Peter Zijlstra --- arch/x86/kernel/process_64.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'arch/x86/kernel/process_64.c') diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 5fe2fbaa56ba..a0701da2bd18 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -364,7 +364,9 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp) { start_thread_common(regs, new_ip, new_sp, - __USER32_CS, __USER32_DS, __USER32_DS); + test_thread_flag(TIF_X32) + ? __USER_CS : __USER32_CS, + __USER_DS, __USER_DS); } #endif @@ -508,6 +510,7 @@ void set_personality_64bit(void) /* Make sure to be in 64bit mode */ clear_thread_flag(TIF_IA32); + clear_thread_flag(TIF_X32); clear_thread_flag(TIF_ADDR32); clear_thread_flag(TIF_X32); @@ -522,22 +525,28 @@ void set_personality_64bit(void) current->personality &= ~READ_IMPLIES_EXEC; } -void set_personality_ia32(void) +void set_personality_ia32(bool x32) { /* inherit personality from parent */ /* Make sure to be in 32bit mode */ - set_thread_flag(TIF_IA32); set_thread_flag(TIF_ADDR32); - clear_thread_flag(TIF_X32); - current->personality |= force_personality32; /* Mark the associated mm as containing 32-bit tasks. */ if (current->mm) current->mm->context.ia32_compat = 1; - /* Prepare the first "return" to user space */ - current_thread_info()->status |= TS_COMPAT; + if (x32) { + clear_thread_flag(TIF_IA32); + set_thread_flag(TIF_X32); + current->personality &= ~READ_IMPLIES_EXEC; + } else { + set_thread_flag(TIF_IA32); + clear_thread_flag(TIF_X32); + current->personality |= force_personality32; + /* Prepare the first "return" to user space */ + current_thread_info()->status |= TS_COMPAT; + } } unsigned long get_wchan(struct task_struct *p) -- cgit v1.2.3 From ce5f7a99df87918b5be4618a9386213a8e9a7146 Mon Sep 17 00:00:00 2001 From: Bobby Powers Date: Sat, 25 Feb 2012 23:25:38 -0500 Subject: x32: Make sure TS_COMPAT is cleared for x32 tasks If a process has a non-x32 ia32 personality and changes to x32, the process would keep its TS_COMPAT flag. x32 uses the presence of the x32 flag on a syscall to determine compat status, so make sure TS_COMPAT is cleared. Signed-off-by: Bobby Powers Link: http://lkml.kernel.org/r/1330230338-25077-1-git-send-email-bobbypowers@gmail.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/process_64.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/x86/kernel/process_64.c') diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index a0701da2bd18..32e04120b2cd 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -540,6 +540,9 @@ void set_personality_ia32(bool x32) clear_thread_flag(TIF_IA32); set_thread_flag(TIF_X32); current->personality &= ~READ_IMPLIES_EXEC; + /* is_compat_task() uses the presence of the x32 + syscall bit flag to determine compat status */ + current_thread_info()->status &= ~TS_COMPAT; } else { set_thread_flag(TIF_IA32); clear_thread_flag(TIF_X32); -- cgit v1.2.3 From 00194b2e845da29395ad00c13a884d9acb9306b5 Mon Sep 17 00:00:00 2001 From: Bobby Powers Date: Sat, 25 Feb 2012 22:59:34 -0500 Subject: x32: Only clear TIF_X32 flag once Commits bb212724 and d1a797f3 both added a call to clear_thread_flag(TIF_X32) under set_personality_64bit() - only one is needed. Signed-off-by: Bobby Powers Link: http://lkml.kernel.org/r/1330228774-24223-1-git-send-email-bobbypowers@gmail.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/process_64.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/x86/kernel/process_64.c') diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 32e04120b2cd..a4659739e202 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -510,7 +510,6 @@ void set_personality_64bit(void) /* Make sure to be in 64bit mode */ clear_thread_flag(TIF_IA32); - clear_thread_flag(TIF_X32); clear_thread_flag(TIF_ADDR32); clear_thread_flag(TIF_X32); -- cgit v1.2.3