All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Berg <benjamin@sipsolutions.net>
To: linux-um@lists.infradead.org
Cc: Benjamin Berg <benjamin@sipsolutions.net>
Subject: [PATCH 11/27] um: Rely on PTRACE_SETREGSET to set FS/GS base registers
Date: Wed,  3 Mar 2021 16:55:07 +0100	[thread overview]
Message-ID: <20210303155523.124277-12-benjamin@sipsolutions.net> (raw)
In-Reply-To: <20210303155523.124277-1-benjamin@sipsolutions.net>

These registers are saved/restored together with the other general
registers using ptrace. In arch_set_tls we then just need to set the
register and it will be synced back normally.

Most of this logic was introduced in commit f355559cf7845 ("[PATCH] uml:
x86_64 thread fixes"). However, at least today we can rely on ptrace to
restore the base registers for us. As such, only the part of the patch
that tracks the FS register for use as thread local storage is actually
needed.

Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
---
 arch/um/include/shared/os.h    |  3 --
 arch/x86/um/asm/elf.h          |  4 +--
 arch/x86/um/asm/processor_64.h |  3 --
 arch/x86/um/os-Linux/Makefile  |  1 -
 arch/x86/um/os-Linux/prctl.c   | 12 -------
 arch/x86/um/syscalls_64.c      | 59 ++++++----------------------------
 arch/x86/um/tls_64.c           |  2 +-
 7 files changed, 13 insertions(+), 71 deletions(-)
 delete mode 100644 arch/x86/um/os-Linux/prctl.c

diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 13d86f94cf0f..9a543aa614bb 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -325,9 +325,6 @@ extern void sigio_broken(int fd);
 extern int __add_sigio_fd(int fd);
 extern int __ignore_sigio_fd(int fd);
 
-/* prctl.c */
-extern int os_arch_prctl(int pid, int option, unsigned long *arg2);
-
 /* tty.c */
 extern int get_pty(void);
 
diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h
index c907b20d4993..30eeb2e3404a 100644
--- a/arch/x86/um/asm/elf.h
+++ b/arch/x86/um/asm/elf.h
@@ -168,8 +168,8 @@ do {								\
 	(pr_reg)[18] = (_regs)->regs.gp[18];			\
 	(pr_reg)[19] = (_regs)->regs.gp[19];			\
 	(pr_reg)[20] = (_regs)->regs.gp[20];			\
-	(pr_reg)[21] = current->thread.arch.fs;			\
-	(pr_reg)[22] = 0;					\
+	(pr_reg)[21] = (_regs)->regs.gp[21];			\
+	(pr_reg)[22] = (_regs)->regs.gp[22];			\
 	(pr_reg)[23] = 0;					\
 	(pr_reg)[24] = 0;					\
 	(pr_reg)[25] = 0;					\
diff --git a/arch/x86/um/asm/processor_64.h b/arch/x86/um/asm/processor_64.h
index 1ef9c21877bc..f90159508936 100644
--- a/arch/x86/um/asm/processor_64.h
+++ b/arch/x86/um/asm/processor_64.h
@@ -10,13 +10,11 @@
 struct arch_thread {
         unsigned long debugregs[8];
         int debugregs_seq;
-        unsigned long fs;
         struct faultinfo faultinfo;
 };
 
 #define INIT_ARCH_THREAD { .debugregs  		= { [ 0 ... 7 ] = 0 }, \
 			   .debugregs_seq	= 0, \
-			   .fs			= 0, \
 			   .faultinfo		= { 0, 0, 0 } }
 
 #define STACKSLOTS_PER_LINE 4
@@ -28,7 +26,6 @@ static inline void arch_flush_thread(struct arch_thread *thread)
 static inline void arch_copy_thread(struct arch_thread *from,
                                     struct arch_thread *to)
 {
-	to->fs = from->fs;
 }
 
 #define current_sp() ({ void *sp; __asm__("movq %%rsp, %0" : "=r" (sp) : ); sp; })
diff --git a/arch/x86/um/os-Linux/Makefile b/arch/x86/um/os-Linux/Makefile
index 253bfb8cb702..2859bbf0f3db 100644
--- a/arch/x86/um/os-Linux/Makefile
+++ b/arch/x86/um/os-Linux/Makefile
@@ -6,7 +6,6 @@
 obj-y = registers.o task_size.o mcontext.o
 
 obj-$(CONFIG_X86_32) += tls.o
-obj-$(CONFIG_64BIT) += prctl.o
 
 USER_OBJS := $(obj-y)
 
diff --git a/arch/x86/um/os-Linux/prctl.c b/arch/x86/um/os-Linux/prctl.c
deleted file mode 100644
index 8431e87ac333..000000000000
--- a/arch/x86/um/os-Linux/prctl.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
- * Licensed under the GPL
- */
-
-#include <sys/ptrace.h>
-#include <asm/ptrace.h>
-
-int os_arch_prctl(int pid, int option, unsigned long *arg2)
-{
-	return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, option);
-}
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index 58f51667e2e4..5e89a509d225 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -15,60 +15,22 @@
 long arch_prctl(struct task_struct *task, int option,
 		unsigned long __user *arg2)
 {
-	unsigned long *ptr = arg2, tmp;
-	long ret;
-	int pid = task->mm->context.id.u.pid;
-
-	/*
-	 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
-	 * be safe), we need to call arch_prctl on the host because
-	 * setting %fs may result in something else happening (like a
-	 * GDT or thread.fs being set instead).  So, we let the host
-	 * fiddle the registers and thread struct and restore the
-	 * registers afterwards.
-	 *
-	 * So, the saved registers are stored to the process (this
-	 * needed because a stub may have been the last thing to run),
-	 * arch_prctl is run on the host, then the registers are read
-	 * back.
-	 */
-	switch (option) {
-	case ARCH_SET_FS:
-	case ARCH_SET_GS:
-		ret = restore_registers(pid, &current->thread.regs.regs);
-		if (ret)
-			return ret;
-		break;
-	case ARCH_GET_FS:
-	case ARCH_GET_GS:
-		/*
-		 * With these two, we read to a local pointer and
-		 * put_user it to the userspace pointer that we were
-		 * given.  If addr isn't valid (because it hasn't been
-		 * faulted in or is just bogus), we want put_user to
-		 * fault it in (or return -EFAULT) instead of having
-		 * the host return -EFAULT.
-		 */
-		ptr = &tmp;
-	}
-
-	ret = os_arch_prctl(pid, option, ptr);
-	if (ret)
-		return ret;
+	long ret = -EINVAL;
 
 	switch (option) {
 	case ARCH_SET_FS:
-		current->thread.arch.fs = (unsigned long) ptr;
-		ret = save_registers(pid, &current->thread.regs.regs);
+		current->thread.regs.regs.gp[FS_BASE / sizeof(unsigned long)] = (unsigned long) arg2;
+		ret = 0;
 		break;
 	case ARCH_SET_GS:
-		ret = save_registers(pid, &current->thread.regs.regs);
+		current->thread.regs.regs.gp[GS_BASE / sizeof(unsigned long)] = (unsigned long) arg2;
+		ret = 0;
 		break;
 	case ARCH_GET_FS:
-		ret = put_user(tmp, arg2);
+		ret = put_user(current->thread.regs.regs.gp[FS_BASE / sizeof(unsigned long)], arg2);
 		break;
 	case ARCH_GET_GS:
-		ret = put_user(tmp, arg2);
+		ret = put_user(current->thread.regs.regs.gp[GS_BASE / sizeof(unsigned long)], arg2);
 		break;
 	}
 
@@ -82,8 +44,7 @@ SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 
 void arch_switch_to(struct task_struct *to)
 {
-	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
-		return;
-
-	arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
+	/* Nothing needs to be done on x86_64.
+	 * The FS_BASE/GS_BASE registers are saved in the ptrace register set.
+	 */
 }
diff --git a/arch/x86/um/tls_64.c b/arch/x86/um/tls_64.c
index ebd3855d9b13..c51a613f6f5c 100644
--- a/arch/x86/um/tls_64.c
+++ b/arch/x86/um/tls_64.c
@@ -12,7 +12,7 @@ int arch_set_tls(struct task_struct *t, unsigned long tls)
 	 * If CLONE_SETTLS is set, we need to save the thread id
 	 * so it can be set during context switches.
 	 */
-	t->thread.arch.fs = tls;
+	t->thread.regs.regs.gp[FS_BASE / sizeof(unsigned long)] = tls;
 
 	return 0;
 }
-- 
2.29.2


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


  parent reply	other threads:[~2021-03-03 16:02 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-03 15:54 [PATCH 00/27] Implement SECCOMP based userland Benjamin Berg
2021-03-03 15:54 ` [PATCH 01/27] um: Switch printk calls to adhere to correct coding style Benjamin Berg
2021-03-03 15:54 ` [PATCH 02/27] um: Declare fix_range_common as a static function Benjamin Berg
2021-03-03 15:54 ` [PATCH 03/27] um: Drop support for hosts without SYSEMU_SINGLESTEP support Benjamin Berg
2021-06-19 20:17   ` Richard Weinberger
2021-06-20 12:05     ` Benjamin Berg
2021-03-03 15:55 ` [PATCH 04/27] um: Drop NULL check from start_userspace Benjamin Berg
2021-03-03 15:55 ` [PATCH 05/27] um: Make errors to stop ptraced child fatal during startup Benjamin Berg
2021-03-03 15:55 ` [PATCH 06/27] um: Don't use vfprintf() for os_info() Benjamin Berg
2021-03-03 15:55 ` [PATCH 07/27] um: Do not use printk in SIGWINCH helper thread Benjamin Berg
2021-03-03 15:55 ` [PATCH 08/27] um: Reap winch thread if it fails Benjamin Berg
2021-03-03 15:55 ` [PATCH 09/27] um: Do not use printk in userspace trampoline Benjamin Berg
2021-03-03 15:55 ` [PATCH 10/27] um: Always inline stub functions Benjamin Berg
2021-03-03 15:55 ` Benjamin Berg [this message]
2021-03-03 15:55 ` [PATCH 12/27] um: Remove unused register save/restore functions Benjamin Berg
2021-03-03 15:55 ` [PATCH 13/27] um: Mark 32bit syscall helpers as clobbering memory Benjamin Berg
2021-03-03 15:55 ` [PATCH 14/27] um: Create signal stack memory assignment in stub_data Benjamin Berg
2021-03-03 15:55 ` [PATCH 15/27] um: Add generic stub_syscall6 function Benjamin Berg
2021-03-03 15:55 ` [PATCH 16/27] um: Rework syscall handling Benjamin Berg
2021-03-03 15:55 ` [PATCH 17/27] um: Store full CSGSFS and SS register from mcontext Benjamin Berg
2021-03-03 15:55 ` [PATCH 18/27] um: Pass full mm_id to functions creating helper processes Benjamin Berg
2021-03-03 15:55 ` [PATCH 19/27] um: Move faultinfo extraction into userspace routine Benjamin Berg
2021-03-03 15:55 ` [PATCH 20/27] um: Use struct uml_pt_regs for copy_context_skas0 Benjamin Berg
2021-03-03 15:55 ` [PATCH 21/27] um: Add UML_SECCOMP configuration option Benjamin Berg
2021-03-03 15:55 ` [PATCH 22/27] um: Add stub side of SECCOMP/futex based process handling Benjamin Berg
2021-03-03 15:55 ` [PATCH 23/27] um: Add helper functions to get/set state for SECCOMP Benjamin Berg
2021-03-03 15:55 ` [PATCH 24/27] um: Add SECCOMP support detection and initialization Benjamin Berg
2021-03-03 15:55 ` [PATCH 25/27] um: Die if a child dies unexpectedly in seccomp mode Benjamin Berg
2021-03-03 15:55 ` [PATCH 26/27] um: Implement kernel side of SECCOMP based process handling Benjamin Berg
2021-03-03 15:55 ` [PATCH 27/27] um: Delay flushing syscalls until the thread is restarted Benjamin Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210303155523.124277-12-benjamin@sipsolutions.net \
    --to=benjamin@sipsolutions.net \
    --cc=linux-um@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.