aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/include/os.h15
-rw-r--r--arch/um/include/user_util.h8
-rw-r--r--arch/um/kernel/Makefile13
-rw-r--r--arch/um/kernel/um_arch.c2
-rw-r--r--arch/um/os-Linux/Makefile7
-rw-r--r--arch/um/os-Linux/process.c58
-rw-r--r--arch/um/os-Linux/start_up.c (renamed from arch/um/kernel/process.c)182
-rw-r--r--arch/um/os-Linux/tt.c113
8 files changed, 230 insertions, 168 deletions
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 881d2988d2d8..4c362458052c 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -153,6 +153,11 @@ extern int os_file_type(char *file);
153extern int os_file_mode(char *file, struct openflags *mode_out); 153extern int os_file_mode(char *file, struct openflags *mode_out);
154extern int os_lock_file(int fd, int excl); 154extern int os_lock_file(int fd, int excl);
155 155
156/* start_up.c */
157extern void os_early_checks(void);
158extern int can_do_skas(void);
159
160/* process.c */
156extern unsigned long os_process_pc(int pid); 161extern unsigned long os_process_pc(int pid);
157extern int os_process_parent(int pid); 162extern int os_process_parent(int pid);
158extern void os_stop_process(int pid); 163extern void os_stop_process(int pid);
@@ -161,6 +166,9 @@ extern void os_kill_ptraced_process(int pid, int reap_child);
161extern void os_usr1_process(int pid); 166extern void os_usr1_process(int pid);
162extern int os_getpid(void); 167extern int os_getpid(void);
163extern int os_getpgrp(void); 168extern int os_getpgrp(void);
169extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
170extern void init_new_thread_signals(int altstack);
171extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
164 172
165extern int os_map_memory(void *virt, int fd, unsigned long long off, 173extern int os_map_memory(void *virt, int fd, unsigned long long off,
166 unsigned long len, int r, int w, int x); 174 unsigned long len, int r, int w, int x);
@@ -170,6 +178,13 @@ extern int os_unmap_memory(void *addr, int len);
170extern void os_flush_stdout(void); 178extern void os_flush_stdout(void);
171extern unsigned long long os_usecs(void); 179extern unsigned long long os_usecs(void);
172 180
181/* tt.c
182 * for tt mode only (will be deleted in future...)
183 */
184extern void forward_pending_sigio(int target);
185extern int start_fork_tramp(void *arg, unsigned long temp_stack,
186 int clone_flags, int (*tramp)(void *));
187
173#endif 188#endif
174 189
175/* 190/*
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 7b6a24dfd302..bb505e01d994 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -54,8 +54,6 @@ extern void stack_protections(unsigned long address);
54extern void task_protections(unsigned long address); 54extern void task_protections(unsigned long address);
55extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); 55extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
56extern void *add_signal_handler(int sig, void (*handler)(int)); 56extern void *add_signal_handler(int sig, void (*handler)(int));
57extern int start_fork_tramp(void *arg, unsigned long temp_stack,
58 int clone_flags, int (*tramp)(void *));
59extern int linux_main(int argc, char **argv); 57extern int linux_main(int argc, char **argv);
60extern void set_cmdline(char *cmd); 58extern void set_cmdline(char *cmd);
61extern void input_cb(void (*proc)(void *), void *arg, int arg_len); 59extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
@@ -64,8 +62,6 @@ extern void *um_kmalloc(int size);
64extern int switcheroo(int fd, int prot, void *from, void *to, int size); 62extern int switcheroo(int fd, int prot, void *from, void *to, int size);
65extern void setup_machinename(char *machine_out); 63extern void setup_machinename(char *machine_out);
66extern void setup_hostinfo(void); 64extern void setup_hostinfo(void);
67extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
68extern void init_new_thread_signals(int altstack);
69extern void do_exec(int old_pid, int new_pid); 65extern void do_exec(int old_pid, int new_pid);
70extern void tracer_panic(char *msg, ...); 66extern void tracer_panic(char *msg, ...);
71extern char *get_umid(int only_if_set); 67extern char *get_umid(int only_if_set);
@@ -74,16 +70,12 @@ extern int detach(int pid, int sig);
74extern int attach(int pid); 70extern int attach(int pid);
75extern void kill_child_dead(int pid); 71extern void kill_child_dead(int pid);
76extern int cont(int pid); 72extern int cont(int pid);
77extern void check_ptrace(void);
78extern void check_sigio(void); 73extern void check_sigio(void);
79extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
80extern void write_sigio_workaround(void); 74extern void write_sigio_workaround(void);
81extern void arch_check_bugs(void); 75extern void arch_check_bugs(void);
82extern int cpu_feature(char *what, char *buf, int len); 76extern int cpu_feature(char *what, char *buf, int len);
83extern int arch_handle_signal(int sig, union uml_pt_regs *regs); 77extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
84extern int arch_fixup(unsigned long address, void *sc_ptr); 78extern int arch_fixup(unsigned long address, void *sc_ptr);
85extern void forward_pending_sigio(int target);
86extern int can_do_skas(void);
87extern void arch_init_thread(void); 79extern void arch_init_thread(void);
88extern int setjmp_wrapper(void (*proc)(void *, void *), ...); 80extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
89extern int raw(int fd); 81extern int raw(int fd);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index a9cdd00775a3..614b8ebeb0ed 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -8,11 +8,10 @@ clean-files :=
8 8
9obj-y = config.o exec_kern.o exitcode.o \ 9obj-y = config.o exec_kern.o exitcode.o \
10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ 10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
11 physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ 11 physmem.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
12 sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ 12 sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o \
13 syscall_kern.o sysrq.o tempfile.o time.o time_kern.o \ 13 tempfile.o time.o time_kern.o tlb.o trap_kern.o trap_user.o \
14 tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ 14 uaccess_user.o um_arch.o umid.o user_util.o
15 user_util.o
16 15
17obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
18obj-$(CONFIG_GPROF) += gprof_syms.o 17obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -25,8 +24,8 @@ obj-$(CONFIG_MODE_SKAS) += skas/
25 24
26user-objs-$(CONFIG_TTY_LOG) += tty_log.o 25user-objs-$(CONFIG_TTY_LOG) += tty_log.o
27 26
28USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ 27USER_OBJS := $(user-objs-y) config.o helper.o main.o tempfile.o time.o \
29 time.o tty_log.o umid.o user_util.o 28 tty_log.o umid.o user_util.o
30 29
31include arch/um/scripts/Makefile.rules 30include arch/um/scripts/Makefile.rules
32 31
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index b781b6f94283..09f6f7ce4695 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -333,6 +333,7 @@ int linux_main(int argc, char **argv)
333 if(have_root == 0) 333 if(have_root == 0)
334 add_arg(DEFAULT_COMMAND_LINE); 334 add_arg(DEFAULT_COMMAND_LINE);
335 335
336 os_early_checks();
336 mode_tt = force_tt ? 1 : !can_do_skas(); 337 mode_tt = force_tt ? 1 : !can_do_skas();
337#ifndef CONFIG_MODE_TT 338#ifndef CONFIG_MODE_TT
338 if (mode_tt) { 339 if (mode_tt) {
@@ -470,7 +471,6 @@ void __init setup_arch(char **cmdline_p)
470void __init check_bugs(void) 471void __init check_bugs(void)
471{ 472{
472 arch_check_bugs(); 473 arch_check_bugs();
473 check_ptrace();
474 check_sigio(); 474 check_sigio();
475 check_devanon(); 475 check_devanon();
476} 476}
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 351d96934679..d3c1560e3ed8 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,10 +3,11 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o process.o signal.o time.o tty.o user_syms.o \ 6obj-y = aio.o elf_aux.o file.o process.o signal.o start_up.o time.o tt.o \
7 drivers/ sys-$(SUBARCH)/ 7 tty.o user_syms.o drivers/ sys-$(SUBARCH)/
8 8
9USER_OBJS := aio.o elf_aux.o file.o process.o signal.o time.o tty.o 9USER_OBJS := aio.o elf_aux.o file.o process.o signal.o start_up.o time.o tt.o \
10 tty.o
10 11
11CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) 12CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
12 13
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 1e126bfd31a7..d32413e4b4ce 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -3,10 +3,10 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdio.h> 6#include <stdio.h>
8#include <errno.h> 7#include <errno.h>
9#include <signal.h> 8#include <signal.h>
9#include <setjmp.h>
10#include <linux/unistd.h> 10#include <linux/unistd.h>
11#include <sys/mman.h> 11#include <sys/mman.h>
12#include <sys/wait.h> 12#include <sys/wait.h>
@@ -14,6 +14,10 @@
14#include "os.h" 14#include "os.h"
15#include "user.h" 15#include "user.h"
16#include "user_util.h" 16#include "user_util.h"
17#include "signal_user.h"
18#include "process.h"
19#include "irq_user.h"
20#include "kern_util.h"
17 21
18#define ARBITRARY_ADDR -1 22#define ARBITRARY_ADDR -1
19#define FAILURE_PID -1 23#define FAILURE_PID -1
@@ -114,8 +118,10 @@ void os_usr1_process(int pid)
114 kill(pid, SIGUSR1); 118 kill(pid, SIGUSR1);
115} 119}
116 120
117/*Don't use the glibc version, which caches the result in TLS. It misses some 121/* Don't use the glibc version, which caches the result in TLS. It misses some
118 * syscalls, and also breaks with clone(), which does not unshare the TLS.*/ 122 * syscalls, and also breaks with clone(), which does not unshare the TLS.
123 */
124
119inline _syscall0(pid_t, getpid) 125inline _syscall0(pid_t, getpid)
120 126
121int os_getpid(void) 127int os_getpid(void)
@@ -164,6 +170,52 @@ int os_unmap_memory(void *addr, int len)
164 return(0); 170 return(0);
165} 171}
166 172
173void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
174{
175 int flags = 0, pages;
176
177 if(sig_stack != NULL){
178 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
179 set_sigstack(sig_stack, pages * page_size());
180 flags = SA_ONSTACK;
181 }
182 if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
183}
184
185void init_new_thread_signals(int altstack)
186{
187 int flags = altstack ? SA_ONSTACK : 0;
188
189 set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
190 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
191 set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
192 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
193 set_handler(SIGFPE, (__sighandler_t) sig_handler, flags,
194 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
195 set_handler(SIGILL, (__sighandler_t) sig_handler, flags,
196 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
197 set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
198 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
199 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
200 flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
201 signal(SIGHUP, SIG_IGN);
202
203 init_irq_signals(altstack);
204}
205
206int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
207{
208 sigjmp_buf buf;
209 int n;
210
211 *jmp_ptr = &buf;
212 n = sigsetjmp(buf, 1);
213 if(n != 0)
214 return(n);
215 (*fn)(arg);
216 return(0);
217}
218
167/* 219/*
168 * Overrides for Emacs so that we follow Linus's tabbing style. 220 * Overrides for Emacs so that we follow Linus's tabbing style.
169 * Emacs will notice this stuff at the end of the file and automatically 221 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/process.c b/arch/um/os-Linux/start_up.c
index 67acd92c5322..a3eab25f3791 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/os-Linux/start_up.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -19,7 +19,6 @@
19#include "user_util.h" 19#include "user_util.h"
20#include "kern_util.h" 20#include "kern_util.h"
21#include "user.h" 21#include "user.h"
22#include "process.h"
23#include "signal_kern.h" 22#include "signal_kern.h"
24#include "signal_user.h" 23#include "signal_user.h"
25#include "sysdep/ptrace.h" 24#include "sysdep/ptrace.h"
@@ -39,98 +38,6 @@
39#include "registers.h" 38#include "registers.h"
40#endif 39#endif
41 40
42void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
43{
44 int flags = 0, pages;
45
46 if(sig_stack != NULL){
47 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
48 set_sigstack(sig_stack, pages * page_size());
49 flags = SA_ONSTACK;
50 }
51 if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
52}
53
54void init_new_thread_signals(int altstack)
55{
56 int flags = altstack ? SA_ONSTACK : 0;
57
58 set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
59 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
60 set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
61 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
62 set_handler(SIGFPE, (__sighandler_t) sig_handler, flags,
63 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
64 set_handler(SIGILL, (__sighandler_t) sig_handler, flags,
65 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
66 set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
67 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
68 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
69 flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
70 signal(SIGHUP, SIG_IGN);
71
72 init_irq_signals(altstack);
73}
74
75struct tramp {
76 int (*tramp)(void *);
77 void *tramp_data;
78 unsigned long temp_stack;
79 int flags;
80 int pid;
81};
82
83/* See above for why sigkill is here */
84
85int sigkill = SIGKILL;
86
87int outer_tramp(void *arg)
88{
89 struct tramp *t;
90 int sig = sigkill;
91
92 t = arg;
93 t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
94 t->flags, t->tramp_data);
95 if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
96 kill(os_getpid(), sig);
97 _exit(0);
98}
99
100int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
101 int clone_flags, int (*tramp)(void *))
102{
103 struct tramp arg;
104 unsigned long sp;
105 int new_pid, status, err;
106
107 /* The trampoline will run on the temporary stack */
108 sp = stack_sp(temp_stack);
109
110 clone_flags |= CLONE_FILES | SIGCHLD;
111
112 arg.tramp = tramp;
113 arg.tramp_data = thread_arg;
114 arg.temp_stack = temp_stack;
115 arg.flags = clone_flags;
116
117 /* Start the process and wait for it to kill itself */
118 new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
119 if(new_pid < 0)
120 return(new_pid);
121
122 CATCH_EINTR(err = waitpid(new_pid, &status, 0));
123 if(err < 0)
124 panic("Waiting for outer trampoline failed - errno = %d",
125 errno);
126
127 if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
128 panic("outer trampoline didn't exit with SIGKILL, "
129 "status = %d", status);
130
131 return(arg.pid);
132}
133
134static int ptrace_child(void *arg) 41static int ptrace_child(void *arg)
135{ 42{
136 int ret; 43 int ret;
@@ -165,7 +72,7 @@ static int start_ptraced_child(void **stack_out)
165 void *stack; 72 void *stack;
166 unsigned long sp; 73 unsigned long sp;
167 int pid, n, status; 74 int pid, n, status;
168 75
169 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, 76 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
170 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 77 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
171 if(stack == MAP_FAILED) 78 if(stack == MAP_FAILED)
@@ -173,10 +80,10 @@ static int start_ptraced_child(void **stack_out)
173 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); 80 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
174 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); 81 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
175 if(pid < 0) 82 if(pid < 0)
176 panic("check_ptrace : clone failed, errno = %d", errno); 83 panic("start_ptraced_child : clone failed, errno = %d", errno);
177 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 84 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
178 if(n < 0) 85 if(n < 0)
179 panic("check_ptrace : wait failed, errno = %d", errno); 86 panic("check_ptrace : clone failed, errno = %d", errno);
180 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 87 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
181 panic("check_ptrace : expected SIGSTOP, got status = %d", 88 panic("check_ptrace : expected SIGSTOP, got status = %d",
182 status); 89 status);
@@ -185,11 +92,14 @@ static int start_ptraced_child(void **stack_out)
185 return(pid); 92 return(pid);
186} 93}
187 94
188/* When testing for SYSEMU support, if it is one of the broken versions, we must 95/* When testing for SYSEMU support, if it is one of the broken versions, we
189 * just avoid using sysemu, not panic, but only if SYSEMU features are broken. 96 * must just avoid using sysemu, not panic, but only if SYSEMU features are
97 * broken.
190 * So only for SYSEMU features we test mustpanic, while normal host features 98 * So only for SYSEMU features we test mustpanic, while normal host features
191 * must work anyway!*/ 99 * must work anyway!
192static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) 100 */
101static int stop_ptraced_child(int pid, void *stack, int exitcode,
102 int mustpanic)
193{ 103{
194 int status, n, ret = 0; 104 int status, n, ret = 0;
195 105
@@ -217,8 +127,6 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
217 return ret; 127 return ret;
218} 128}
219 129
220static int force_sysemu_disabled = 0;
221
222int ptrace_faultinfo = 1; 130int ptrace_faultinfo = 1;
223int proc_mm = 1; 131int proc_mm = 1;
224 132
@@ -228,24 +136,27 @@ static int __init skas0_cmd_param(char *str, int* add)
228 return 0; 136 return 0;
229} 137}
230 138
139__uml_setup("skas0", skas0_cmd_param,
140 "skas0\n"
141 " Disables SKAS3 usage, so that SKAS0 is used, unless \n"
142 " you specify mode=tt.\n\n");
143
144static int force_sysemu_disabled = 0;
145
231static int __init nosysemu_cmd_param(char *str, int* add) 146static int __init nosysemu_cmd_param(char *str, int* add)
232{ 147{
233 force_sysemu_disabled = 1; 148 force_sysemu_disabled = 1;
234 return 0; 149 return 0;
235} 150}
236 151
237__uml_setup("skas0", skas0_cmd_param,
238 "skas0\n"
239 " Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
240 " specify mode=tt.\n\n");
241
242__uml_setup("nosysemu", nosysemu_cmd_param, 152__uml_setup("nosysemu", nosysemu_cmd_param,
243 "nosysemu\n" 153"nosysemu\n"
244 " Turns off syscall emulation patch for ptrace (SYSEMU) on.\n" 154" Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
245 " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n" 155" SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n"
246 " behaviour of ptrace() and helps reducing host context switch rate.\n" 156" behaviour of ptrace() and helps reducing host context switch rate.\n"
247 " To make it working, you need a kernel patch for your host, too.\n" 157" To make it working, you need a kernel patch for your host, too.\n"
248 " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information.\n\n"); 158" See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n"
159" information.\n\n");
249 160
250static void __init check_sysemu(void) 161static void __init check_sysemu(void)
251{ 162{
@@ -321,7 +232,7 @@ fail_stopped:
321 printk("missing\n"); 232 printk("missing\n");
322} 233}
323 234
324void __init check_ptrace(void) 235static void __init check_ptrace(void)
325{ 236{
326 void *stack; 237 void *stack;
327 int pid, syscall, n, status; 238 int pid, syscall, n, status;
@@ -329,12 +240,12 @@ void __init check_ptrace(void)
329 printk("Checking that ptrace can change system call numbers..."); 240 printk("Checking that ptrace can change system call numbers...");
330 pid = start_ptraced_child(&stack); 241 pid = start_ptraced_child(&stack);
331 242
332 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) 243 if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
333 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); 244 panic("check_ptrace: PTRACE_OLDSETOPTIONS failed, errno = %d", errno);
334 245
335 while(1){ 246 while(1){
336 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) 247 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
337 panic("check_ptrace : ptrace failed, errno = %d", 248 panic("check_ptrace : ptrace failed, errno = %d",
338 errno); 249 errno);
339 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 250 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
340 if(n < 0) 251 if(n < 0)
@@ -342,7 +253,7 @@ void __init check_ptrace(void)
342 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP + 0x80)) 253 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP + 0x80))
343 panic("check_ptrace : expected SIGTRAP + 0x80, " 254 panic("check_ptrace : expected SIGTRAP + 0x80, "
344 "got status = %d", status); 255 "got status = %d", status);
345 256
346 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 257 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
347 0); 258 0);
348 if(syscall == __NR_getpid){ 259 if(syscall == __NR_getpid){
@@ -359,33 +270,12 @@ void __init check_ptrace(void)
359 check_sysemu(); 270 check_sysemu();
360} 271}
361 272
362int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) 273void os_early_checks(void)
363{
364 sigjmp_buf buf;
365 int n;
366
367 *jmp_ptr = &buf;
368 n = sigsetjmp(buf, 1);
369 if(n != 0)
370 return(n);
371 (*fn)(arg);
372 return(0);
373}
374
375void forward_pending_sigio(int target)
376{ 274{
377 sigset_t sigs; 275 check_ptrace();
378
379 if(sigpending(&sigs))
380 panic("forward_pending_sigio : sigpending failed");
381 if(sigismember(&sigs, SIGIO))
382 kill(target, SIGIO);
383} 276}
384 277
385extern void *__syscall_stub_start, __syscall_stub_end;
386
387#ifdef UML_CONFIG_MODE_SKAS 278#ifdef UML_CONFIG_MODE_SKAS
388
389static inline void check_skas3_ptrace_support(void) 279static inline void check_skas3_ptrace_support(void)
390{ 280{
391 struct ptrace_faultinfo fi; 281 struct ptrace_faultinfo fi;
@@ -400,9 +290,8 @@ static inline void check_skas3_ptrace_support(void)
400 ptrace_faultinfo = 0; 290 ptrace_faultinfo = 0;
401 if(errno == EIO) 291 if(errno == EIO)
402 printf("not found\n"); 292 printf("not found\n");
403 else { 293 else
404 perror("not found"); 294 perror("not found");
405 }
406 } 295 }
407 else { 296 else {
408 if (!ptrace_faultinfo) 297 if (!ptrace_faultinfo)
@@ -419,9 +308,10 @@ int can_do_skas(void)
419{ 308{
420 printf("Checking for /proc/mm..."); 309 printf("Checking for /proc/mm...");
421 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) { 310 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
422 proc_mm = 0; 311 proc_mm = 0;
423 printf("not found\n"); 312 printf("not found\n");
424 } else { 313 }
314 else {
425 if (!proc_mm) 315 if (!proc_mm)
426 printf("found but disabled on command line\n"); 316 printf("found but disabled on command line\n");
427 else 317 else
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
new file mode 100644
index 000000000000..5b047ab8416a
--- /dev/null
+++ b/arch/um/os-Linux/tt.c
@@ -0,0 +1,113 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <unistd.h>
8#include <signal.h>
9#include <sched.h>
10#include <errno.h>
11#include <stdarg.h>
12#include <stdlib.h>
13#include <setjmp.h>
14#include <sys/time.h>
15#include <sys/ptrace.h>
16#include <linux/ptrace.h>
17#include <sys/wait.h>
18#include <sys/mman.h>
19#include <asm/ptrace.h>
20#include <asm/unistd.h>
21#include <asm/page.h>
22#include "user_util.h"
23#include "kern_util.h"
24#include "user.h"
25#include "signal_kern.h"
26#include "signal_user.h"
27#include "sysdep/ptrace.h"
28#include "sysdep/sigcontext.h"
29#include "irq_user.h"
30#include "ptrace_user.h"
31#include "time_user.h"
32#include "init.h"
33#include "os.h"
34#include "uml-config.h"
35#include "choose-mode.h"
36#include "mode.h"
37#include "tempfile.h"
38
39/*
40 *-------------------------
41 * only for tt mode (will be deleted in future...)
42 *-------------------------
43 */
44
45struct tramp {
46 int (*tramp)(void *);
47 void *tramp_data;
48 unsigned long temp_stack;
49 int flags;
50 int pid;
51};
52
53/* See above for why sigkill is here */
54
55int sigkill = SIGKILL;
56
57int outer_tramp(void *arg)
58{
59 struct tramp *t;
60 int sig = sigkill;
61
62 t = arg;
63 t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
64 t->flags, t->tramp_data);
65 if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
66 kill(os_getpid(), sig);
67 _exit(0);
68}
69
70int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
71 int clone_flags, int (*tramp)(void *))
72{
73 struct tramp arg;
74 unsigned long sp;
75 int new_pid, status, err;
76
77 /* The trampoline will run on the temporary stack */
78 sp = stack_sp(temp_stack);
79
80 clone_flags |= CLONE_FILES | SIGCHLD;
81
82 arg.tramp = tramp;
83 arg.tramp_data = thread_arg;
84 arg.temp_stack = temp_stack;
85 arg.flags = clone_flags;
86
87 /* Start the process and wait for it to kill itself */
88 new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
89 if(new_pid < 0)
90 return(new_pid);
91
92 CATCH_EINTR(err = waitpid(new_pid, &status, 0));
93 if(err < 0)
94 panic("Waiting for outer trampoline failed - errno = %d",
95 errno);
96
97 if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
98 panic("outer trampoline didn't exit with SIGKILL, "
99 "status = %d", status);
100
101 return(arg.pid);
102}
103
104void forward_pending_sigio(int target)
105{
106 sigset_t sigs;
107
108 if(sigpending(&sigs))
109 panic("forward_pending_sigio : sigpending failed");
110 if(sigismember(&sigs, SIGIO))
111 kill(target, SIGIO);
112}
113