aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-07-31 20:37:25 -0400
committerPaul Mackerras <paulus@samba.org>2006-07-31 20:37:25 -0400
commit57cad8084e0837e0f2c97da789ec9b3f36809be9 (patch)
treee9c790afb4286f78cb08d9664f58baa7e876fe55 /arch/um/kernel
parentcb18bd40030c879cd93fef02fd579f74dbab473d (diff)
parent49b1e3ea19b1c95c2f012b8331ffb3b169e4c042 (diff)
Merge branch 'merge'
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/Makefile10
-rw-r--r--arch/um/kernel/dyn.lds.S1
-rw-r--r--arch/um/kernel/exec.c (renamed from arch/um/kernel/exec_kern.c)13
-rw-r--r--arch/um/kernel/irq.c62
-rw-r--r--arch/um/kernel/ksyms.c6
-rw-r--r--arch/um/kernel/mem.c11
-rw-r--r--arch/um/kernel/physmem.c2
-rw-r--r--arch/um/kernel/sigio.c (renamed from arch/um/kernel/sigio_kern.c)16
-rw-r--r--arch/um/kernel/signal.c (renamed from arch/um/kernel/signal_kern.c)10
-rw-r--r--arch/um/kernel/skas/mem.c24
-rw-r--r--arch/um/kernel/skas/process_kern.c2
-rw-r--r--arch/um/kernel/skas/syscall.c7
-rw-r--r--arch/um/kernel/syscall.c174
-rw-r--r--arch/um/kernel/syscall_kern.c166
-rw-r--r--arch/um/kernel/time.c (renamed from arch/um/kernel/time_kern.c)84
-rw-r--r--arch/um/kernel/trap.c (renamed from arch/um/kernel/trap_kern.c)18
-rw-r--r--arch/um/kernel/tt/exec_kern.c2
-rw-r--r--arch/um/kernel/tt/mem.c21
-rw-r--r--arch/um/kernel/tt/process_kern.c2
-rw-r--r--arch/um/kernel/tt/syscall_kern.c12
-rw-r--r--arch/um/kernel/tt/tracer.c22
-rw-r--r--arch/um/kernel/um_arch.c9
-rw-r--r--arch/um/kernel/uml.lds.S13
-rw-r--r--arch/um/kernel/vmlinux.lds.S2
24 files changed, 264 insertions, 425 deletions
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index fe08971b64cf..a2d93065b2d0 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -6,16 +6,14 @@
6extra-y := vmlinux.lds 6extra-y := vmlinux.lds
7clean-files := 7clean-files :=
8 8
9obj-y = config.o exec_kern.o exitcode.o \ 9obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
10 init_task.o irq.o ksyms.o mem.o physmem.o \ 10 physmem.o process_kern.o ptrace.o reboot.o resource.o sigio.o \
11 process_kern.o ptrace.o reboot.o resource.o sigio_kern.o \ 11 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \
12 signal_kern.o smp.o syscall_kern.o sysrq.o \ 12 um_arch.o umid.o
13 time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o
14 13
15obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 14obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
16obj-$(CONFIG_GPROF) += gprof_syms.o 15obj-$(CONFIG_GPROF) += gprof_syms.o
17obj-$(CONFIG_GCOV) += gmon_syms.o 16obj-$(CONFIG_GCOV) += gmon_syms.o
18obj-$(CONFIG_SYSCALL_DEBUG) += syscall.o
19 17
20obj-$(CONFIG_MODE_TT) += tt/ 18obj-$(CONFIG_MODE_TT) += tt/
21obj-$(CONFIG_MODE_SKAS) += skas/ 19obj-$(CONFIG_MODE_SKAS) += skas/
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 2517ecb8bf27..68ed24df5c8f 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -26,6 +26,7 @@ SECTIONS
26 26
27 /* Read-only sections, merged into text segment: */ 27 /* Read-only sections, merged into text segment: */
28 .hash : { *(.hash) } 28 .hash : { *(.hash) }
29 .gnu.hash : { *(.gnu.hash) }
29 .dynsym : { *(.dynsym) } 30 .dynsym : { *(.dynsym) }
30 .dynstr : { *(.dynstr) } 31 .dynstr : { *(.dynstr) }
31 .gnu.version : { *(.gnu.version) } 32 .gnu.version : { *(.gnu.version) }
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec.c
index c0cb627bf594..fc38a6d5906d 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -31,18 +31,27 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
31 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); 31 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
32} 32}
33 33
34#ifdef CONFIG_TTY_LOG
35extern void log_exec(char **argv, void *tty);
36#endif
37
34static long execve1(char *file, char __user * __user *argv, 38static long execve1(char *file, char __user * __user *argv,
35 char __user *__user *env) 39 char __user *__user *env)
36{ 40{
37 long error; 41 long error;
38 42
39#ifdef CONFIG_TTY_LOG 43#ifdef CONFIG_TTY_LOG
40 log_exec(argv, current->tty); 44 task_lock(current);
45 log_exec(argv, current->signal->tty);
46 task_unlock(current);
41#endif 47#endif
42 error = do_execve(file, argv, env, &current->thread.regs); 48 error = do_execve(file, argv, env, &current->thread.regs);
43 if (error == 0){ 49 if (error == 0){
44 task_lock(current); 50 task_lock(current);
45 current->ptrace &= ~PT_DTRACE; 51 current->ptrace &= ~PT_DTRACE;
52#ifdef SUBARCH_EXECVE1
53 SUBARCH_EXECVE1(&current->thread.regs.regs);
54#endif
46 task_unlock(current); 55 task_unlock(current);
47 set_cmdline(current_cmd()); 56 set_cmdline(current_cmd());
48 } 57 }
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index bfd0bdc8cd40..589c69a75043 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -110,18 +110,7 @@ void sigio_handler(int sig, union uml_pt_regs *regs)
110 free_irqs(); 110 free_irqs();
111} 111}
112 112
113static void maybe_sigio_broken(int fd, int type) 113static DEFINE_SPINLOCK(irq_lock);
114{
115 if (os_isatty(fd)) {
116 if ((type == IRQ_WRITE) && !pty_output_sigio) {
117 write_sigio_workaround();
118 add_sigio_fd(fd, 0);
119 } else if ((type == IRQ_READ) && !pty_close_sigio) {
120 write_sigio_workaround();
121 add_sigio_fd(fd, 1);
122 }
123 }
124}
125 114
126int activate_fd(int irq, int fd, int type, void *dev_id) 115int activate_fd(int irq, int fd, int type, void *dev_id)
127{ 116{
@@ -166,7 +155,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
166 * this is called only from process context, and can be locked with 155 * this is called only from process context, and can be locked with
167 * a semaphore. 156 * a semaphore.
168 */ 157 */
169 flags = irq_lock(); 158 spin_lock_irqsave(&irq_lock, flags);
170 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { 159 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
171 if ((irq_fd->fd == fd) && (irq_fd->type == type)) { 160 if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
172 printk("Registering fd %d twice\n", fd); 161 printk("Registering fd %d twice\n", fd);
@@ -199,7 +188,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
199 * so we will not be able to put new pollfd struct to pollfds 188 * so we will not be able to put new pollfd struct to pollfds
200 * then we free the buffer tmp_fds and try again. 189 * then we free the buffer tmp_fds and try again.
201 */ 190 */
202 irq_unlock(flags); 191 spin_unlock_irqrestore(&irq_lock, flags);
203 kfree(tmp_pfd); 192 kfree(tmp_pfd);
204 tmp_pfd = NULL; 193 tmp_pfd = NULL;
205 194
@@ -207,24 +196,24 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
207 if (tmp_pfd == NULL) 196 if (tmp_pfd == NULL)
208 goto out_kfree; 197 goto out_kfree;
209 198
210 flags = irq_lock(); 199 spin_lock_irqsave(&irq_lock, flags);
211 } 200 }
212 /*-------------*/ 201 /*-------------*/
213 202
214 *last_irq_ptr = new_fd; 203 *last_irq_ptr = new_fd;
215 last_irq_ptr = &new_fd->next; 204 last_irq_ptr = &new_fd->next;
216 205
217 irq_unlock(flags); 206 spin_unlock_irqrestore(&irq_lock, flags);
218 207
219 /* This calls activate_fd, so it has to be outside the critical 208 /* This calls activate_fd, so it has to be outside the critical
220 * section. 209 * section.
221 */ 210 */
222 maybe_sigio_broken(fd, type); 211 maybe_sigio_broken(fd, (type == IRQ_READ));
223 212
224 return(0); 213 return(0);
225 214
226 out_unlock: 215 out_unlock:
227 irq_unlock(flags); 216 spin_unlock_irqrestore(&irq_lock, flags);
228 out_kfree: 217 out_kfree:
229 kfree(new_fd); 218 kfree(new_fd);
230 out: 219 out:
@@ -235,9 +224,9 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
235{ 224{
236 unsigned long flags; 225 unsigned long flags;
237 226
238 flags = irq_lock(); 227 spin_lock_irqsave(&irq_lock, flags);
239 os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr); 228 os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
240 irq_unlock(flags); 229 spin_unlock_irqrestore(&irq_lock, flags);
241} 230}
242 231
243struct irq_and_dev { 232struct irq_and_dev {
@@ -304,19 +293,19 @@ void reactivate_fd(int fd, int irqnum)
304 unsigned long flags; 293 unsigned long flags;
305 int i; 294 int i;
306 295
307 flags = irq_lock(); 296 spin_lock_irqsave(&irq_lock, flags);
308 irq = find_irq_by_fd(fd, irqnum, &i); 297 irq = find_irq_by_fd(fd, irqnum, &i);
309 if (irq == NULL) { 298 if (irq == NULL) {
310 irq_unlock(flags); 299 spin_unlock_irqrestore(&irq_lock, flags);
311 return; 300 return;
312 } 301 }
313 os_set_pollfd(i, irq->fd); 302 os_set_pollfd(i, irq->fd);
314 irq_unlock(flags); 303 spin_unlock_irqrestore(&irq_lock, flags);
315 304
316 /* This calls activate_fd, so it has to be outside the critical 305 /* This calls activate_fd, so it has to be outside the critical
317 * section. 306 * section.
318 */ 307 */
319 maybe_sigio_broken(fd, irq->type); 308 maybe_sigio_broken(fd, (irq->type == IRQ_READ));
320} 309}
321 310
322void deactivate_fd(int fd, int irqnum) 311void deactivate_fd(int fd, int irqnum)
@@ -325,13 +314,13 @@ void deactivate_fd(int fd, int irqnum)
325 unsigned long flags; 314 unsigned long flags;
326 int i; 315 int i;
327 316
328 flags = irq_lock(); 317 spin_lock_irqsave(&irq_lock, flags);
329 irq = find_irq_by_fd(fd, irqnum, &i); 318 irq = find_irq_by_fd(fd, irqnum, &i);
330 if (irq == NULL) 319 if (irq == NULL)
331 goto out; 320 goto out;
332 os_set_pollfd(i, -1); 321 os_set_pollfd(i, -1);
333 out: 322 out:
334 irq_unlock(flags); 323 spin_unlock_irqrestore(&irq_lock, flags);
335} 324}
336 325
337int deactivate_all_fds(void) 326int deactivate_all_fds(void)
@@ -350,13 +339,14 @@ int deactivate_all_fds(void)
350 return 0; 339 return 0;
351} 340}
352 341
342#ifdef CONFIG_MODE_TT
353void forward_interrupts(int pid) 343void forward_interrupts(int pid)
354{ 344{
355 struct irq_fd *irq; 345 struct irq_fd *irq;
356 unsigned long flags; 346 unsigned long flags;
357 int err; 347 int err;
358 348
359 flags = irq_lock(); 349 spin_lock_irqsave(&irq_lock, flags);
360 for (irq = active_fds; irq != NULL; irq = irq->next) { 350 for (irq = active_fds; irq != NULL; irq = irq->next) {
361 err = os_set_owner(irq->fd, pid); 351 err = os_set_owner(irq->fd, pid);
362 if (err < 0) { 352 if (err < 0) {
@@ -369,8 +359,9 @@ void forward_interrupts(int pid)
369 359
370 irq->pid = pid; 360 irq->pid = pid;
371 } 361 }
372 irq_unlock(flags); 362 spin_unlock_irqrestore(&irq_lock, flags);
373} 363}
364#endif
374 365
375/* 366/*
376 * do_IRQ handles all normal device IRQ's (the special 367 * do_IRQ handles all normal device IRQ's (the special
@@ -403,21 +394,6 @@ int um_request_irq(unsigned int irq, int fd, int type,
403EXPORT_SYMBOL(um_request_irq); 394EXPORT_SYMBOL(um_request_irq);
404EXPORT_SYMBOL(reactivate_fd); 395EXPORT_SYMBOL(reactivate_fd);
405 396
406static DEFINE_SPINLOCK(irq_spinlock);
407
408unsigned long irq_lock(void)
409{
410 unsigned long flags;
411
412 spin_lock_irqsave(&irq_spinlock, flags);
413 return flags;
414}
415
416void irq_unlock(unsigned long flags)
417{
418 spin_unlock_irqrestore(&irq_spinlock, flags);
419}
420
421/* hw_interrupt_type must define (startup || enable) && 397/* hw_interrupt_type must define (startup || enable) &&
422 * (shutdown || disable) && end */ 398 * (shutdown || disable) && end */
423static void dummy(unsigned int irq) 399static void dummy(unsigned int irq)
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 432cf0b97a13..c97045d6d89f 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -88,12 +88,6 @@ EXPORT_SYMBOL(dump_thread);
88EXPORT_SYMBOL(do_gettimeofday); 88EXPORT_SYMBOL(do_gettimeofday);
89EXPORT_SYMBOL(do_settimeofday); 89EXPORT_SYMBOL(do_settimeofday);
90 90
91/* This is here because UML expands lseek to sys_lseek, not to a system
92 * call instruction.
93 */
94EXPORT_SYMBOL(sys_lseek);
95EXPORT_SYMBOL(sys_wait4);
96
97#ifdef CONFIG_SMP 91#ifdef CONFIG_SMP
98 92
99/* required for SMP */ 93/* required for SMP */
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 44e41a35f000..61280167c560 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -24,8 +24,6 @@
24#include "init.h" 24#include "init.h"
25#include "kern_constants.h" 25#include "kern_constants.h"
26 26
27extern char __binary_start;
28
29/* Changed during early boot */ 27/* Changed during early boot */
30unsigned long *empty_zero_page = NULL; 28unsigned long *empty_zero_page = NULL;
31unsigned long *empty_bad_page = NULL; 29unsigned long *empty_bad_page = NULL;
@@ -65,8 +63,6 @@ static void setup_highmem(unsigned long highmem_start,
65 63
66void mem_init(void) 64void mem_init(void)
67{ 65{
68 unsigned long start;
69
70 max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT; 66 max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT;
71 67
72 /* clear the zero-page */ 68 /* clear the zero-page */
@@ -81,13 +77,6 @@ void mem_init(void)
81 free_bootmem(__pa(brk_end), uml_reserved - brk_end); 77 free_bootmem(__pa(brk_end), uml_reserved - brk_end);
82 uml_reserved = brk_end; 78 uml_reserved = brk_end;
83 79
84 /* Fill in any hole at the start of the binary */
85 start = (unsigned long) &__binary_start & PAGE_MASK;
86 if(uml_physmem != start){
87 map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
88 1, 1, 0);
89 }
90
91 /* this will put all low memory onto the freelists */ 80 /* this will put all low memory onto the freelists */
92 totalram_pages = free_all_bootmem(); 81 totalram_pages = free_all_bootmem();
93 totalhigh_pages = highmem >> PAGE_SHIFT; 82 totalhigh_pages = highmem >> PAGE_SHIFT;
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 166cb09cae4c..abafa64b8727 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -317,7 +317,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
317 } 317 }
318} 318}
319 319
320extern int __syscall_stub_start, __binary_start; 320extern int __syscall_stub_start;
321 321
322void setup_physmem(unsigned long start, unsigned long reserve_end, 322void setup_physmem(unsigned long start, unsigned long reserve_end,
323 unsigned long len, unsigned long long highmem) 323 unsigned long len, unsigned long long highmem)
diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio.c
index 51b677083948..0ad755ceb212 100644
--- a/arch/um/kernel/sigio_kern.c
+++ b/arch/um/kernel/sigio.c
@@ -31,7 +31,7 @@ int write_sigio_irq(int fd)
31 int err; 31 int err;
32 32
33 err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, 33 err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
34 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "write sigio", 34 IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio",
35 NULL); 35 NULL);
36 if(err){ 36 if(err){
37 printk("write_sigio_irq : um_request_irq failed, err = %d\n", 37 printk("write_sigio_irq : um_request_irq failed, err = %d\n",
@@ -53,17 +53,3 @@ void sigio_unlock(void)
53{ 53{
54 spin_unlock(&sigio_spinlock); 54 spin_unlock(&sigio_spinlock);
55} 55}
56
57extern void sigio_cleanup(void);
58__uml_exitcall(sigio_cleanup);
59
60/*
61 * Overrides for Emacs so that we follow Linus's tabbing style.
62 * Emacs will notice this stuff at the end of the file and automatically
63 * adjust the settings for this buffer only. This must remain at the end
64 * of the file.
65 * ---------------------------------------------------------------------------
66 * Local variables:
67 * c-file-style: "linux"
68 * End:
69 */
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal.c
index da17b7541e08..4aa9808ba264 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal.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 */
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(unblock_signals);
36 36
37/* 37/*
38 * OK, we're invoking a handler 38 * OK, we're invoking a handler
39 */ 39 */
40static int handle_signal(struct pt_regs *regs, unsigned long signr, 40static int handle_signal(struct pt_regs *regs, unsigned long signr,
41 struct k_sigaction *ka, siginfo_t *info, 41 struct k_sigaction *ka, siginfo_t *info,
42 sigset_t *oldset) 42 sigset_t *oldset)
@@ -88,7 +88,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
88 force_sigsegv(signr, current); 88 force_sigsegv(signr, current);
89 } else { 89 } else {
90 spin_lock_irq(&current->sighand->siglock); 90 spin_lock_irq(&current->sighand->siglock);
91 sigorsets(&current->blocked, &current->blocked, 91 sigorsets(&current->blocked, &current->blocked,
92 &ka->sa.sa_mask); 92 &ka->sa.sa_mask);
93 if(!(ka->sa.sa_flags & SA_NODEFER)) 93 if(!(ka->sa.sa_flags & SA_NODEFER))
94 sigaddset(&current->blocked, signr); 94 sigaddset(&current->blocked, signr);
@@ -136,7 +136,7 @@ static int kern_do_signal(struct pt_regs *regs)
136 PT_REGS_RESTART_SYSCALL(regs); 136 PT_REGS_RESTART_SYSCALL(regs);
137 break; 137 break;
138 case -ERESTART_RESTARTBLOCK: 138 case -ERESTART_RESTARTBLOCK:
139 PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall; 139 PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
140 PT_REGS_RESTART_SYSCALL(regs); 140 PT_REGS_RESTART_SYSCALL(regs);
141 break; 141 break;
142 } 142 }
@@ -146,7 +146,7 @@ static int kern_do_signal(struct pt_regs *regs)
146 * you set a breakpoint on a system call instruction and singlestep 146 * you set a breakpoint on a system call instruction and singlestep
147 * from it, the tracing thread used to PTRACE_SINGLESTEP the process 147 * from it, the tracing thread used to PTRACE_SINGLESTEP the process
148 * rather than PTRACE_SYSCALL it, allowing the system call to execute 148 * rather than PTRACE_SYSCALL it, allowing the system call to execute
149 * on the host. The tracing thread will check this flag and 149 * on the host. The tracing thread will check this flag and
150 * PTRACE_SYSCALL if necessary. 150 * PTRACE_SYSCALL if necessary.
151 */ 151 */
152 if(current->ptrace & PT_DTRACE) 152 if(current->ptrace & PT_DTRACE)
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index 88ab96c609ce..27bbf54b1e52 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -9,31 +9,19 @@
9#include "mem_user.h" 9#include "mem_user.h"
10#include "skas.h" 10#include "skas.h"
11 11
12unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, 12unsigned long set_task_sizes_skas(unsigned long *task_size_out)
13 unsigned long *task_size_out)
14{ 13{
15 /* Round up to the nearest 4M */ 14 /* Round up to the nearest 4M */
16 unsigned long top = ROUND_4M((unsigned long) &arg); 15 unsigned long host_task_size = ROUND_4M((unsigned long)
16 &host_task_size);
17 17
18#ifdef CONFIG_HOST_TASK_SIZE 18#ifdef CONFIG_HOST_TASK_SIZE
19 *host_size_out = CONFIG_HOST_TASK_SIZE; 19 *host_size_out = ROUND_4M(CONFIG_HOST_TASK_SIZE);
20 *task_size_out = CONFIG_HOST_TASK_SIZE; 20 *task_size_out = CONFIG_HOST_TASK_SIZE;
21#else 21#else
22 *host_size_out = top;
23 if (!skas_needs_stub) 22 if (!skas_needs_stub)
24 *task_size_out = top; 23 *task_size_out = host_task_size;
25 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; 24 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
26#endif 25#endif
27 return(((unsigned long) set_task_sizes_skas) & ~0xffffff); 26 return host_task_size;
28} 27}
29
30/*
31 * Overrides for Emacs so that we follow Linus's tabbing style.
32 * Emacs will notice this stuff at the end of the file and automatically
33 * adjust the settings for this buffer only. This must remain at the end
34 * of the file.
35 * ---------------------------------------------------------------------------
36 * Local variables:
37 * c-file-style: "linux"
38 * End:
39 */
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 2135eaf98a93..55caeec8b257 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -177,7 +177,7 @@ int start_uml_skas(void)
177 if(proc_mm) 177 if(proc_mm)
178 userspace_pid[0] = start_userspace(0); 178 userspace_pid[0] = start_userspace(0);
179 179
180 init_new_thread_signals(1); 180 init_new_thread_signals();
181 181
182 init_task.thread.request.u.thread.proc = start_kernel_proc; 182 init_task.thread.request.u.thread.proc = start_kernel_proc;
183 init_task.thread.request.u.thread.arg = NULL; 183 init_task.thread.request.u.thread.arg = NULL;
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 51fb94076fcf..0ae4eea21be4 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -18,11 +18,7 @@ void handle_syscall(union uml_pt_regs *r)
18 struct pt_regs *regs = container_of(r, struct pt_regs, regs); 18 struct pt_regs *regs = container_of(r, struct pt_regs, regs);
19 long result; 19 long result;
20 int syscall; 20 int syscall;
21#ifdef UML_CONFIG_SYSCALL_DEBUG
22 int index;
23 21
24 index = record_syscall_start(UPT_SYSCALL_NR(r));
25#endif
26 syscall_trace(r, 0); 22 syscall_trace(r, 0);
27 23
28 current->thread.nsyscalls++; 24 current->thread.nsyscalls++;
@@ -44,7 +40,4 @@ void handle_syscall(union uml_pt_regs *r)
44 REGS_SET_SYSCALL_RETURN(r->skas.regs, result); 40 REGS_SET_SYSCALL_RETURN(r->skas.regs, result);
45 41
46 syscall_trace(r, 1); 42 syscall_trace(r, 1);
47#ifdef UML_CONFIG_SYSCALL_DEBUG
48 record_syscall_end(index, result);
49#endif
50} 43}
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 1731d90e6850..48cf88dd02d4 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -1,36 +1,166 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h"
7#include "linux/file.h"
8#include "linux/smp_lock.h"
9#include "linux/mm.h"
10#include "linux/utsname.h"
11#include "linux/msg.h"
12#include "linux/shm.h"
13#include "linux/sys.h"
14#include "linux/syscalls.h"
15#include "linux/unistd.h"
16#include "linux/slab.h"
17#include "linux/utime.h"
18#include "asm/mman.h"
19#include "asm/uaccess.h"
6#include "kern_util.h" 20#include "kern_util.h"
7#include "syscall.h" 21#include "user_util.h"
8#include "os.h" 22#include "sysdep/syscalls.h"
23#include "mode_kern.h"
24#include "choose-mode.h"
9 25
10struct { 26/* Unlocked, I don't care if this is a bit off */
11 int syscall; 27int nsyscalls = 0;
12 int pid;
13 long result;
14 unsigned long long start;
15 unsigned long long end;
16} syscall_record[1024];
17 28
18int record_syscall_start(int syscall) 29long sys_fork(void)
19{ 30{
20 int max, index; 31 long ret;
21 32
22 max = sizeof(syscall_record)/sizeof(syscall_record[0]); 33 current->thread.forking = 1;
23 index = next_syscall_index(max); 34 ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
35 &current->thread.regs, 0, NULL, NULL);
36 current->thread.forking = 0;
37 return(ret);
38}
39
40long sys_vfork(void)
41{
42 long ret;
43
44 current->thread.forking = 1;
45 ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
46 UPT_SP(&current->thread.regs.regs),
47 &current->thread.regs, 0, NULL, NULL);
48 current->thread.forking = 0;
49 return(ret);
50}
51
52/* common code for old and new mmaps */
53long sys_mmap2(unsigned long addr, unsigned long len,
54 unsigned long prot, unsigned long flags,
55 unsigned long fd, unsigned long pgoff)
56{
57 long error = -EBADF;
58 struct file * file = NULL;
59
60 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
61 if (!(flags & MAP_ANONYMOUS)) {
62 file = fget(fd);
63 if (!file)
64 goto out;
65 }
66
67 down_write(&current->mm->mmap_sem);
68 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
69 up_write(&current->mm->mmap_sem);
70
71 if (file)
72 fput(file);
73 out:
74 return error;
75}
76
77long old_mmap(unsigned long addr, unsigned long len,
78 unsigned long prot, unsigned long flags,
79 unsigned long fd, unsigned long offset)
80{
81 long err = -EINVAL;
82 if (offset & ~PAGE_MASK)
83 goto out;
84
85 err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
86 out:
87 return err;
88}
89/*
90 * sys_pipe() is the normal C calling standard for creating
91 * a pipe. It's not the way unix traditionally does this, though.
92 */
93long sys_pipe(unsigned long __user * fildes)
94{
95 int fd[2];
96 long error;
97
98 error = do_pipe(fd);
99 if (!error) {
100 if (copy_to_user(fildes, fd, sizeof(fd)))
101 error = -EFAULT;
102 }
103 return error;
104}
24 105
25 syscall_record[index].syscall = syscall; 106
26 syscall_record[index].pid = current_pid(); 107long sys_uname(struct old_utsname __user * name)
27 syscall_record[index].result = 0xdeadbeef; 108{
28 syscall_record[index].start = os_nsecs(); 109 long err;
29 return(index); 110 if (!name)
111 return -EFAULT;
112 down_read(&uts_sem);
113 err = copy_to_user(name, &system_utsname, sizeof (*name));
114 up_read(&uts_sem);
115 return err?-EFAULT:0;
30} 116}
31 117
32void record_syscall_end(int index, long result) 118long sys_olduname(struct oldold_utsname __user * name)
33{ 119{
34 syscall_record[index].result = result; 120 long error;
35 syscall_record[index].end = os_nsecs(); 121
122 if (!name)
123 return -EFAULT;
124 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
125 return -EFAULT;
126
127 down_read(&uts_sem);
128
129 error = __copy_to_user(&name->sysname,&system_utsname.sysname,
130 __OLD_UTS_LEN);
131 error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
132 error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
133 __OLD_UTS_LEN);
134 error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
135 error |= __copy_to_user(&name->release,&system_utsname.release,
136 __OLD_UTS_LEN);
137 error |= __put_user(0,name->release+__OLD_UTS_LEN);
138 error |= __copy_to_user(&name->version,&system_utsname.version,
139 __OLD_UTS_LEN);
140 error |= __put_user(0,name->version+__OLD_UTS_LEN);
141 error |= __copy_to_user(&name->machine,&system_utsname.machine,
142 __OLD_UTS_LEN);
143 error |= __put_user(0,name->machine+__OLD_UTS_LEN);
144
145 up_read(&uts_sem);
146
147 error = error ? -EFAULT : 0;
148
149 return error;
150}
151
152DEFINE_SPINLOCK(syscall_lock);
153
154static int syscall_index = 0;
155
156int next_syscall_index(int limit)
157{
158 int ret;
159
160 spin_lock(&syscall_lock);
161 ret = syscall_index;
162 if(++syscall_index == limit)
163 syscall_index = 0;
164 spin_unlock(&syscall_lock);
165 return(ret);
36} 166}
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
deleted file mode 100644
index 37d3978337d8..000000000000
--- a/arch/um/kernel/syscall_kern.c
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/sched.h"
7#include "linux/file.h"
8#include "linux/smp_lock.h"
9#include "linux/mm.h"
10#include "linux/utsname.h"
11#include "linux/msg.h"
12#include "linux/shm.h"
13#include "linux/sys.h"
14#include "linux/syscalls.h"
15#include "linux/unistd.h"
16#include "linux/slab.h"
17#include "linux/utime.h"
18#include "asm/mman.h"
19#include "asm/uaccess.h"
20#include "kern_util.h"
21#include "user_util.h"
22#include "sysdep/syscalls.h"
23#include "mode_kern.h"
24#include "choose-mode.h"
25
26/* Unlocked, I don't care if this is a bit off */
27int nsyscalls = 0;
28
29long sys_fork(void)
30{
31 long ret;
32
33 current->thread.forking = 1;
34 ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
35 &current->thread.regs, 0, NULL, NULL);
36 current->thread.forking = 0;
37 return(ret);
38}
39
40long sys_vfork(void)
41{
42 long ret;
43
44 current->thread.forking = 1;
45 ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
46 UPT_SP(&current->thread.regs.regs),
47 &current->thread.regs, 0, NULL, NULL);
48 current->thread.forking = 0;
49 return(ret);
50}
51
52/* common code for old and new mmaps */
53long sys_mmap2(unsigned long addr, unsigned long len,
54 unsigned long prot, unsigned long flags,
55 unsigned long fd, unsigned long pgoff)
56{
57 long error = -EBADF;
58 struct file * file = NULL;
59
60 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
61 if (!(flags & MAP_ANONYMOUS)) {
62 file = fget(fd);
63 if (!file)
64 goto out;
65 }
66
67 down_write(&current->mm->mmap_sem);
68 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
69 up_write(&current->mm->mmap_sem);
70
71 if (file)
72 fput(file);
73 out:
74 return error;
75}
76
77long old_mmap(unsigned long addr, unsigned long len,
78 unsigned long prot, unsigned long flags,
79 unsigned long fd, unsigned long offset)
80{
81 long err = -EINVAL;
82 if (offset & ~PAGE_MASK)
83 goto out;
84
85 err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
86 out:
87 return err;
88}
89/*
90 * sys_pipe() is the normal C calling standard for creating
91 * a pipe. It's not the way unix traditionally does this, though.
92 */
93long sys_pipe(unsigned long __user * fildes)
94{
95 int fd[2];
96 long error;
97
98 error = do_pipe(fd);
99 if (!error) {
100 if (copy_to_user(fildes, fd, sizeof(fd)))
101 error = -EFAULT;
102 }
103 return error;
104}
105
106
107long sys_uname(struct old_utsname __user * name)
108{
109 long err;
110 if (!name)
111 return -EFAULT;
112 down_read(&uts_sem);
113 err=copy_to_user(name, &system_utsname, sizeof (*name));
114 up_read(&uts_sem);
115 return err?-EFAULT:0;
116}
117
118long sys_olduname(struct oldold_utsname __user * name)
119{
120 long error;
121
122 if (!name)
123 return -EFAULT;
124 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
125 return -EFAULT;
126
127 down_read(&uts_sem);
128
129 error = __copy_to_user(&name->sysname,&system_utsname.sysname,
130 __OLD_UTS_LEN);
131 error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
132 error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
133 __OLD_UTS_LEN);
134 error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
135 error |= __copy_to_user(&name->release,&system_utsname.release,
136 __OLD_UTS_LEN);
137 error |= __put_user(0,name->release+__OLD_UTS_LEN);
138 error |= __copy_to_user(&name->version,&system_utsname.version,
139 __OLD_UTS_LEN);
140 error |= __put_user(0,name->version+__OLD_UTS_LEN);
141 error |= __copy_to_user(&name->machine,&system_utsname.machine,
142 __OLD_UTS_LEN);
143 error |= __put_user(0,name->machine+__OLD_UTS_LEN);
144
145 up_read(&uts_sem);
146
147 error = error ? -EFAULT : 0;
148
149 return error;
150}
151
152DEFINE_SPINLOCK(syscall_lock);
153
154static int syscall_index = 0;
155
156int next_syscall_index(int limit)
157{
158 int ret;
159
160 spin_lock(&syscall_lock);
161 ret = syscall_index;
162 if(++syscall_index == limit)
163 syscall_index = 0;
164 spin_unlock(&syscall_lock);
165 return(ret);
166}
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time.c
index d7e044b5e5ee..552ca1cb9847 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time.c
@@ -38,7 +38,6 @@ unsigned long long sched_clock(void)
38/* Changed at early boot */ 38/* Changed at early boot */
39int timer_irq_inited = 0; 39int timer_irq_inited = 0;
40 40
41static int first_tick;
42static unsigned long long prev_nsecs; 41static unsigned long long prev_nsecs;
43#ifdef CONFIG_UML_REAL_TIME_CLOCK 42#ifdef CONFIG_UML_REAL_TIME_CLOCK
44static long long delta; /* Deviation per interval */ 43static long long delta; /* Deviation per interval */
@@ -48,15 +47,8 @@ void timer_irq(union uml_pt_regs *regs)
48{ 47{
49 unsigned long long ticks = 0; 48 unsigned long long ticks = 0;
50 49
51 if(!timer_irq_inited){
52 /* This is to ensure that ticks don't pile up when
53 * the timer handler is suspended */
54 first_tick = 0;
55 return;
56 }
57
58 if(first_tick){
59#ifdef CONFIG_UML_REAL_TIME_CLOCK 50#ifdef CONFIG_UML_REAL_TIME_CLOCK
51 if(prev_nsecs){
60 /* We've had 1 tick */ 52 /* We've had 1 tick */
61 unsigned long long nsecs = os_nsecs(); 53 unsigned long long nsecs = os_nsecs();
62 54
@@ -69,44 +61,17 @@ void timer_irq(union uml_pt_regs *regs)
69 61
70 ticks += (delta * HZ) / BILLION; 62 ticks += (delta * HZ) / BILLION;
71 delta -= (ticks * BILLION) / HZ; 63 delta -= (ticks * BILLION) / HZ;
64 }
65 else prev_nsecs = os_nsecs();
72#else 66#else
73 ticks = 1; 67 ticks = 1;
74#endif 68#endif
75 }
76 else {
77 prev_nsecs = os_nsecs();
78 first_tick = 1;
79 }
80
81 while(ticks > 0){ 69 while(ticks > 0){
82 do_IRQ(TIMER_IRQ, regs); 70 do_IRQ(TIMER_IRQ, regs);
83 ticks--; 71 ticks--;
84 } 72 }
85} 73}
86 74
87
88void time_init_kern(void)
89{
90 long long nsecs;
91
92 nsecs = os_nsecs();
93 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
94 -nsecs % BILLION);
95}
96
97void do_boot_timer_handler(struct sigcontext * sc)
98{
99 unsigned long flags;
100 struct pt_regs regs;
101
102 CHOOSE_MODE((void) (UPT_SC(&regs.regs) = sc),
103 (void) (regs.regs.skas.is_user = 0));
104
105 write_seqlock_irqsave(&xtime_lock, flags);
106 do_timer(&regs);
107 write_sequnlock_irqrestore(&xtime_lock, flags);
108}
109
110static DEFINE_SPINLOCK(timer_spinlock); 75static DEFINE_SPINLOCK(timer_spinlock);
111 76
112static unsigned long long local_offset = 0; 77static unsigned long long local_offset = 0;
@@ -142,6 +107,32 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
142 return IRQ_HANDLED; 107 return IRQ_HANDLED;
143} 108}
144 109
110static void register_timer(void)
111{
112 int err;
113
114 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
115 if(err != 0)
116 printk(KERN_ERR "timer_init : request_irq failed - "
117 "errno = %d\n", -err);
118
119 timer_irq_inited = 1;
120
121 user_time_init();
122}
123
124extern void (*late_time_init)(void);
125
126void time_init(void)
127{
128 long long nsecs;
129
130 nsecs = os_nsecs();
131 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
132 -nsecs % BILLION);
133 late_time_init = register_timer;
134}
135
145void do_gettimeofday(struct timeval *tv) 136void do_gettimeofday(struct timeval *tv)
146{ 137{
147 unsigned long long nsecs = get_time(); 138 unsigned long long nsecs = get_time();
@@ -189,18 +180,3 @@ void timer_handler(int sig, union uml_pt_regs *regs)
189 if(current_thread->cpu == 0) 180 if(current_thread->cpu == 0)
190 timer_irq(regs); 181 timer_irq(regs);
191} 182}
192
193int __init timer_init(void)
194{
195 int err;
196
197 user_time_init();
198 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
199 if(err != 0)
200 printk(KERN_ERR "timer_init : request_irq failed - "
201 "errno = %d\n", -err);
202 timer_irq_inited = 1;
203 return(0);
204}
205
206arch_initcall(timer_init);
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap.c
index 02f6d4d8dc3a..ac70fa5a2e2a 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap.c
@@ -35,7 +35,7 @@
35#include "os.h" 35#include "os.h"
36 36
37/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ 37/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
38int handle_page_fault(unsigned long address, unsigned long ip, 38int handle_page_fault(unsigned long address, unsigned long ip,
39 int is_write, int is_user, int *code_out) 39 int is_write, int is_user, int *code_out)
40{ 40{
41 struct mm_struct *mm = current->mm; 41 struct mm_struct *mm = current->mm;
@@ -55,20 +55,20 @@ int handle_page_fault(unsigned long address, unsigned long ip,
55 55
56 down_read(&mm->mmap_sem); 56 down_read(&mm->mmap_sem);
57 vma = find_vma(mm, address); 57 vma = find_vma(mm, address);
58 if(!vma) 58 if(!vma)
59 goto out; 59 goto out;
60 else if(vma->vm_start <= address) 60 else if(vma->vm_start <= address)
61 goto good_area; 61 goto good_area;
62 else if(!(vma->vm_flags & VM_GROWSDOWN)) 62 else if(!(vma->vm_flags & VM_GROWSDOWN))
63 goto out; 63 goto out;
64 else if(is_user && !ARCH_IS_STACKGROW(address)) 64 else if(is_user && !ARCH_IS_STACKGROW(address))
65 goto out; 65 goto out;
66 else if(expand_stack(vma, address)) 66 else if(expand_stack(vma, address))
67 goto out; 67 goto out;
68 68
69good_area: 69good_area:
70 *code_out = SEGV_ACCERR; 70 *code_out = SEGV_ACCERR;
71 if(is_write && !(vma->vm_flags & VM_WRITE)) 71 if(is_write && !(vma->vm_flags & VM_WRITE))
72 goto out; 72 goto out;
73 73
74 /* Don't require VM_READ|VM_EXEC for write faults! */ 74 /* Don't require VM_READ|VM_EXEC for write faults! */
@@ -184,14 +184,14 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
184 else if(catcher != NULL){ 184 else if(catcher != NULL){
185 current->thread.fault_addr = (void *) address; 185 current->thread.fault_addr = (void *) address;
186 do_longjmp(catcher, 1); 186 do_longjmp(catcher, 1);
187 } 187 }
188 else if(current->thread.fault_addr != NULL) 188 else if(current->thread.fault_addr != NULL)
189 panic("fault_addr set but no fault catcher"); 189 panic("fault_addr set but no fault catcher");
190 else if(!is_user && arch_fixup(ip, sc)) 190 else if(!is_user && arch_fixup(ip, sc))
191 return(0); 191 return(0);
192 192
193 if(!is_user) 193 if(!is_user)
194 panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", 194 panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
195 address, ip); 195 address, ip);
196 196
197 if (err == -EACCES) { 197 if (err == -EACCES) {
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 5c1e4cc1c049..ad66df17d9d7 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -21,7 +21,7 @@
21static int exec_tramp(void *sig_stack) 21static int exec_tramp(void *sig_stack)
22{ 22{
23 init_new_thread_stack(sig_stack, NULL); 23 init_new_thread_stack(sig_stack, NULL);
24 init_new_thread_signals(1); 24 init_new_thread_signals();
25 os_stop_process(os_getpid()); 25 os_stop_process(os_getpid());
26 return(0); 26 return(0);
27} 27}
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index bcb8796c3cb1..84a23b14f770 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -24,22 +24,13 @@ void before_mem_tt(unsigned long brk_start)
24#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) 24#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
25#define START (CONFIG_TOP_ADDR - SIZE) 25#define START (CONFIG_TOP_ADDR - SIZE)
26 26
27unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 27unsigned long set_task_sizes_tt(unsigned long *task_size_out)
28 unsigned long *task_size_out)
29{ 28{
29 unsigned long host_task_size;
30
30 /* Round up to the nearest 4M */ 31 /* Round up to the nearest 4M */
31 *host_size_out = ROUND_4M((unsigned long) &arg); 32 host_task_size = ROUND_4M((unsigned long) &host_task_size);
32 *task_size_out = START; 33 *task_size_out = START;
33 return(START);
34}
35 34
36/* 35 return host_task_size;
37 * Overrides for Emacs so that we follow Linus's tabbing style. 36}
38 * Emacs will notice this stuff at the end of the file and automatically
39 * adjust the settings for this buffer only. This must remain at the end
40 * of the file.
41 * ---------------------------------------------------------------------------
42 * Local variables:
43 * c-file-style: "linux"
44 * End:
45 */
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 8368c2dbe635..1e86f0bfef72 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -142,7 +142,7 @@ static void new_thread_handler(int sig)
142 schedule_tail(current->thread.prev_sched); 142 schedule_tail(current->thread.prev_sched);
143 current->thread.prev_sched = NULL; 143 current->thread.prev_sched = NULL;
144 144
145 init_new_thread_signals(1); 145 init_new_thread_signals();
146 enable_timer(); 146 enable_timer();
147 free_page(current->thread.temp_stack); 147 free_page(current->thread.temp_stack);
148 set_cmdline("(kernel thread)"); 148 set_cmdline("(kernel thread)");
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
index 3fda9a03c59a..293caa6d0c2d 100644
--- a/arch/um/kernel/tt/syscall_kern.c
+++ b/arch/um/kernel/tt/syscall_kern.c
@@ -21,18 +21,11 @@ void syscall_handler_tt(int sig, struct pt_regs *regs)
21 void *sc; 21 void *sc;
22 long result; 22 long result;
23 int syscall; 23 int syscall;
24#ifdef CONFIG_SYSCALL_DEBUG 24
25 int index;
26#endif
27 sc = UPT_SC(&regs->regs); 25 sc = UPT_SC(&regs->regs);
28 SC_START_SYSCALL(sc); 26 SC_START_SYSCALL(sc);
29 27
30 syscall = UPT_SYSCALL_NR(&regs->regs); 28 syscall = UPT_SYSCALL_NR(&regs->regs);
31
32#ifdef CONFIG_SYSCALL_DEBUG
33 index = record_syscall_start(syscall);
34#endif
35
36 syscall_trace(&regs->regs, 0); 29 syscall_trace(&regs->regs, 0);
37 30
38 current->thread.nsyscalls++; 31 current->thread.nsyscalls++;
@@ -50,7 +43,4 @@ void syscall_handler_tt(int sig, struct pt_regs *regs)
50 SC_SET_SYSCALL_RETURN(sc, result); 43 SC_SET_SYSCALL_RETURN(sc, result);
51 44
52 syscall_trace(&regs->regs, 1); 45 syscall_trace(&regs->regs, 1);
53#ifdef CONFIG_SYSCALL_DEBUG
54 record_syscall_end(index, result);
55#endif
56} 46}
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 71daae24e48a..9882342206ec 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -188,10 +188,7 @@ int tracer(int (*init_proc)(void *), void *sp)
188 int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; 188 int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
189 int proc_id = 0, n, err, old_tracing = 0, strace = 0; 189 int proc_id = 0, n, err, old_tracing = 0, strace = 0;
190 int local_using_sysemu = 0; 190 int local_using_sysemu = 0;
191#ifdef UML_CONFIG_SYSCALL_DEBUG 191
192 unsigned long eip = 0;
193 int last_index;
194#endif
195 signal(SIGPIPE, SIG_IGN); 192 signal(SIGPIPE, SIG_IGN);
196 setup_tracer_winch(); 193 setup_tracer_winch();
197 tracing_pid = os_getpid(); 194 tracing_pid = os_getpid();
@@ -282,23 +279,6 @@ int tracer(int (*init_proc)(void *), void *sp)
282 else if(WIFSTOPPED(status)){ 279 else if(WIFSTOPPED(status)){
283 proc_id = pid_to_processor_id(pid); 280 proc_id = pid_to_processor_id(pid);
284 sig = WSTOPSIG(status); 281 sig = WSTOPSIG(status);
285#ifdef UML_CONFIG_SYSCALL_DEBUG
286 if(signal_index[proc_id] == 1024){
287 signal_index[proc_id] = 0;
288 last_index = 1023;
289 }
290 else last_index = signal_index[proc_id] - 1;
291 if(((sig == SIGPROF) || (sig == SIGVTALRM) ||
292 (sig == SIGALRM)) &&
293 (signal_record[proc_id][last_index].signal == sig)&&
294 (signal_record[proc_id][last_index].pid == pid))
295 signal_index[proc_id] = last_index;
296 signal_record[proc_id][signal_index[proc_id]].pid = pid;
297 gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
298 eip = ptrace(PTRACE_PEEKUSR, pid, PT_IP_OFFSET, 0);
299 signal_record[proc_id][signal_index[proc_id]].addr = eip;
300 signal_record[proc_id][signal_index[proc_id]++].signal = sig;
301#endif
302 if(proc_id == -1){ 282 if(proc_id == -1){
303 sleeping_process_signal(pid, sig); 283 sleeping_process_signal(pid, sig);
304 continue; 284 continue;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 37cfe7701f06..7896cf98232d 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -330,6 +330,8 @@ EXPORT_SYMBOL(end_iomem);
330 330
331#define MIN_VMALLOC (32 * 1024 * 1024) 331#define MIN_VMALLOC (32 * 1024 * 1024)
332 332
333extern char __binary_start;
334
333int linux_main(int argc, char **argv) 335int linux_main(int argc, char **argv)
334{ 336{
335 unsigned long avail, diff; 337 unsigned long avail, diff;
@@ -374,8 +376,9 @@ int linux_main(int argc, char **argv)
374 376
375 printf("UML running in %s mode\n", mode); 377 printf("UML running in %s mode\n", mode);
376 378
377 uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, 379 uml_start = (unsigned long) &__binary_start;
378 &host_task_size, &task_size); 380 host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt,
381 set_task_sizes_skas, &task_size);
379 382
380 /* 383 /*
381 * Setting up handlers to 'sig_info' struct 384 * Setting up handlers to 'sig_info' struct
@@ -395,7 +398,7 @@ int linux_main(int argc, char **argv)
395 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); 398 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
396 } 399 }
397 400
398 uml_physmem = uml_start; 401 uml_physmem = uml_start & PAGE_MASK;
399 402
400 /* Reserve up to 4M after the current brk */ 403 /* Reserve up to 4M after the current brk */
401 uml_reserved = ROUND_4M(brk_start) + (1 << 22); 404 uml_reserved = ROUND_4M(brk_start) + (1 << 22);
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index af11915ce0a8..8eca47a6ff08 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -7,13 +7,16 @@ jiffies = jiffies_64;
7 7
8SECTIONS 8SECTIONS
9{ 9{
10 /*This must contain the right address - not quite the default ELF one.*/ 10 /* This must contain the right address - not quite the default ELF one.*/
11 PROVIDE (__executable_start = START); 11 PROVIDE (__executable_start = START);
12 . = START + SIZEOF_HEADERS; 12 /* Static binaries stick stuff here, like the sigreturn trampoline,
13 * invisibly to objdump. So, just make __binary_start equal to the very
14 * beginning of the executable, and if there are unmapped pages after this,
15 * they are forever unusable.
16 */
17 __binary_start = START;
13 18
14 /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start 19 . = START + SIZEOF_HEADERS;
15 * is remapped.*/
16 __binary_start = .;
17 20
18#ifdef MODE_TT 21#ifdef MODE_TT
19 .remap_data : { UNMAP_PATH (.data .bss) } 22 .remap_data : { UNMAP_PATH (.data .bss) }
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
index 72acdce205e0..f8aeb448aab6 100644
--- a/arch/um/kernel/vmlinux.lds.S
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -1,5 +1,3 @@
1/* in case the preprocessor is a 32bit one */
2#undef i386
3#ifdef CONFIG_LD_SCRIPT_STATIC 1#ifdef CONFIG_LD_SCRIPT_STATIC
4#include "uml.lds.S" 2#include "uml.lds.S"
5#else 3#else