Skip to contentSkip to conversation

x86/compat: Separate X32 from 32-bit compat

PATCH In review Brian Gerst 3 participants 28 messages Jun 22, 2015 – Jul 6, 2015

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

cover x86/compat: Separate X32 from 32-bit compat

This patch series makes it possible to enable the X32 ABI support without the dependency on 32-bit compatability. Code that is shared between X32 and 32-bit compat is marked with CONFIG_COMPAT, but non-shared code like syscall entries, signal handling, and the VDSO are kept under separate config options.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in Please read the FAQ at http://www.tux.org/lkml/

#1 lore raw

PATCH 1/12 x86/compat: Move copy_siginfo_*_user32() to signal_compat.c

copy_siginfo_to_user32() and copy_siginfo_from_user32() are used by both the 32-bit compat and x32 ABIs. Move them to signal_compat.c.

---
 arch/x86/ia32/ia32_signal.c     | 93 ----------------------------------------
 arch/x86/kernel/Makefile        |  1 +
 arch/x86/kernel/signal_compat.c | 95 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+), 93 deletions(-)
 create mode 100644 arch/x86/kernel/signal_compat.c
arch/x86/ia32/ia32_signal.c +0 -93
index ae3a29a..a0a19b7 100644
@@ -34,99 +34,6 @@
 #include <asm/sys_ia32.h>
 #include <asm/smap.h>
 
-int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
-{
-	int err = 0;
-	bool ia32 = test_thread_flag(TIF_IA32);
-
-	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
-		return -EFAULT;
-
-	put_user_try {
-		/* If you change siginfo_t structure, please make sure that
-		   this code is fixed accordingly.
-		   It should never copy any pad contained in the structure
-		   to avoid security leaks, but must copy the generic
-		   3 ints plus the relevant union member.  */
-		put_user_ex(from->si_signo, &to->si_signo);
-		put_user_ex(from->si_errno, &to->si_errno);
-		put_user_ex((short)from->si_code, &to->si_code);
-
-		if (from->si_code < 0) {
-			put_user_ex(from->si_pid, &to->si_pid);
-			put_user_ex(from->si_uid, &to->si_uid);
-			put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
-		} else {
-			/*
-			 * First 32bits of unions are always present:
-			 * si_pid === si_band === si_tid === si_addr(LS half)
-			 */
-			put_user_ex(from->_sifields._pad[0],
-					  &to->_sifields._pad[0]);
-			switch (from->si_code >> 16) {
-			case __SI_FAULT >> 16:
-				break;
-			case __SI_SYS >> 16:
-				put_user_ex(from->si_syscall, &to->si_syscall);
-				put_user_ex(from->si_arch, &to->si_arch);
-				break;
-			case __SI_CHLD >> 16:
-				if (ia32) {
-					put_user_ex(from->si_utime, &to->si_utime);
-					put_user_ex(from->si_stime, &to->si_stime);
-				} else {
-					put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
-					put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
-				}
-				put_user_ex(from->si_status, &to->si_status);
-				/* FALL THROUGH */
-			default:
-			case __SI_KILL >> 16:
-				put_user_ex(from->si_uid, &to->si_uid);
-				break;
-			case __SI_POLL >> 16:
-				put_user_ex(from->si_fd, &to->si_fd);
-				break;
-			case __SI_TIMER >> 16:
-				put_user_ex(from->si_overrun, &to->si_overrun);
-				put_user_ex(ptr_to_compat(from->si_ptr),
-					    &to->si_ptr);
-				break;
-				 /* This is not generated by the kernel as of now.  */
-			case __SI_RT >> 16:
-			case __SI_MESGQ >> 16:
-				put_user_ex(from->si_uid, &to->si_uid);
-				put_user_ex(from->si_int, &to->si_int);
-				break;
-			}
-		}
-	} put_user_catch(err);
-
-	return err;
-}
-
-int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
-{
-	int err = 0;
-	u32 ptr32;
-
-	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
-		return -EFAULT;
-
-	get_user_try {
-		get_user_ex(to->si_signo, &from->si_signo);
-		get_user_ex(to->si_errno, &from->si_errno);
-		get_user_ex(to->si_code, &from->si_code);
-
-		get_user_ex(to->si_pid, &from->si_pid);
-		get_user_ex(to->si_uid, &from->si_uid);
-		get_user_ex(ptr32, &from->si_ptr);
-		to->si_ptr = compat_ptr(ptr32);
-	} get_user_catch(err);
-
-	return err;
-}
-
 /*
  * Do a signal return; undo the signal stack.
  */
arch/x86/kernel/Makefile +1 -0
index 0f15af4..dc19730 100644
@@ -23,6 +23,7 @@ KASAN_SANITIZE_dumpstack_$(BITS).o := n
 CFLAGS_irq.o := -I$(src)/../include/asm/trace
 
 obj-y			:= process_$(BITS).o signal.o
+obj-$(CONFIG_COMPAT)	+= signal_compat.o
 obj-y			+= traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y			+= time.o ioport.o ldt.o dumpstack.o nmi.o
 obj-y			+= setup.o x86_init.o i8259.o irqinit.o jump_label.o
arch/x86/kernel/signal_compat.c new file +95 -0

95 lines not on this page · raw message

Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#2 lore raw

[tip:x86/asm] x86/compat: Move copy_siginfo_*_user32() to signal_compat.c

x86/compat: Move copy_siginfo_*_user32() to signal_compat.c
Commit-ID:  c0bfd26e136cafc2b23c16225b4d7b1e14de81c1
Gitweb:     http://git.kernel.org/tip/c0bfd26e136cafc2b23c16225b4d7b1e14de81c1
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:10 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:55 +0200

x86/compat: Move copy_siginfo_*_user32() to signal_compat.c

copy_siginfo_to_user32() and copy_siginfo_from_user32() are used by both the 32-bit compat and x32 ABIs. Move them to signal_compat.c.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/ia32/ia32_signal.c     | 93 ----------------------------------------
 arch/x86/kernel/Makefile        |  1 +
 arch/x86/kernel/signal_compat.c | 95 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+), 93 deletions(-)
arch/x86/ia32/ia32_signal.c +0 -93
index ae3a29a..a0a19b7 100644
@@ -34,99 +34,6 @@
 #include <asm/sys_ia32.h>
 #include <asm/smap.h>
 
-int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
-{
-	int err = 0;
-	bool ia32 = test_thread_flag(TIF_IA32);
-
-	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
-		return -EFAULT;
-
-	put_user_try {
-		/* If you change siginfo_t structure, please make sure that
-		   this code is fixed accordingly.
-		   It should never copy any pad contained in the structure
-		   to avoid security leaks, but must copy the generic
-		   3 ints plus the relevant union member.  */
-		put_user_ex(from->si_signo, &to->si_signo);
-		put_user_ex(from->si_errno, &to->si_errno);
-		put_user_ex((short)from->si_code, &to->si_code);
-
-		if (from->si_code < 0) {
-			put_user_ex(from->si_pid, &to->si_pid);
-			put_user_ex(from->si_uid, &to->si_uid);
-			put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
-		} else {
-			/*
-			 * First 32bits of unions are always present:
-			 * si_pid === si_band === si_tid === si_addr(LS half)
-			 */
-			put_user_ex(from->_sifields._pad[0],
-					  &to->_sifields._pad[0]);
-			switch (from->si_code >> 16) {
-			case __SI_FAULT >> 16:
-				break;
-			case __SI_SYS >> 16:
-				put_user_ex(from->si_syscall, &to->si_syscall);
-				put_user_ex(from->si_arch, &to->si_arch);
-				break;
-			case __SI_CHLD >> 16:
-				if (ia32) {
-					put_user_ex(from->si_utime, &to->si_utime);
-					put_user_ex(from->si_stime, &to->si_stime);
-				} else {
-					put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
-					put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
-				}
-				put_user_ex(from->si_status, &to->si_status);
-				/* FALL THROUGH */
-			default:
-			case __SI_KILL >> 16:
-				put_user_ex(from->si_uid, &to->si_uid);
-				break;
-			case __SI_POLL >> 16:
-				put_user_ex(from->si_fd, &to->si_fd);
-				break;
-			case __SI_TIMER >> 16:
-				put_user_ex(from->si_overrun, &to->si_overrun);
-				put_user_ex(ptr_to_compat(from->si_ptr),
-					    &to->si_ptr);
-				break;
-				 /* This is not generated by the kernel as of now.  */
-			case __SI_RT >> 16:
-			case __SI_MESGQ >> 16:
-				put_user_ex(from->si_uid, &to->si_uid);
-				put_user_ex(from->si_int, &to->si_int);
-				break;
-			}
-		}
-	} put_user_catch(err);
-
-	return err;
-}
-
-int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
-{
-	int err = 0;
-	u32 ptr32;
-
-	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
-		return -EFAULT;
-
-	get_user_try {
-		get_user_ex(to->si_signo, &from->si_signo);
-		get_user_ex(to->si_errno, &from->si_errno);
-		get_user_ex(to->si_code, &from->si_code);
-
-		get_user_ex(to->si_pid, &from->si_pid);
-		get_user_ex(to->si_uid, &from->si_uid);
-		get_user_ex(ptr32, &from->si_ptr);
-		to->si_ptr = compat_ptr(ptr32);
-	} get_user_catch(err);
-
-	return err;
-}
-
 /*
  * Do a signal return; undo the signal stack.
  */
arch/x86/kernel/Makefile +1 -0
index 0f15af4..dc19730 100644
@@ -23,6 +23,7 @@ KASAN_SANITIZE_dumpstack_$(BITS).o := n
 CFLAGS_irq.o := -I$(src)/../include/asm/trace
 
 obj-y			:= process_$(BITS).o signal.o
+obj-$(CONFIG_COMPAT)	+= signal_compat.o
 obj-y			+= traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y			+= time.o ioport.o ldt.o dumpstack.o nmi.o
 obj-y			+= setup.o x86_init.o i8259.o irqinit.o jump_label.o
arch/x86/kernel/signal_compat.c new file +95 -0

95 lines not on this page · raw message

#3 lore raw

PATCH 2/12 x86/compat: Make mmap_is_ia32() common compat

In reply to Brian Gerst

TIF_ADDR32 is set for both ia32 and x32 tasks, so change from CONFIG_IA32_EMULATION to CONFIG_COMPAT. Use config_enabled() to make the function more readable.

---
 arch/x86/include/asm/elf.h | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
arch/x86/include/asm/elf.h +3 -8
index f161c18..180b6fe 100644
@@ -344,14 +344,9 @@ extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
  */
 static inline int mmap_is_ia32(void)
 {
-#ifdef CONFIG_X86_32
-	return 1;
-#endif
-#ifdef CONFIG_IA32_EMULATION
-	if (test_thread_flag(TIF_ADDR32))
-		return 1;
-#endif
-	return 0;
+	return config_enabled(CONFIG_X86_32) ||
+	       (config_enabled(CONFIG_COMPAT) &&
+		test_thread_flag(TIF_ADDR32));
 }
 
 /* Do not change the values. See get_align_mask() */
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#4 lore raw

[tip:x86/asm] x86/compat: Make mmap_is_ia32() common compat

x86/compat: Make mmap_is_ia32() common compat
Commit-ID:  b2e02b820d5b42479195b89d3d73f31bcedb264e
Gitweb:     http://git.kernel.org/tip/b2e02b820d5b42479195b89d3d73f31bcedb264e
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:11 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:55 +0200

x86/compat: Make mmap_is_ia32() common compat

TIF_ADDR32 is set for both ia32 and x32 tasks, so change from CONFIG_IA32_EMULATION to CONFIG_COMPAT. Use config_enabled() to make the function more readable.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/include/asm/elf.h | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
arch/x86/include/asm/elf.h +3 -8
index f161c18..180b6fe 100644
@@ -344,14 +344,9 @@ extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
  */
 static inline int mmap_is_ia32(void)
 {
-#ifdef CONFIG_X86_32
-	return 1;
-#endif
-#ifdef CONFIG_IA32_EMULATION
-	if (test_thread_flag(TIF_ADDR32))
-		return 1;
-#endif
-	return 0;
+	return config_enabled(CONFIG_X86_32) ||
+	       (config_enabled(CONFIG_COMPAT) &&
+		test_thread_flag(TIF_ADDR32));
 }
 
 /* Do not change the values. See get_align_mask() */
#5 lore raw

PATCH 3/12 x86/compat: Move ucontext_x32 to sigframe.h

In reply to Brian Gerst

ia32.h should only contain the code for 32-bit compatability.

---
 arch/x86/include/asm/ia32.h     |  9 ---------
 arch/x86/include/asm/sigframe.h | 10 ++++++++++
 2 files changed, 10 insertions(+), 9 deletions(-)
arch/x86/include/asm/ia32.h +0 -9
index d0e8e01..2801976 100644
@@ -22,15 +22,6 @@ struct ucontext_ia32 {
 	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
-struct ucontext_x32 {
-	unsigned int	  uc_flags;
-	unsigned int 	  uc_link;
-	compat_stack_t	  uc_stack;
-	unsigned int	  uc__pad0;     /* needed for alignment */
-	struct sigcontext uc_mcontext;  /* the 64-bit sigcontext type */
-	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
 /* This matches struct stat64 in glibc2.2, hence the absolutely
  * insane amounts of padding around dev_t's.
  */
arch/x86/include/asm/sigframe.h +10 -0
index 7c7c27c..1f3175b 100644
@@ -4,6 +4,7 @@
 #include <asm/sigcontext.h>
 #include <asm/siginfo.h>
 #include <asm/ucontext.h>
+#include <linux/compat.h>
 
 #ifdef CONFIG_X86_32
 #define sigframe_ia32		sigframe
@@ -69,6 +70,15 @@ struct rt_sigframe {
 
 #ifdef CONFIG_X86_X32_ABI
 
+struct ucontext_x32 {
+	unsigned int	  uc_flags;
+	unsigned int 	  uc_link;
+	compat_stack_t	  uc_stack;
+	unsigned int	  uc__pad0;     /* needed for alignment */
+	struct sigcontext uc_mcontext;  /* the 64-bit sigcontext type */
+	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
 struct rt_sigframe_x32 {
 	u64 pretcode;
 	struct ucontext_x32 uc;
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#6 lore raw

[tip:x86/asm] x86/compat: Move ucontext_x32 to sigframe.h

x86/compat: Move ucontext_x32 to sigframe.h
Commit-ID:  b829d1be20ab51a3b76ec003118c9260d1fa424e
Gitweb:     http://git.kernel.org/tip/b829d1be20ab51a3b76ec003118c9260d1fa424e
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:12 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:55 +0200

x86/compat: Move ucontext_x32 to sigframe.h

ia32.h should only contain the code for 32-bit compatability.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/include/asm/ia32.h     |  9 ---------
 arch/x86/include/asm/sigframe.h | 10 ++++++++++
 2 files changed, 10 insertions(+), 9 deletions(-)
arch/x86/include/asm/ia32.h +0 -9
index d0e8e01..2801976 100644
@@ -22,15 +22,6 @@ struct ucontext_ia32 {
 	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
-struct ucontext_x32 {
-	unsigned int	  uc_flags;
-	unsigned int 	  uc_link;
-	compat_stack_t	  uc_stack;
-	unsigned int	  uc__pad0;     /* needed for alignment */
-	struct sigcontext uc_mcontext;  /* the 64-bit sigcontext type */
-	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
 /* This matches struct stat64 in glibc2.2, hence the absolutely
  * insane amounts of padding around dev_t's.
  */
arch/x86/include/asm/sigframe.h +10 -0
index 7c7c27c..1f3175b 100644
@@ -4,6 +4,7 @@
 #include <asm/sigcontext.h>
 #include <asm/siginfo.h>
 #include <asm/ucontext.h>
+#include <linux/compat.h>
 
 #ifdef CONFIG_X86_32
 #define sigframe_ia32		sigframe
@@ -69,6 +70,15 @@ struct rt_sigframe {
 
 #ifdef CONFIG_X86_X32_ABI
 
+struct ucontext_x32 {
+	unsigned int	  uc_flags;
+	unsigned int 	  uc_link;
+	compat_stack_t	  uc_stack;
+	unsigned int	  uc__pad0;     /* needed for alignment */
+	struct sigcontext uc_mcontext;  /* the 64-bit sigcontext type */
+	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
 struct rt_sigframe_x32 {
 	u64 pretcode;
 	struct ucontext_x32 uc;
#7 lore raw

PATCH 4/12 x86/compat: Rename start_thread_ia32 to compat_start_thread

In reply to Brian Gerst

This function is shared between the 32-bit compat and x32 ABIs.

---
 arch/x86/include/asm/elf.h   | 4 ++--
 arch/x86/kernel/process_64.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/elf.h +2 -2
index 180b6fe..2bf67c0 100644
@@ -187,8 +187,8 @@ static inline void elf_common_init(struct thread_struct *t,
 #define	COMPAT_ELF_PLAT_INIT(regs, load_addr)		\
 	elf_common_init(&current->thread, regs, __USER_DS)
 
-void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp);
-#define compat_start_thread start_thread_ia32
+void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp);
+#define compat_start_thread compat_start_thread
 
 void set_personality_ia32(bool);
 #define COMPAT_SET_PERSONALITY(ex)			\
arch/x86/kernel/process_64.c +2 -2
index 843f92e..69c6f7a 100644
@@ -248,8 +248,8 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
 			    __USER_CS, __USER_DS, 0);
 }
 
-#ifdef CONFIG_IA32_EMULATION
-void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp)
+#ifdef CONFIG_COMPAT
+void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp)
 {
 	start_thread_common(regs, new_ip, new_sp,
 			    test_thread_flag(TIF_X32)
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#8 lore raw

[tip:x86/asm] x86/compat: Rename 'start_thread_ia32' to ' compat_start_thread'

x86/compat: Rename 'start_thread_ia32' to 'compat_start_thread'
Commit-ID:  7da770785f9740af1cb24b8fd63075543bd00711
Gitweb:     http://git.kernel.org/tip/7da770785f9740af1cb24b8fd63075543bd00711
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:13 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:56 +0200

x86/compat: Rename 'start_thread_ia32' to 'compat_start_thread'

This function is shared between the 32-bit compat and x32 ABIs.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/include/asm/elf.h   | 4 ++--
 arch/x86/kernel/process_64.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/elf.h +2 -2
index 180b6fe..2bf67c0 100644
@@ -187,8 +187,8 @@ static inline void elf_common_init(struct thread_struct *t,
 #define	COMPAT_ELF_PLAT_INIT(regs, load_addr)		\
 	elf_common_init(&current->thread, regs, __USER_DS)
 
-void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp);
-#define compat_start_thread start_thread_ia32
+void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp);
+#define compat_start_thread compat_start_thread
 
 void set_personality_ia32(bool);
 #define COMPAT_SET_PERSONALITY(ex)			\
arch/x86/kernel/process_64.c +2 -2
index 71d7849..0831ba3 100644
@@ -248,8 +248,8 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
 			    __USER_CS, __USER_DS, 0);
 }
 
-#ifdef CONFIG_IA32_EMULATION
-void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp)
+#ifdef CONFIG_COMPAT
+void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp)
 {
 	start_thread_common(regs, new_ip, new_sp,
 			    test_thread_flag(TIF_X32)
#9 lore raw

PATCH 5/12 x86/compat: Move ia32 compat code from compat_arch_ptrace()

In reply to Brian Gerst

Move the ia32-specific code in compat_arch_ptrace() into its own function.

---
 arch/x86/kernel/ptrace.c | 138 +++++++++++++++++++++++++----------------------
 1 file changed, 74 insertions(+), 64 deletions(-)
arch/x86/kernel/ptrace.c +74 -64
index 9be72bc..7155957 100644
@@ -1123,6 +1123,73 @@ static int genregs32_set(struct task_struct *target,
 	return ret;
 }
 
+static long ia32_arch_ptrace(struct task_struct *child, compat_long_t request,
+			     compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	unsigned long addr = caddr;
+	unsigned long data = cdata;
+	void __user *datap = compat_ptr(data);
+	int ret;
+	__u32 val;
+
+	switch (request) {
+	case PTRACE_PEEKUSR:
+		ret = getreg32(child, addr, &val);
+		if (ret == 0)
+			ret = put_user(val, (__u32 __user *)datap);
+		break;
+
+	case PTRACE_POKEUSR:
+		ret = putreg32(child, addr, data);
+		break;
+
+	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
+		return copy_regset_to_user(child, &user_x86_32_view,
+					   REGSET_GENERAL,
+					   0, sizeof(struct user_regs_struct32),
+					   datap);
+
+	case PTRACE_SETREGS:	/* Set all gp regs in the child. */
+		return copy_regset_from_user(child, &user_x86_32_view,
+					     REGSET_GENERAL, 0,
+					     sizeof(struct user_regs_struct32),
+					     datap);
+
+	case PTRACE_GETFPREGS:	/* Get the child FPU state. */
+		return copy_regset_to_user(child, &user_x86_32_view,
+					   REGSET_FP, 0,
+					   sizeof(struct user_i387_ia32_struct),
+					   datap);
+
+	case PTRACE_SETFPREGS:	/* Set the child FPU state. */
+		return copy_regset_from_user(
+			child, &user_x86_32_view, REGSET_FP,
+			0, sizeof(struct user_i387_ia32_struct), datap);
+
+	case PTRACE_GETFPXREGS:	/* Get the child extended FPU state. */
+		return copy_regset_to_user(child, &user_x86_32_view,
+					   REGSET_XFP, 0,
+					   sizeof(struct user32_fxsr_struct),
+					   datap);
+
+	case PTRACE_SETFPXREGS:	/* Set the child extended FPU state. */
+		return copy_regset_from_user(child, &user_x86_32_view,
+					     REGSET_XFP, 0,
+					     sizeof(struct user32_fxsr_struct),
+					     datap);
+
+	case PTRACE_GET_THREAD_AREA:
+	case PTRACE_SET_THREAD_AREA:
+		return arch_ptrace(child, request, addr, data);
+
+	default:
+		return compat_ptrace_request(child, request, addr, data);
+	}
+
+	return ret;
+}
+#endif /* CONFIG_IA32_EMULATION */
+
 #ifdef CONFIG_X86_X32_ABI
 static long x32_arch_ptrace(struct task_struct *child,
 			    compat_long_t request, compat_ulong_t caddr,
@@ -1211,78 +1278,21 @@ static long x32_arch_ptrace(struct task_struct *child,
 }
 #endif
 
+#ifdef CONFIG_COMPAT
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
 {
-	unsigned long addr = caddr;
-	unsigned long data = cdata;
-	void __user *datap = compat_ptr(data);
-	int ret;
-	__u32 val;
-
 #ifdef CONFIG_X86_X32_ABI
 	if (!is_ia32_task())
 		return x32_arch_ptrace(child, request, caddr, cdata);
 #endif
-
-	switch (request) {
-	case PTRACE_PEEKUSR:
-		ret = getreg32(child, addr, &val);
-		if (ret == 0)
-			ret = put_user(val, (__u32 __user *)datap);
-		break;
-
-	case PTRACE_POKEUSR:
-		ret = putreg32(child, addr, data);
-		break;
-
-	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
-		return copy_regset_to_user(child, &user_x86_32_view,
-					   REGSET_GENERAL,
-					   0, sizeof(struct user_regs_struct32),
-					   datap);
-
-	case PTRACE_SETREGS:	/* Set all gp regs in the child. */
-		return copy_regset_from_user(child, &user_x86_32_view,
-					     REGSET_GENERAL, 0,
-					     sizeof(struct user_regs_struct32),
-					     datap);
-
-	case PTRACE_GETFPREGS:	/* Get the child FPU state. */
-		return copy_regset_to_user(child, &user_x86_32_view,
-					   REGSET_FP, 0,
-					   sizeof(struct user_i387_ia32_struct),
-					   datap);
-
-	case PTRACE_SETFPREGS:	/* Set the child FPU state. */
-		return copy_regset_from_user(
-			child, &user_x86_32_view, REGSET_FP,
-			0, sizeof(struct user_i387_ia32_struct), datap);
-
-	case PTRACE_GETFPXREGS:	/* Get the child extended FPU state. */
-		return copy_regset_to_user(child, &user_x86_32_view,
-					   REGSET_XFP, 0,
-					   sizeof(struct user32_fxsr_struct),
-					   datap);
-
-	case PTRACE_SETFPXREGS:	/* Set the child extended FPU state. */
-		return copy_regset_from_user(child, &user_x86_32_view,
-					     REGSET_XFP, 0,
-					     sizeof(struct user32_fxsr_struct),
-					     datap);
-
-	case PTRACE_GET_THREAD_AREA:
-	case PTRACE_SET_THREAD_AREA:
-		return arch_ptrace(child, request, addr, data);
-
-	default:
-		return compat_ptrace_request(child, request, addr, data);
-	}
-
-	return ret;
+#ifdef CONFIG_IA32_EMULATION
+	return ia32_arch_ptrace(child, request, caddr, cdata);
+#else
+	return 0;
+#endif
 }
-
-#endif	/* CONFIG_IA32_EMULATION */
+#endif	/* CONFIG_COMPAT */
 
 #ifdef CONFIG_X86_64
 
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#10 lore raw

[tip:x86/asm] x86/compat: Factor out ia32 compat code from compat_arch_ptrace()

x86/compat: Factor out ia32 compat code from compat_arch_ptrace()
Commit-ID:  601275c3e04c43b3b34237ab36c27fc1cfb8a189
Gitweb:     http://git.kernel.org/tip/601275c3e04c43b3b34237ab36c27fc1cfb8a189
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:14 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:56 +0200

x86/compat: Factor out ia32 compat code from compat_arch_ptrace()

Move the ia32-specific code in compat_arch_ptrace() into its own function.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/kernel/ptrace.c | 138 +++++++++++++++++++++++++----------------------
 1 file changed, 74 insertions(+), 64 deletions(-)
arch/x86/kernel/ptrace.c +74 -64
index 9be72bc..7155957 100644
@@ -1123,6 +1123,73 @@ static int genregs32_set(struct task_struct *target,
 	return ret;
 }
 
+static long ia32_arch_ptrace(struct task_struct *child, compat_long_t request,
+			     compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	unsigned long addr = caddr;
+	unsigned long data = cdata;
+	void __user *datap = compat_ptr(data);
+	int ret;
+	__u32 val;
+
+	switch (request) {
+	case PTRACE_PEEKUSR:
+		ret = getreg32(child, addr, &val);
+		if (ret == 0)
+			ret = put_user(val, (__u32 __user *)datap);
+		break;
+
+	case PTRACE_POKEUSR:
+		ret = putreg32(child, addr, data);
+		break;
+
+	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
+		return copy_regset_to_user(child, &user_x86_32_view,
+					   REGSET_GENERAL,
+					   0, sizeof(struct user_regs_struct32),
+					   datap);
+
+	case PTRACE_SETREGS:	/* Set all gp regs in the child. */
+		return copy_regset_from_user(child, &user_x86_32_view,
+					     REGSET_GENERAL, 0,
+					     sizeof(struct user_regs_struct32),
+					     datap);
+
+	case PTRACE_GETFPREGS:	/* Get the child FPU state. */
+		return copy_regset_to_user(child, &user_x86_32_view,
+					   REGSET_FP, 0,
+					   sizeof(struct user_i387_ia32_struct),
+					   datap);
+
+	case PTRACE_SETFPREGS:	/* Set the child FPU state. */
+		return copy_regset_from_user(
+			child, &user_x86_32_view, REGSET_FP,
+			0, sizeof(struct user_i387_ia32_struct), datap);
+
+	case PTRACE_GETFPXREGS:	/* Get the child extended FPU state. */
+		return copy_regset_to_user(child, &user_x86_32_view,
+					   REGSET_XFP, 0,
+					   sizeof(struct user32_fxsr_struct),
+					   datap);
+
+	case PTRACE_SETFPXREGS:	/* Set the child extended FPU state. */
+		return copy_regset_from_user(child, &user_x86_32_view,
+					     REGSET_XFP, 0,
+					     sizeof(struct user32_fxsr_struct),
+					     datap);
+
+	case PTRACE_GET_THREAD_AREA:
+	case PTRACE_SET_THREAD_AREA:
+		return arch_ptrace(child, request, addr, data);
+
+	default:
+		return compat_ptrace_request(child, request, addr, data);
+	}
+
+	return ret;
+}
+#endif /* CONFIG_IA32_EMULATION */
+
 #ifdef CONFIG_X86_X32_ABI
 static long x32_arch_ptrace(struct task_struct *child,
 			    compat_long_t request, compat_ulong_t caddr,
@@ -1211,78 +1278,21 @@ static long x32_arch_ptrace(struct task_struct *child,
 }
 #endif
 
+#ifdef CONFIG_COMPAT
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
 {
-	unsigned long addr = caddr;
-	unsigned long data = cdata;
-	void __user *datap = compat_ptr(data);
-	int ret;
-	__u32 val;
-
 #ifdef CONFIG_X86_X32_ABI
 	if (!is_ia32_task())
 		return x32_arch_ptrace(child, request, caddr, cdata);
 #endif
-
-	switch (request) {
-	case PTRACE_PEEKUSR:
-		ret = getreg32(child, addr, &val);
-		if (ret == 0)
-			ret = put_user(val, (__u32 __user *)datap);
-		break;
-
-	case PTRACE_POKEUSR:
-		ret = putreg32(child, addr, data);
-		break;
-
-	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
-		return copy_regset_to_user(child, &user_x86_32_view,
-					   REGSET_GENERAL,
-					   0, sizeof(struct user_regs_struct32),
-					   datap);
-
-	case PTRACE_SETREGS:	/* Set all gp regs in the child. */
-		return copy_regset_from_user(child, &user_x86_32_view,
-					     REGSET_GENERAL, 0,
-					     sizeof(struct user_regs_struct32),
-					     datap);
-
-	case PTRACE_GETFPREGS:	/* Get the child FPU state. */
-		return copy_regset_to_user(child, &user_x86_32_view,
-					   REGSET_FP, 0,
-					   sizeof(struct user_i387_ia32_struct),
-					   datap);
-
-	case PTRACE_SETFPREGS:	/* Set the child FPU state. */
-		return copy_regset_from_user(
-			child, &user_x86_32_view, REGSET_FP,
-			0, sizeof(struct user_i387_ia32_struct), datap);
-
-	case PTRACE_GETFPXREGS:	/* Get the child extended FPU state. */
-		return copy_regset_to_user(child, &user_x86_32_view,
-					   REGSET_XFP, 0,
-					   sizeof(struct user32_fxsr_struct),
-					   datap);
-
-	case PTRACE_SETFPXREGS:	/* Set the child extended FPU state. */
-		return copy_regset_from_user(child, &user_x86_32_view,
-					     REGSET_XFP, 0,
-					     sizeof(struct user32_fxsr_struct),
-					     datap);
-
-	case PTRACE_GET_THREAD_AREA:
-	case PTRACE_SET_THREAD_AREA:
-		return arch_ptrace(child, request, addr, data);
-
-	default:
-		return compat_ptrace_request(child, request, addr, data);
-	}
-
-	return ret;
+#ifdef CONFIG_IA32_EMULATION
+	return ia32_arch_ptrace(child, request, caddr, cdata);
+#else
+	return 0;
+#endif
 }
-
-#endif	/* CONFIG_IA32_EMULATION */
+#endif	/* CONFIG_COMPAT */
 
 #ifdef CONFIG_X86_64
 
#11 lore raw

PATCH 6/12 x86/compat: Don't build 32-bit vdso if not needed.

In reply to Brian Gerst

Build the 32-bit vdso only for native 32-bit or 32-bit compat is enabled. x32 should not force it to build.

---
 arch/x86/entry/vdso/Makefile | 6 +++---
 arch/x86/entry/vdso/vma.c    | 7 +++++--
 arch/x86/include/asm/elf.h   | 2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)
arch/x86/entry/vdso/Makefile +3 -3
index e970320..96c0617 100644
@@ -8,7 +8,7 @@ KASAN_SANITIZE := n
 VDSO64-$(CONFIG_X86_64)		:= y
 VDSOX32-$(CONFIG_X86_X32_ABI)	:= y
 VDSO32-$(CONFIG_X86_32)		:= y
-VDSO32-$(CONFIG_COMPAT)		:= y
+VDSO32-$(CONFIG_IA32_EMULATION)	:= y
 
 # files to link into the vdso
 vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
@@ -20,7 +20,7 @@ obj-y				+= vma.o
 vdso_img-$(VDSO64-y)		+= 64
 vdso_img-$(VDSOX32-y)		+= x32
 vdso_img-$(VDSO32-y)		+= 32-int80
-vdso_img-$(CONFIG_COMPAT)	+= 32-syscall
+vdso_img-$(CONFIG_IA32_EMULATION)	+= 32-syscall
 vdso_img-$(VDSO32-y)		+= 32-sysenter
 
 obj-$(VDSO32-y)			+= vdso32-setup.o
@@ -126,7 +126,7 @@ $(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
 # Build multiple 32-bit vDSO images to choose from at boot time.
 #
 vdso32.so-$(VDSO32-y)		+= int80
-vdso32.so-$(CONFIG_COMPAT)	+= syscall
+vdso32.so-$(CONFIG_IA32_EMULATION)	+= syscall
 vdso32.so-$(VDSO32-y)		+= sysenter
 
 vdso32-images			= $(vdso32.so-y:%=vdso32-%.so)
arch/x86/entry/vdso/vma.c +5 -2
index 1c9f750..4345431 100644
@@ -177,7 +177,7 @@ up_fail:
 	return ret;
 }
 
-#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
+#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
 static int load_vdso32(void)
 {
 	int ret;
@@ -219,8 +219,11 @@ int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
 		return map_vdso(&vdso_image_x32, true);
 	}
 #endif
-
+#ifdef CONFIG_IA32_EMULATION
 	return load_vdso32();
+#else
+	return 0;
+#endif
 }
 #endif
 #else
arch/x86/include/asm/elf.h +1 -1
index 2bf67c0..141c561 100644
@@ -78,7 +78,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
 #ifdef CONFIG_X86_64
 extern unsigned int vdso64_enabled;
 #endif
-#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
+#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
 extern unsigned int vdso32_enabled;
 #endif
 
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#12 lore raw

[tip:x86/asm] x86/compat: Don' t build the 32-bit VDSO if not needed

x86/compat: Don't build the 32-bit VDSO if not needed
Commit-ID:  ab8b82ee6dad7c9c257f450d14719a0e3f327244
Gitweb:     http://git.kernel.org/tip/ab8b82ee6dad7c9c257f450d14719a0e3f327244
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:15 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:56 +0200

x86/compat: Don't build the 32-bit VDSO if not needed

Build the 32-bit vdso only for native 32-bit or 32-bit compat is enabled. x32 should not force it to build.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/entry/vdso/Makefile | 6 +++---
 arch/x86/entry/vdso/vma.c    | 7 +++++--
 arch/x86/include/asm/elf.h   | 2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)
arch/x86/entry/vdso/Makefile +3 -3
index e970320..96c0617 100644
@@ -8,7 +8,7 @@ KASAN_SANITIZE := n
 VDSO64-$(CONFIG_X86_64)		:= y
 VDSOX32-$(CONFIG_X86_X32_ABI)	:= y
 VDSO32-$(CONFIG_X86_32)		:= y
-VDSO32-$(CONFIG_COMPAT)		:= y
+VDSO32-$(CONFIG_IA32_EMULATION)	:= y
 
 # files to link into the vdso
 vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
@@ -20,7 +20,7 @@ obj-y				+= vma.o
 vdso_img-$(VDSO64-y)		+= 64
 vdso_img-$(VDSOX32-y)		+= x32
 vdso_img-$(VDSO32-y)		+= 32-int80
-vdso_img-$(CONFIG_COMPAT)	+= 32-syscall
+vdso_img-$(CONFIG_IA32_EMULATION)	+= 32-syscall
 vdso_img-$(VDSO32-y)		+= 32-sysenter
 
 obj-$(VDSO32-y)			+= vdso32-setup.o
@@ -126,7 +126,7 @@ $(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
 # Build multiple 32-bit vDSO images to choose from at boot time.
 #
 vdso32.so-$(VDSO32-y)		+= int80
-vdso32.so-$(CONFIG_COMPAT)	+= syscall
+vdso32.so-$(CONFIG_IA32_EMULATION)	+= syscall
 vdso32.so-$(VDSO32-y)		+= sysenter
 
 vdso32-images			= $(vdso32.so-y:%=vdso32-%.so)
arch/x86/entry/vdso/vma.c +5 -2
index 1c9f750..4345431 100644
@@ -177,7 +177,7 @@ up_fail:
 	return ret;
 }
 
-#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
+#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
 static int load_vdso32(void)
 {
 	int ret;
@@ -219,8 +219,11 @@ int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
 		return map_vdso(&vdso_image_x32, true);
 	}
 #endif
-
+#ifdef CONFIG_IA32_EMULATION
 	return load_vdso32();
+#else
+	return 0;
+#endif
 }
 #endif
 #else
arch/x86/include/asm/elf.h +1 -1
index 2bf67c0..141c561 100644
@@ -78,7 +78,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
 #ifdef CONFIG_X86_64
 extern unsigned int vdso64_enabled;
 #endif
-#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
+#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
 extern unsigned int vdso32_enabled;
 #endif
 
#13 lore raw

PATCH 7/12 x86/compat: get_gate_vma should check for both 32-bit compat and x32

In reply to Brian Gerst

Change this to CONFIG_COMPAT so both 32-bit compat and x32 will do the check.

---
 arch/x86/entry/vsyscall/vsyscall_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/entry/vsyscall/vsyscall_64.c +1 -1
index 2dcc6ff..26a46f4 100644
@@ -290,7 +290,7 @@ static struct vm_area_struct gate_vma = {
 
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 {
-#ifdef CONFIG_IA32_EMULATION
+#ifdef CONFIG_COMPAT
 	if (!mm || mm->context.ia32_compat)
 		return NULL;
 #endif
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#14 lore raw

Re: [PATCH 07/12] x86/compat: get_gate_vma should check for both 32-bit compat and x32

Quoted 13 lines · Brian Gerst

Change this to CONFIG_COMPAT so both 32-bit compat and x32 will do the check.

---
 arch/x86/entry/vsyscall/vsyscall_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/entry/vsyscall/vsyscall_64.c +0 -0
index 2dcc6ff..26a46f4 100644

arch/x86/entry/vsyscall/vsyscall_64.c static struct vm_area_struct gate_vma = { · line 296

Quoted 8 lines
arch/x86/entry/vsyscall/vsyscall_64.c +1 -1
@@ -290,7 +290,7 @@ static struct vm_area_struct gate_vma = {
 
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 {
-#ifdef CONFIG_IA32_EMULATION
+#ifdef CONFIG_COMPAT
        if (!mm || mm->context.ia32_compat)
                return NULL;
 #endif

This makes little sense to me.

First, why is the !mm check guarded by any ifdef at all? If this said "if (mm && mm->...)", it would make no sense.

Second, and more importantly, what does mm->context.ia32_compat mean in the new less-nonsensical regime? The flag itself is defined in a way that makes no sense (it's either 0, TIF_X32, or TIF_IA32 -- presumably it should be an enum). There aren't a whole lot of things that care -- it's just this check and some uprobe thing. At some point, mpx will start caring, too. There's also TIF_ADDR32, which is similarly ridiculous (why isn't it part of mm->context?, and why does it exist at all).

I think that the questions we want to be able to answer are:

1. Is this mm intended to be addressable using 32 bits? If so, we should probably not show the vsyscall area in /proc/self/maps.

2. Is this mm's mpx context intended to be used by 32-bit userspace? (That's real 32 bit, not x32 -- x32 is certainly 64-bit as far as MPX is concerned.)

3. Is the current mmap call intended to return something in the low 32 bits? Presumably that should depend only on the mmap call's bitness (is_compat_task, etc, which we really need to rename to something like in_compat_syscall).

I find myself wondering whether there is any legitimate reason that TASK_SIZE isn't the same thing as TASK_SIZE_MAX...

Anyway, your patch is probably fine -- you're not actually making anything worse.

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in Please read the FAQ at http://www.tux.org/lkml/

#15 lore raw

Re: [PATCH 07/12] x86/compat: get_gate_vma should check for both 32-bit compat and x32

Quoted 52 lines · Andy Lutomirski
Quoted 13 lines · Brian Gerst

Change this to CONFIG_COMPAT so both 32-bit compat and x32 will do the check.

---
 arch/x86/entry/vsyscall/vsyscall_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/entry/vsyscall/vsyscall_64.c +0 -0
index 2dcc6ff..26a46f4 100644

arch/x86/entry/vsyscall/vsyscall_64.c static struct vm_area_struct gate_vma = { · line 296

Quoted 8 lines
arch/x86/entry/vsyscall/vsyscall_64.c +1 -1
@@ -290,7 +290,7 @@ static struct vm_area_struct gate_vma = {
 
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 {
-#ifdef CONFIG_IA32_EMULATION
+#ifdef CONFIG_COMPAT
        if (!mm || mm->context.ia32_compat)
                return NULL;
 #endif

This makes little sense to me.

First, why is the !mm check guarded by any ifdef at all? If this said "if (mm && mm->...)", it would make no sense.

Second, and more importantly, what does mm->context.ia32_compat mean in the new less-nonsensical regime? The flag itself is defined in a way that makes no sense (it's either 0, TIF_X32, or TIF_IA32 -- presumably it should be an enum). There aren't a whole lot of things that care -- it's just this check and some uprobe thing. At some point, mpx will start caring, too. There's also TIF_ADDR32, which is similarly ridiculous (why isn't it part of mm->context?, and why does it exist at all).

I think that the questions we want to be able to answer are:

1. Is this mm intended to be addressable using 32 bits? If so, we should probably not show the vsyscall area in /proc/self/maps.

2. Is this mm's mpx context intended to be used by 32-bit userspace? (That's real 32 bit, not x32 -- x32 is certainly 64-bit as far as MPX is concerned.)

3. Is the current mmap call intended to return something in the low 32 bits? Presumably that should depend only on the mmap call's bitness (is_compat_task, etc, which we really need to rename to something like in_compat_syscall).

Quoted 7 lines

I find myself wondering whether there is any legitimate reason that TASK_SIZE isn't the same thing as TASK_SIZE_MAX...

Anyway, your patch is probably fine -- you're not actually making anything worse.

--Andy

I agree there are more cleanups needed here. But that's probably a whole patch series in itself. This patch is intended to be no code change when X32 doesn't depend on 32-bit compat anymore.

--
Brian Gerst
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in Please read the FAQ at http://www.tux.org/lkml/

#16 lore raw

Re: [PATCH 07/12] x86/compat: get_gate_vma should check for both 32-bit compat and x32

Quoted 56 lines · Brian Gerst
Quoted 55 lines · Andy Lutomirski
Quoted 13 lines · Brian Gerst

Change this to CONFIG_COMPAT so both 32-bit compat and x32 will do the check.

---
 arch/x86/entry/vsyscall/vsyscall_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/entry/vsyscall/vsyscall_64.c +0 -0
index 2dcc6ff..26a46f4 100644

arch/x86/entry/vsyscall/vsyscall_64.c static struct vm_area_struct gate_vma = { · line 296

Quoted 8 lines
arch/x86/entry/vsyscall/vsyscall_64.c +1 -1
@@ -290,7 +290,7 @@ static struct vm_area_struct gate_vma = {
 
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 {
-#ifdef CONFIG_IA32_EMULATION
+#ifdef CONFIG_COMPAT
        if (!mm || mm->context.ia32_compat)
                return NULL;
 #endif

This makes little sense to me.

First, why is the !mm check guarded by any ifdef at all? If this said "if (mm && mm->...)", it would make no sense.

Second, and more importantly, what does mm->context.ia32_compat mean in the new less-nonsensical regime? The flag itself is defined in a way that makes no sense (it's either 0, TIF_X32, or TIF_IA32 -- presumably it should be an enum). There aren't a whole lot of things that care -- it's just this check and some uprobe thing. At some point, mpx will start caring, too. There's also TIF_ADDR32, which is similarly ridiculous (why isn't it part of mm->context?, and why does it exist at all).

I think that the questions we want to be able to answer are:

1. Is this mm intended to be addressable using 32 bits? If so, we should probably not show the vsyscall area in /proc/self/maps.

2. Is this mm's mpx context intended to be used by 32-bit userspace? (That's real 32 bit, not x32 -- x32 is certainly 64-bit as far as MPX is concerned.)

3. Is the current mmap call intended to return something in the low 32 bits? Presumably that should depend only on the mmap call's bitness (is_compat_task, etc, which we really need to rename to something like in_compat_syscall).

I find myself wondering whether there is any legitimate reason that TASK_SIZE isn't the same thing as TASK_SIZE_MAX...

Quoted 8 lines
Quoted 4 lines

Anyway, your patch is probably fine -- you're not actually making anything worse.

--Andy

I agree there are more cleanups needed here. But that's probably a whole patch series in itself. This patch is intended to be no code change when X32 doesn't depend on 32-bit compat anymore.

Fair enough.

Quoted 3 lines

--
Brian Gerst

Signature · 5 lines
Andy Lutomirski
AMA Capital Management, LLC
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#17 lore raw

[tip:x86/asm] x86/compat: Check for both 32-bit compat and x32 in get_gate_vma()

In reply to Brian Gerst
x86/compat: Check for both 32-bit compat and x32 in get_gate_vma()
Commit-ID:  c338867d0e4224771c68d0a7727289b86c23eccd
Gitweb:     http://git.kernel.org/tip/c338867d0e4224771c68d0a7727289b86c23eccd
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:16 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:57 +0200

x86/compat: Check for both 32-bit compat and x32 in get_gate_vma()

Change this to CONFIG_COMPAT so both 32-bit compat and x32 will do the check.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/entry/vsyscall/vsyscall_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/entry/vsyscall/vsyscall_64.c +1 -1
index 2dcc6ff..26a46f4 100644
@@ -290,7 +290,7 @@ static struct vm_area_struct gate_vma = {
 
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 {
-#ifdef CONFIG_IA32_EMULATION
+#ifdef CONFIG_COMPAT
 	if (!mm || mm->context.ia32_compat)
 		return NULL;
 #endif
#18 lore raw

PATCH 8/12 x86/compat/perf: perf_callchain_user32 is only for 32-bit compat

In reply to Brian Gerst

perf_callchain_user32() is not needed for x32.

---
 arch/x86/kernel/cpu/perf_event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/perf_event.c +1 -1
index 5801a14..1924fad 100644
@@ -2206,7 +2206,7 @@ static unsigned long get_segment_base(unsigned int segment)
 	return get_desc_base(desc + idx);
 }
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_IA32_EMULATION
 
 #include <asm/compat.h>
 
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#19 lore raw

[tip:x86/asm] x86/compat, x86/perf: Don' t build perf_callchain_user32() on x32

x86/compat, x86/perf: Don't build perf_callchain_user32() on x32
Commit-ID:  10ed34935e7e828ce4ce566647a2d6b8240e4dee
Gitweb:     http://git.kernel.org/tip/10ed34935e7e828ce4ce566647a2d6b8240e4dee
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:17 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:57 +0200

x86/compat, x86/perf: Don't build perf_callchain_user32() on x32

perf_callchain_user32() is not needed for x32.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/kernel/cpu/perf_event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/perf_event.c +1 -1
index 3658de4..641413d 100644
@@ -2196,7 +2196,7 @@ static unsigned long get_segment_base(unsigned int segment)
 	return get_desc_base(desc + idx);
 }
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_IA32_EMULATION
 
 #include <asm/compat.h>
 
#20 lore raw

PATCH 9/12 x86/compat: Remove unneeded include

In reply to Brian Gerst

Including sys_ia32.h is not needed in signal.c.

---
 arch/x86/kernel/signal.c | 1 -
 1 file changed, 1 deletion(-)
arch/x86/kernel/signal.c +0 -1
index 206996c..6c22aad 100644
@@ -35,7 +35,6 @@
 #ifdef CONFIG_X86_64
 #include <asm/proto.h>
 #include <asm/ia32_unistd.h>
-#include <asm/sys_ia32.h>
 #endif /* CONFIG_X86_64 */
 
 #include <asm/syscall.h>
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#21 lore raw

[tip:x86/asm] x86/compat: Remove unneeded #include

x86/compat: Remove unneeded #include
Commit-ID:  5e2aad2460bd38d0777052486893b32902efcdcd
Gitweb:     http://git.kernel.org/tip/5e2aad2460bd38d0777052486893b32902efcdcd
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:18 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:57 +0200

x86/compat: Remove unneeded #include

Including sys_ia32.h is not needed in signal.c.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/kernel/signal.c | 1 -
 1 file changed, 1 deletion(-)
arch/x86/kernel/signal.c +0 -1
index 206996c..6c22aad 100644
@@ -35,7 +35,6 @@
 #ifdef CONFIG_X86_64
 #include <asm/proto.h>
 #include <asm/ia32_unistd.h>
-#include <asm/sys_ia32.h>
 #endif /* CONFIG_X86_64 */
 
 #include <asm/syscall.h>
#22 lore raw

PATCH 10/12 x86/compat: define ARCH_WANT_OLD_COMPAT_IPC only for 32-bit compat

In reply to Brian Gerst

x32 does not need ARCH_WANT_OLD_COMPAT_IPC.

---
 arch/x86/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Kconfig +1 -1
index c4f27a8..94afa69 100644
@@ -2548,6 +2548,7 @@ config IA32_EMULATION
 	select BINFMT_ELF
 	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
+	select ARCH_WANT_OLD_COMPAT_IPC
 	---help---
 	  Include code to run legacy 32-bit programs under a
 	  64-bit kernel. You should likely turn this on, unless you're
@@ -2575,7 +2576,6 @@ config X86_X32
 config COMPAT
 	def_bool y
 	depends on IA32_EMULATION || X86_X32
-	select ARCH_WANT_OLD_COMPAT_IPC
 
 if COMPAT
 config COMPAT_FOR_U64_ALIGNMENT
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#23 lore raw

[tip:x86/asm] x86/compat: Define ARCH_WANT_OLD_COMPAT_IPC only for 32-bit compat

x86/compat: Define ARCH_WANT_OLD_COMPAT_IPC only for 32-bit compat
Commit-ID:  3bead553ab657d482c3fd6559a1fd7f024414a63
Gitweb:     http://git.kernel.org/tip/3bead553ab657d482c3fd6559a1fd7f024414a63
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:19 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:57 +0200

x86/compat: Define ARCH_WANT_OLD_COMPAT_IPC only for 32-bit compat

x32 does not need CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Kconfig +1 -1
index 55bced1..6e910ba 100644
@@ -2517,6 +2517,7 @@ config IA32_EMULATION
 	select BINFMT_ELF
 	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
+	select ARCH_WANT_OLD_COMPAT_IPC
 	---help---
 	  Include code to run legacy 32-bit programs under a
 	  64-bit kernel. You should likely turn this on, unless you're
@@ -2544,7 +2545,6 @@ config X86_X32
 config COMPAT
 	def_bool y
 	depends on IA32_EMULATION || X86_X32
-	select ARCH_WANT_OLD_COMPAT_IPC
 
 if COMPAT
 config COMPAT_FOR_U64_ALIGNMENT
#24 lore raw

PATCH 11/12 x86/compat: clean up HAVE_UID16 config

In reply to Brian Gerst

Merge the 32-bit compat config setting for HAVE_UID16 with the 32-bit native one.

---
 arch/x86/Kconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/x86/Kconfig +1 -2
index 94afa69..9236bed 100644
@@ -128,7 +128,7 @@ config X86
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_SYSCALL_TRACEPOINTS
-	select HAVE_UID16			if X86_32
+	select HAVE_UID16			if X86_32 || IA32_EMULATION
 	select HAVE_UNSTABLE_SCHED_CLOCK
 	select HAVE_USER_RETURN_NOTIFIER
 	select IRQ_FORCED_THREADING
@@ -2547,7 +2547,6 @@ config IA32_EMULATION
 	depends on X86_64
 	select BINFMT_ELF
 	select COMPAT_BINFMT_ELF
-	select HAVE_UID16
 	select ARCH_WANT_OLD_COMPAT_IPC
 	---help---
 	  Include code to run legacy 32-bit programs under a
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#25 lore raw

[tip:x86/asm] x86/compat: Clean up HAVE_UID16 config

x86/compat: Clean up HAVE_UID16 config
Commit-ID:  0c3619ea6756833e5c636c886cb55ca5b77f5d73
Gitweb:     http://git.kernel.org/tip/0c3619ea6756833e5c636c886cb55ca5b77f5d73
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:20 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:58 +0200

x86/compat: Clean up HAVE_UID16 config

Merge the 32-bit compat config setting for HAVE_UID16 with the 32-bit native one.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/Kconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/x86/Kconfig +1 -2
index 6e910ba..d823a33 100644
@@ -132,7 +132,7 @@ config X86
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_SYSCALL_TRACEPOINTS
-	select HAVE_UID16			if X86_32
+	select HAVE_UID16			if X86_32 || IA32_EMULATION
 	select HAVE_UNSTABLE_SCHED_CLOCK
 	select HAVE_USER_RETURN_NOTIFIER
 	select IRQ_FORCED_THREADING
@@ -2516,7 +2516,6 @@ config IA32_EMULATION
 	depends on X86_64
 	select BINFMT_ELF
 	select COMPAT_BINFMT_ELF
-	select HAVE_UID16
 	select ARCH_WANT_OLD_COMPAT_IPC
 	---help---
 	  Include code to run legacy 32-bit programs under a
#26 lore raw

PATCH 12/12 x86/compat: Separate ia32 and x32 compat ABIs

In reply to Brian Gerst

The x32 ABI is now independent of the ia32 compat ABI. Common code is now conditional on CONFIG_COMPAT, but unshared code like syscall entry, signal handling, and the VDSO are under separate config options.

---
 arch/x86/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Kconfig +1 -1
index 9236bed..70c1956 100644
@@ -2561,7 +2561,7 @@ config IA32_AOUT
 
 config X86_X32
 	bool "x32 ABI for 64-bit mode"
-	depends on X86_64 && IA32_EMULATION
+	depends on X86_64
 	---help---
 	  Include code to run binaries for the x32 native 32-bit ABI
 	  for 64-bit processors.  An x32 process gets access to the
Signature · 5 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/
#27 lore raw

[tip:x86/asm] x86/compat: Separate ia32 and x32 compat ABIs

x86/compat: Separate ia32 and x32 compat ABIs
Commit-ID:  9b54050bfe438d9e1108211d28cb0b995b1f347c
Gitweb:     http://git.kernel.org/tip/9b54050bfe438d9e1108211d28cb0b995b1f347c
Author:     Brian Gerst <[email protected]>
AuthorDate: Mon, 22 Jun 2015 07:55:21 -0400
Committer:  Ingo Molnar <[email protected]>
CommitDate: Mon, 6 Jul 2015 15:28:58 +0200

x86/compat: Separate ia32 and x32 compat ABIs

The x32 ABI is now independent of the ia32 compat ABI. Common code is now conditional on CONFIG_COMPAT, but unshared code like syscall entry, signal handling, and the VDSO are under separate config options.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Kconfig +1 -1
index d823a33..aa94fd0 100644
@@ -2530,7 +2530,7 @@ config IA32_AOUT
 
 config X86_X32
 	bool "x32 ABI for 64-bit mode"
-	depends on X86_64 && IA32_EMULATION
+	depends on X86_64
 	---help---
 	  Include code to run binaries for the x32 native 32-bit ABI
 	  for 64-bit processors.  An x32 process gets access to the