summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-01-17 10:44:34 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-01-17 10:44:34 -0800
commit6cff79f4b90a42d73f039564f09fa5d59ec3d8ab (patch)
tree099dc35b21aac02b76094bd9c1551d46aea37467
parent0c6bc37255927cf2e2cfdd9dc9bd1eced9c166de (diff)
parent83aec96c631e0fa75cfe6d6a1b113a32151aaa88 (diff)
downloadlinux-6cff79f4b90a42d73f039564f09fa5d59ec3d8ab.tar.gz
linux-6cff79f4b90a42d73f039564f09fa5d59ec3d8ab.tar.bz2
linux-6cff79f4b90a42d73f039564f09fa5d59ec3d8ab.zip
Merge tag 'uml-for-linus-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux
Pull UML updates from Richard Weinberger: - Clang coverage support - Many cleanups from Benjamin Berg - Various minor fixes * tag 'uml-for-linus-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux: um: Mark 32bit syscall helpers as clobbering memory um: Remove unused register save/restore functions um: Rely on PTRACE_SETREGSET to set FS/GS base registers Documentation: kunit: Add clang UML coverage example arch: um: Add Clang coverage support um: time-travel: fix time corruption um: net: Fix return type of uml_net_start_xmit() um: Always inline stub functions um: Do not use printk in userspace trampoline um: Reap winch thread if it fails um: Do not use printk in SIGWINCH helper thread um: Don't use vfprintf() for os_info() um: Make errors to stop ptraced child fatal during startup um: Drop NULL check from start_userspace um: Drop support for hosts without SYSEMU_SINGLESTEP support um: document arch_futex_atomic_op_inuser um: mmu: remove stub_pages um: Fix naming clash between UML and scheduler um: virt-pci: fix platform map offset
-rw-r--r--Documentation/dev-tools/kunit/running_tips.rst11
-rw-r--r--arch/um/Makefile-skas5
-rw-r--r--arch/um/drivers/chan_user.c42
-rw-r--r--arch/um/drivers/line.c13
-rw-r--r--arch/um/drivers/net_kern.c2
-rw-r--r--arch/um/drivers/virt-pci.c2
-rw-r--r--arch/um/include/asm/mmu.h1
-rw-r--r--arch/um/include/asm/processor-generic.h1
-rw-r--r--arch/um/include/shared/kern_util.h5
-rw-r--r--arch/um/include/shared/os.h3
-rw-r--r--arch/um/include/shared/ptrace_user.h41
-rw-r--r--arch/um/include/shared/registers.h2
-rw-r--r--arch/um/kernel/process.c14
-rw-r--r--arch/um/kernel/ptrace.c2
-rw-r--r--arch/um/kernel/signal.c12
-rw-r--r--arch/um/kernel/skas/uaccess.c4
-rw-r--r--arch/um/kernel/time.c32
-rw-r--r--arch/um/os-Linux/helper.c6
-rw-r--r--arch/um/os-Linux/registers.c20
-rw-r--r--arch/um/os-Linux/skas/process.c117
-rw-r--r--arch/um/os-Linux/start_up.c111
-rw-r--r--arch/um/os-Linux/util.c19
-rw-r--r--arch/x86/um/asm/elf.h4
-rw-r--r--arch/x86/um/asm/processor_64.h3
-rw-r--r--arch/x86/um/os-Linux/Makefile1
-rw-r--r--arch/x86/um/os-Linux/prctl.c12
-rw-r--r--arch/x86/um/ptrace_32.c24
-rw-r--r--arch/x86/um/ptrace_64.c26
-rw-r--r--arch/x86/um/shared/sysdep/ptrace_32.h4
-rw-r--r--arch/x86/um/shared/sysdep/ptrace_user.h12
-rw-r--r--arch/x86/um/shared/sysdep/stub_32.h39
-rw-r--r--arch/x86/um/shared/sysdep/stub_64.h17
-rw-r--r--arch/x86/um/syscalls_64.c62
-rw-r--r--arch/x86/um/tls_64.c2
34 files changed, 212 insertions, 459 deletions
diff --git a/Documentation/dev-tools/kunit/running_tips.rst b/Documentation/dev-tools/kunit/running_tips.rst
index 024e9ad1d1e9..bd689db6fdd2 100644
--- a/Documentation/dev-tools/kunit/running_tips.rst
+++ b/Documentation/dev-tools/kunit/running_tips.rst
@@ -139,6 +139,17 @@ If your installed version of gcc doesn't work, you can tweak the steps:
$ ./tools/testing/kunit/kunit.py run --make_options=CC=/usr/bin/gcc-6
$ lcov -t "my_kunit_tests" -o coverage.info -c -d .kunit/ --gcov-tool=/usr/bin/gcov-6
+Alternatively, LLVM-based toolchains can also be used:
+
+.. code-block:: bash
+
+ # Build with LLVM and append coverage options to the current config
+ $ ./tools/testing/kunit/kunit.py run --make_options LLVM=1 --kunitconfig=.kunit/ --kunitconfig=tools/testing/kunit/configs/coverage_uml.config
+ $ llvm-profdata merge -sparse default.profraw -o default.profdata
+ $ llvm-cov export --format=lcov .kunit/vmlinux -instr-profile default.profdata > coverage.info
+ # The coverage.info file is in lcov-compatible format and it can be used to e.g. generate HTML report
+ $ genhtml -o /tmp/coverage_html coverage.info
+
Running tests manually
======================
diff --git a/arch/um/Makefile-skas b/arch/um/Makefile-skas
index ac35de5316a6..67323b028999 100644
--- a/arch/um/Makefile-skas
+++ b/arch/um/Makefile-skas
@@ -4,7 +4,12 @@
#
GPROF_OPT += -pg
+
+ifdef CONFIG_CC_IS_CLANG
+GCOV_OPT += -fprofile-instr-generate -fcoverage-mapping
+else
GCOV_OPT += -fprofile-arcs -ftest-coverage
+endif
CFLAGS-$(CONFIG_GCOV) += $(GCOV_OPT)
CFLAGS-$(CONFIG_GPROF) += $(GPROF_OPT)
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 25727ed648b7..ed7cc830b3e7 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -141,7 +141,7 @@ struct winch_data {
int pipe_fd;
};
-static int winch_thread(void *arg)
+static __noreturn int winch_thread(void *arg)
{
struct winch_data *data = arg;
sigset_t sigs;
@@ -153,8 +153,8 @@ static int winch_thread(void *arg)
pipe_fd = data->pipe_fd;
count = write(pipe_fd, &c, sizeof(c));
if (count != sizeof(c))
- printk(UM_KERN_ERR "winch_thread : failed to write "
- "synchronization byte, err = %d\n", -count);
+ os_info("winch_thread : failed to write synchronization byte, err = %d\n",
+ -count);
/*
* We are not using SIG_IGN on purpose, so don't fix it as I thought to
@@ -166,29 +166,29 @@ static int winch_thread(void *arg)
sigfillset(&sigs);
/* Block all signals possible. */
if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) {
- printk(UM_KERN_ERR "winch_thread : sigprocmask failed, "
- "errno = %d\n", errno);
- exit(1);
+ os_info("winch_thread : sigprocmask failed, errno = %d\n",
+ errno);
+ goto wait_kill;
}
/* In sigsuspend(), block anything else than SIGWINCH. */
sigdelset(&sigs, SIGWINCH);
if (setsid() < 0) {
- printk(UM_KERN_ERR "winch_thread : setsid failed, errno = %d\n",
+ os_info("winch_thread : setsid failed, errno = %d\n",
errno);
- exit(1);
+ goto wait_kill;
}
if (ioctl(pty_fd, TIOCSCTTY, 0) < 0) {
- printk(UM_KERN_ERR "winch_thread : TIOCSCTTY failed on "
- "fd %d err = %d\n", pty_fd, errno);
- exit(1);
+ os_info("winch_thread : TIOCSCTTY failed on "
+ "fd %d err = %d\n", pty_fd, errno);
+ goto wait_kill;
}
if (tcsetpgrp(pty_fd, os_getpid()) < 0) {
- printk(UM_KERN_ERR "winch_thread : tcsetpgrp failed on "
- "fd %d err = %d\n", pty_fd, errno);
- exit(1);
+ os_info("winch_thread : tcsetpgrp failed on fd %d err = %d\n",
+ pty_fd, errno);
+ goto wait_kill;
}
/*
@@ -199,8 +199,8 @@ static int winch_thread(void *arg)
*/
count = read(pipe_fd, &c, sizeof(c));
if (count != sizeof(c))
- printk(UM_KERN_ERR "winch_thread : failed to read "
- "synchronization byte, err = %d\n", errno);
+ os_info("winch_thread : failed to read synchronization byte, err = %d\n",
+ errno);
while(1) {
/*
@@ -211,9 +211,15 @@ static int winch_thread(void *arg)
count = write(pipe_fd, &c, sizeof(c));
if (count != sizeof(c))
- printk(UM_KERN_ERR "winch_thread : write failed, "
- "err = %d\n", errno);
+ os_info("winch_thread : write failed, err = %d\n",
+ errno);
}
+
+wait_kill:
+ c = 2;
+ count = write(pipe_fd, &c, sizeof(c));
+ while (1)
+ pause();
}
static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index b98545f3edb5..449d320c3f55 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -629,15 +629,18 @@ static irqreturn_t winch_interrupt(int irq, void *data)
if (fd != -1) {
err = generic_read(fd, &c, NULL);
- if (err < 0) {
+ /* A read of 2 means the winch thread failed and has warned */
+ if (err < 0 || (err == 1 && c == 2)) {
if (err != -EAGAIN) {
winch->fd = -1;
list_del(&winch->list);
os_close_file(fd);
- printk(KERN_ERR "winch_interrupt : "
- "read failed, errno = %d\n", -err);
- printk(KERN_ERR "fd %d is losing SIGWINCH "
- "support\n", winch->tty_fd);
+ if (err < 0) {
+ printk(KERN_ERR "winch_interrupt : read failed, errno = %d\n",
+ -err);
+ printk(KERN_ERR "fd %d is losing SIGWINCH support\n",
+ winch->tty_fd);
+ }
INIT_WORK(&winch->work, __free_winch);
schedule_work(&winch->work);
return IRQ_HANDLED;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 3d7836c46507..cabcc501b448 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -204,7 +204,7 @@ static int uml_net_close(struct net_device *dev)
return 0;
}
-static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct uml_net_private *lp = netdev_priv(dev);
unsigned long flags;
diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
index ffe2ee8a0246..97a37c062997 100644
--- a/arch/um/drivers/virt-pci.c
+++ b/arch/um/drivers/virt-pci.c
@@ -971,7 +971,7 @@ static long um_pci_map_platform(unsigned long offset, size_t size,
*ops = &um_pci_device_bar_ops;
*priv = &um_pci_platform_device->resptr[0];
- return 0;
+ return offset;
}
static const struct logic_iomem_region_ops um_pci_platform_ops = {
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h
index 5b072aba5b65..a7555e43ed14 100644
--- a/arch/um/include/asm/mmu.h
+++ b/arch/um/include/asm/mmu.h
@@ -12,7 +12,6 @@
typedef struct mm_context {
struct mm_id id;
struct uml_arch_mm_context arch;
- struct page *stub_pages[2];
} mm_context_t;
extern void __switch_mm(struct mm_id * mm_idp);
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index 7414154b8e9a..6c3779541845 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -22,7 +22,6 @@ struct mm_struct;
struct thread_struct {
struct pt_regs regs;
struct pt_regs *segv_regs;
- int singlestep_syscall;
void *fault_addr;
jmp_buf *fault_catcher;
struct task_struct *prev_sched;
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h
index d8b8b4f07e42..789b83013f35 100644
--- a/arch/um/include/shared/kern_util.h
+++ b/arch/um/include/shared/kern_util.h
@@ -34,7 +34,6 @@ extern int handle_page_fault(unsigned long address, unsigned long ip,
extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
extern void initial_thread_cb(void (*proc)(void *), void *arg);
-extern int is_syscall(unsigned long addr);
extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
@@ -50,7 +49,7 @@ extern void do_uml_exitcalls(void);
* Are we disallowed to sleep? Used to choose between GFP_KERNEL and
* GFP_ATOMIC.
*/
-extern int __cant_sleep(void);
+extern int __uml_cant_sleep(void);
extern int get_current_pid(void);
extern int copy_from_user_proc(void *to, void *from, int size);
extern char *uml_strdup(const char *string);
@@ -58,7 +57,7 @@ extern char *uml_strdup(const char *string);
extern unsigned long to_irq_stack(unsigned long *mask_out);
extern unsigned long from_irq_stack(int nested);
-extern int singlestepping(void *t);
+extern int singlestepping(void);
extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs);
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 0df646c6651e..aff8906304ea 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -323,9 +323,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/um/include/shared/ptrace_user.h b/arch/um/include/shared/ptrace_user.h
index 95455e8996e7..8a705d8f96ce 100644
--- a/arch/um/include/shared/ptrace_user.h
+++ b/arch/um/include/shared/ptrace_user.h
@@ -12,45 +12,4 @@
extern int ptrace_getregs(long pid, unsigned long *regs_out);
extern int ptrace_setregs(long pid, unsigned long *regs_in);
-/* syscall emulation path in ptrace */
-
-#ifndef PTRACE_SYSEMU
-#define PTRACE_SYSEMU 31
-#endif
-#ifndef PTRACE_SYSEMU_SINGLESTEP
-#define PTRACE_SYSEMU_SINGLESTEP 32
-#endif
-
-/* On architectures, that started to support PTRACE_O_TRACESYSGOOD
- * in linux 2.4, there are two different definitions of
- * PTRACE_SETOPTIONS: linux 2.4 uses 21 while linux 2.6 uses 0x4200.
- * For binary compatibility, 2.6 also supports the old "21", named
- * PTRACE_OLDSETOPTION. On these architectures, UML always must use
- * "21", to ensure the kernel runs on 2.4 and 2.6 host without
- * recompilation. So, we use PTRACE_OLDSETOPTIONS in UML.
- * We also want to be able to build the kernel on 2.4, which doesn't
- * have PTRACE_OLDSETOPTIONS. So, if it is missing, we declare
- * PTRACE_OLDSETOPTIONS to be the same as PTRACE_SETOPTIONS.
- *
- * On architectures, that start to support PTRACE_O_TRACESYSGOOD on
- * linux 2.6, PTRACE_OLDSETOPTIONS never is defined, and also isn't
- * supported by the host kernel. In that case, our trick lets us use
- * the new 0x4200 with the name PTRACE_OLDSETOPTIONS.
- */
-#ifndef PTRACE_OLDSETOPTIONS
-#define PTRACE_OLDSETOPTIONS PTRACE_SETOPTIONS
-#endif
-
-void set_using_sysemu(int value);
-int get_using_sysemu(void);
-extern int sysemu_supported;
-
-#define SELECT_PTRACE_OPERATION(sysemu_mode, singlestep_mode) \
- (((int[3][3] ) { \
- { PTRACE_SYSCALL, PTRACE_SYSCALL, PTRACE_SINGLESTEP }, \
- { PTRACE_SYSEMU, PTRACE_SYSEMU, PTRACE_SINGLESTEP }, \
- { PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP, \
- PTRACE_SYSEMU_SINGLESTEP } }) \
- [sysemu_mode][singlestep_mode])
-
#endif
diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h
index 2f9c3ce5b45e..a0450326521c 100644
--- a/arch/um/include/shared/registers.h
+++ b/arch/um/include/shared/registers.h
@@ -14,8 +14,6 @@ extern int save_fp_registers(int pid, unsigned long *fp_regs);
extern int restore_fp_registers(int pid, unsigned long *fp_regs);
extern int save_fpx_registers(int pid, unsigned long *fp_regs);
extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
-extern int save_registers(int pid, struct uml_pt_regs *regs);
-extern int restore_pid_registers(int pid, struct uml_pt_regs *regs);
extern int init_pid_registers(int pid);
extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
extern int get_fp_registers(int pid, unsigned long *regs);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 106b7da2f8d6..ab95648e93e1 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -220,7 +220,7 @@ void arch_cpu_idle(void)
um_idle_sleep();
}
-int __cant_sleep(void) {
+int __uml_cant_sleep(void) {
return in_atomic() || irqs_disabled() || in_interrupt();
/* Is in_interrupt() really needed? */
}
@@ -332,17 +332,9 @@ int __init make_proc_sysemu(void)
late_initcall(make_proc_sysemu);
-int singlestepping(void * t)
+int singlestepping(void)
{
- struct task_struct *task = t ? t : current;
-
- if (!test_thread_flag(TIF_SINGLESTEP))
- return 0;
-
- if (task->thread.singlestep_syscall)
- return 1;
-
- return 2;
+ return test_thread_flag(TIF_SINGLESTEP);
}
/*
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 5154b27de580..6600a2782796 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -12,7 +12,6 @@
void user_enable_single_step(struct task_struct *child)
{
set_tsk_thread_flag(child, TIF_SINGLESTEP);
- child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING
SUBARCH_SET_SINGLESTEPPING(child, 1);
@@ -22,7 +21,6 @@ void user_enable_single_step(struct task_struct *child)
void user_disable_single_step(struct task_struct *child)
{
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
- child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING
SUBARCH_SET_SINGLESTEPPING(child, 0);
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index ae4658f576ab..a56b44522766 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -121,18 +121,6 @@ void do_signal(struct pt_regs *regs)
}
/*
- * This closes a way to execute a system call on the host. If
- * you set a breakpoint on a system call instruction and singlestep
- * from it, the tracing thread used to PTRACE_SINGLESTEP the process
- * rather than PTRACE_SYSCALL it, allowing the system call to execute
- * on the host. The tracing thread will check this flag and
- * PTRACE_SYSCALL if necessary.
- */
- if (test_thread_flag(TIF_SINGLESTEP))
- current->thread.singlestep_syscall =
- is_syscall(PT_REGS_IP(&current->thread.regs));
-
- /*
* if there's no signal to deliver, we just put the saved sigmask
* back
*/
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index aaee96f07172..198269e384c4 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -236,7 +236,9 @@ EXPORT_SYMBOL(strnlen_user);
* argument and comparison of the previous
* futex value with another constant.
*
- * @encoded_op: encoded operation to execute
+ * @op: operation to execute
+ * @oparg: argument to operation
+ * @oval: old value at uaddr
* @uaddr: pointer to user space address
*
* Return:
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index fddd1dec27e6..3e270da6b6f6 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -432,9 +432,29 @@ static void time_travel_update_time(unsigned long long next, bool idle)
time_travel_del_event(&ne);
}
+static void time_travel_update_time_rel(unsigned long long offs)
+{
+ unsigned long flags;
+
+ /*
+ * Disable interrupts before calculating the new time so
+ * that a real timer interrupt (signal) can't happen at
+ * a bad time e.g. after we read time_travel_time but
+ * before we've completed updating the time.
+ */
+ local_irq_save(flags);
+ time_travel_update_time(time_travel_time + offs, false);
+ local_irq_restore(flags);
+}
+
void time_travel_ndelay(unsigned long nsec)
{
- time_travel_update_time(time_travel_time + nsec, false);
+ /*
+ * Not strictly needed to use _rel() version since this is
+ * only used in INFCPU/EXT modes, but it doesn't hurt and
+ * is more readable too.
+ */
+ time_travel_update_time_rel(nsec);
}
EXPORT_SYMBOL(time_travel_ndelay);
@@ -568,7 +588,11 @@ static void time_travel_set_start(void)
#define time_travel_time 0
#define time_travel_ext_waiting 0
-static inline void time_travel_update_time(unsigned long long ns, bool retearly)
+static inline void time_travel_update_time(unsigned long long ns, bool idle)
+{
+}
+
+static inline void time_travel_update_time_rel(unsigned long long offs)
{
}
@@ -720,9 +744,7 @@ static u64 timer_read(struct clocksource *cs)
*/
if (!irqs_disabled() && !in_interrupt() && !in_softirq() &&
!time_travel_ext_waiting)
- time_travel_update_time(time_travel_time +
- TIMER_MULTIPLIER,
- false);
+ time_travel_update_time_rel(TIMER_MULTIPLIER);
return time_travel_time / TIMER_MULTIPLIER;
}
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index b459745f52e2..3cb8ac63be6e 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -46,7 +46,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
unsigned long stack, sp;
int pid, fds[2], ret, n;
- stack = alloc_stack(0, __cant_sleep());
+ stack = alloc_stack(0, __uml_cant_sleep());
if (stack == 0)
return -ENOMEM;
@@ -70,7 +70,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
data.pre_data = pre_data;
data.argv = argv;
data.fd = fds[1];
- data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
+ data.buf = __uml_cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
uml_kmalloc(PATH_MAX, UM_GFP_KERNEL);
pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
if (pid < 0) {
@@ -121,7 +121,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
unsigned long stack, sp;
int pid, status, err;
- stack = alloc_stack(0, __cant_sleep());
+ stack = alloc_stack(0, __uml_cant_sleep());
if (stack == 0)
return -ENOMEM;
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index b123955be7ac..bd80b921add0 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -11,26 +11,6 @@
#include <sysdep/ptrace_user.h>
#include <registers.h>
-int save_registers(int pid, struct uml_pt_regs *regs)
-{
- int err;
-
- err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
- if (err < 0)
- return -errno;
- return 0;
-}
-
-int restore_pid_registers(int pid, struct uml_pt_regs *regs)
-{
- int err;
-
- err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
- if (err < 0)
- return -errno;
- return 0;
-}
-
/* This is set once at boot time and not changed thereafter */
static unsigned long exec_regs[MAX_REG_NR];
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 9464833e741a..1f5c3f2523d1 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -177,48 +177,11 @@ static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp
segv(regs->faultinfo, 0, 1, NULL);
}
-/*
- * To use the same value of using_sysemu as the caller, ask it that value
- * (in local_using_sysemu
- */
-static void handle_trap(int pid, struct uml_pt_regs *regs,
- int local_using_sysemu)
+static void handle_trap(int pid, struct uml_pt_regs *regs)
{
- int err, status;
-
if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END))
fatal_sigsegv();
- if (!local_using_sysemu)
- {
- err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
- __NR_getpid);
- if (err < 0) {
- printk(UM_KERN_ERR "%s - nullifying syscall failed, errno = %d\n",
- __func__, errno);
- fatal_sigsegv();
- }
-
- err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
- if (err < 0) {
- printk(UM_KERN_ERR "%s - continuing to end of syscall failed, errno = %d\n",
- __func__, errno);
- fatal_sigsegv();
- }
-
- CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));
- if ((err < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGTRAP + 0x80)) {
- err = ptrace_dump_regs(pid);
- if (err)
- printk(UM_KERN_ERR "Failed to get registers from process, errno = %d\n",
- -err);
- printk(UM_KERN_ERR "%s - failed to wait at end of syscall, errno = %d, status = %d\n",
- __func__, errno, status);
- fatal_sigsegv();
- }
- }
-
handle_syscall(regs);
}
@@ -226,7 +189,7 @@ extern char __syscall_stub_start[];
/**
* userspace_tramp() - userspace trampoline
- * @stack: pointer to the new userspace stack page, can be NULL, if? FIXME:
+ * @stack: pointer to the new userspace stack page
*
* The userspace trampoline is used to setup a new userspace process in start_userspace() after it was clone()'ed.
* This function will run on a temporary stack page.
@@ -241,9 +204,13 @@ extern char __syscall_stub_start[];
*/
static int userspace_tramp(void *stack)
{
+ struct sigaction sa;
void *addr;
int fd;
unsigned long long offset;
+ unsigned long segv_handler = STUB_CODE +
+ (unsigned long) stub_segv_handler -
+ (unsigned long) __syscall_stub_start;
ptrace(PTRACE_TRACEME, 0, 0, 0);
@@ -254,39 +221,30 @@ static int userspace_tramp(void *stack)
addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
if (addr == MAP_FAILED) {
- printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, errno = %d\n",
- STUB_CODE, errno);
+ os_info("mapping mmap stub at 0x%lx failed, errno = %d\n",
+ STUB_CODE, errno);
exit(1);
}
- if (stack != NULL) {
- fd = phys_mapping(uml_to_phys(stack), &offset);
- addr = mmap((void *) STUB_DATA,
- STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_SHARED, fd, offset);
- if (addr == MAP_FAILED) {
- printk(UM_KERN_ERR "mapping segfault stack at 0x%lx failed, errno = %d\n",
- STUB_DATA, errno);
- exit(1);
- }
+ fd = phys_mapping(uml_to_phys(stack), &offset);
+ addr = mmap((void *) STUB_DATA,
+ STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_SHARED, fd, offset);
+ if (addr == MAP_FAILED) {
+ os_info("mapping segfault stack at 0x%lx failed, errno = %d\n",
+ STUB_DATA, errno);
+ exit(1);
}
- if (stack != NULL) {
- struct sigaction sa;
-
- unsigned long v = STUB_CODE +
- (unsigned long) stub_segv_handler -
- (unsigned long) __syscall_stub_start;
-
- set_sigstack((void *) STUB_DATA, STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
- sa.sa_sigaction = (void *) v;
- sa.sa_restorer = NULL;
- if (sigaction(SIGSEGV, &sa, NULL) < 0) {
- printk(UM_KERN_ERR "%s - setting SIGSEGV handler failed - errno = %d\n",
- __func__, errno);
- exit(1);
- }
+
+ set_sigstack((void *) STUB_DATA, STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
+ sa.sa_si