diff options
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/exec.c | 41 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 85 | ||||
-rw-r--r-- | arch/um/kernel/physmem.c | 9 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 110 | ||||
-rw-r--r-- | arch/um/kernel/ptrace.c | 114 | ||||
-rw-r--r-- | arch/um/kernel/reboot.c | 12 | ||||
-rw-r--r-- | arch/um/kernel/signal.c | 58 | ||||
-rw-r--r-- | arch/um/kernel/skas/Makefile | 2 | ||||
-rw-r--r-- | arch/um/kernel/skas/mmu.c | 64 | ||||
-rw-r--r-- | arch/um/kernel/skas/process.c | 27 | ||||
-rw-r--r-- | arch/um/kernel/skas/syscall.c | 17 | ||||
-rw-r--r-- | arch/um/kernel/syscall.c | 38 | ||||
-rw-r--r-- | arch/um/kernel/time.c | 32 | ||||
-rw-r--r-- | arch/um/kernel/tlb.c | 158 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 74 |
15 files changed, 375 insertions, 466 deletions
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 5064fb691eb5..0d260567fd15 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c | |||
@@ -1,24 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/slab.h" | 6 | #include "linux/stddef.h" |
7 | #include "linux/fs.h" | ||
7 | #include "linux/smp_lock.h" | 8 | #include "linux/smp_lock.h" |
8 | #include "linux/ptrace.h" | 9 | #include "linux/ptrace.h" |
9 | #include "linux/fs.h" | 10 | #include "linux/sched.h" |
10 | #include "asm/ptrace.h" | 11 | #include "asm/current.h" |
11 | #include "asm/pgtable.h" | 12 | #include "asm/processor.h" |
12 | #include "asm/tlbflush.h" | ||
13 | #include "asm/uaccess.h" | 13 | #include "asm/uaccess.h" |
14 | #include "kern_util.h" | ||
15 | #include "as-layout.h" | ||
16 | #include "mem_user.h" | 14 | #include "mem_user.h" |
17 | #include "kern.h" | 15 | #include "skas.h" |
18 | #include "irq_user.h" | ||
19 | #include "tlb.h" | ||
20 | #include "os.h" | 16 | #include "os.h" |
21 | #include "skas/skas.h" | ||
22 | 17 | ||
23 | void flush_thread(void) | 18 | void flush_thread(void) |
24 | { | 19 | { |
@@ -29,8 +24,8 @@ void flush_thread(void) | |||
29 | arch_flush_thread(¤t->thread.arch); | 24 | arch_flush_thread(¤t->thread.arch); |
30 | 25 | ||
31 | ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data); | 26 | ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data); |
32 | if(ret){ | 27 | if (ret) { |
33 | printk("flush_thread - clearing address space failed, " | 28 | printk(KERN_ERR "flush_thread - clearing address space failed, " |
34 | "err = %d\n", ret); | 29 | "err = %d\n", ret); |
35 | force_sig(SIGKILL, current); | 30 | force_sig(SIGKILL, current); |
36 | } | 31 | } |
@@ -52,7 +47,7 @@ extern void log_exec(char **argv, void *tty); | |||
52 | static long execve1(char *file, char __user * __user *argv, | 47 | static long execve1(char *file, char __user * __user *argv, |
53 | char __user *__user *env) | 48 | char __user *__user *env) |
54 | { | 49 | { |
55 | long error; | 50 | long error; |
56 | #ifdef CONFIG_TTY_LOG | 51 | #ifdef CONFIG_TTY_LOG |
57 | struct tty_struct *tty; | 52 | struct tty_struct *tty; |
58 | 53 | ||
@@ -62,16 +57,16 @@ static long execve1(char *file, char __user * __user *argv, | |||
62 | log_exec(argv, tty); | 57 | log_exec(argv, tty); |
63 | mutex_unlock(&tty_mutex); | 58 | mutex_unlock(&tty_mutex); |
64 | #endif | 59 | #endif |
65 | error = do_execve(file, argv, env, ¤t->thread.regs); | 60 | error = do_execve(file, argv, env, ¤t->thread.regs); |
66 | if (error == 0){ | 61 | if (error == 0) { |
67 | task_lock(current); | 62 | task_lock(current); |
68 | current->ptrace &= ~PT_DTRACE; | 63 | current->ptrace &= ~PT_DTRACE; |
69 | #ifdef SUBARCH_EXECVE1 | 64 | #ifdef SUBARCH_EXECVE1 |
70 | SUBARCH_EXECVE1(¤t->thread.regs.regs); | 65 | SUBARCH_EXECVE1(¤t->thread.regs.regs); |
71 | #endif | 66 | #endif |
72 | task_unlock(current); | 67 | task_unlock(current); |
73 | } | 68 | } |
74 | return(error); | 69 | return error; |
75 | } | 70 | } |
76 | 71 | ||
77 | long um_execve(char *file, char __user *__user *argv, char __user *__user *env) | 72 | long um_execve(char *file, char __user *__user *argv, char __user *__user *env) |
@@ -79,9 +74,9 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env) | |||
79 | long err; | 74 | long err; |
80 | 75 | ||
81 | err = execve1(file, argv, env); | 76 | err = execve1(file, argv, env); |
82 | if(!err) | 77 | if (!err) |
83 | do_longjmp(current->thread.exec_buf, 1); | 78 | do_longjmp(current->thread.exec_buf, 1); |
84 | return(err); | 79 | return err; |
85 | } | 80 | } |
86 | 81 | ||
87 | long sys_execve(char __user *file, char __user *__user *argv, | 82 | long sys_execve(char __user *file, char __user *__user *argv, |
@@ -98,5 +93,5 @@ long sys_execve(char __user *file, char __user *__user *argv, | |||
98 | putname(filename); | 93 | putname(filename); |
99 | out: | 94 | out: |
100 | unlock_kernel(); | 95 | unlock_kernel(); |
101 | return(error); | 96 | return error; |
102 | } | 97 | } |
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index b10ee28b97cb..277fce17b088 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -1,37 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c: | 4 | * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c: |
5 | * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar | 5 | * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "linux/kernel.h" | 8 | #include "linux/cpumask.h" |
9 | #include "linux/module.h" | 9 | #include "linux/hardirq.h" |
10 | #include "linux/smp.h" | ||
11 | #include "linux/kernel_stat.h" | ||
12 | #include "linux/interrupt.h" | 10 | #include "linux/interrupt.h" |
13 | #include "linux/random.h" | 11 | #include "linux/kernel_stat.h" |
14 | #include "linux/slab.h" | 12 | #include "linux/module.h" |
15 | #include "linux/file.h" | ||
16 | #include "linux/proc_fs.h" | ||
17 | #include "linux/init.h" | ||
18 | #include "linux/seq_file.h" | 13 | #include "linux/seq_file.h" |
19 | #include "linux/profile.h" | 14 | #include "as-layout.h" |
20 | #include "linux/hardirq.h" | ||
21 | #include "asm/irq.h" | ||
22 | #include "asm/hw_irq.h" | ||
23 | #include "asm/atomic.h" | ||
24 | #include "asm/signal.h" | ||
25 | #include "asm/system.h" | ||
26 | #include "asm/errno.h" | ||
27 | #include "asm/uaccess.h" | ||
28 | #include "kern_util.h" | 15 | #include "kern_util.h" |
29 | #include "irq_user.h" | ||
30 | #include "irq_kern.h" | ||
31 | #include "os.h" | 16 | #include "os.h" |
32 | #include "sigio.h" | ||
33 | #include "misc_constants.h" | ||
34 | #include "as-layout.h" | ||
35 | 17 | ||
36 | /* | 18 | /* |
37 | * Generic, controller-independent functions: | 19 | * Generic, controller-independent functions: |
@@ -71,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
71 | seq_putc(p, '\n'); | 53 | seq_putc(p, '\n'); |
72 | skip: | 54 | skip: |
73 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 55 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
74 | } else if (i == NR_IRQS) { | 56 | } else if (i == NR_IRQS) |
75 | seq_putc(p, '\n'); | 57 | seq_putc(p, '\n'); |
76 | } | ||
77 | 58 | ||
78 | return 0; | 59 | return 0; |
79 | } | 60 | } |
@@ -102,11 +83,13 @@ void sigio_handler(int sig, struct uml_pt_regs *regs) | |||
102 | while (1) { | 83 | while (1) { |
103 | n = os_waiting_for_events(active_fds); | 84 | n = os_waiting_for_events(active_fds); |
104 | if (n <= 0) { | 85 | if (n <= 0) { |
105 | if(n == -EINTR) continue; | 86 | if (n == -EINTR) |
87 | continue; | ||
106 | else break; | 88 | else break; |
107 | } | 89 | } |
108 | 90 | ||
109 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { | 91 | for (irq_fd = active_fds; irq_fd != NULL; |
92 | irq_fd = irq_fd->next) { | ||
110 | if (irq_fd->current_events != 0) { | 93 | if (irq_fd->current_events != 0) { |
111 | irq_fd->current_events = 0; | 94 | irq_fd->current_events = 0; |
112 | do_IRQ(irq_fd->irq, regs); | 95 | do_IRQ(irq_fd->irq, regs); |
@@ -138,8 +121,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
138 | 121 | ||
139 | if (type == IRQ_READ) | 122 | if (type == IRQ_READ) |
140 | events = UM_POLLIN | UM_POLLPRI; | 123 | events = UM_POLLIN | UM_POLLPRI; |
141 | else | 124 | else events = UM_POLLOUT; |
142 | events = UM_POLLOUT; | ||
143 | *new_fd = ((struct irq_fd) { .next = NULL, | 125 | *new_fd = ((struct irq_fd) { .next = NULL, |
144 | .id = dev_id, | 126 | .id = dev_id, |
145 | .fd = fd, | 127 | .fd = fd, |
@@ -153,9 +135,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
153 | spin_lock_irqsave(&irq_lock, flags); | 135 | spin_lock_irqsave(&irq_lock, flags); |
154 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { | 136 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { |
155 | if ((irq_fd->fd == fd) && (irq_fd->type == type)) { | 137 | if ((irq_fd->fd == fd) && (irq_fd->type == type)) { |
156 | printk("Registering fd %d twice\n", fd); | 138 | printk(KERN_ERR "Registering fd %d twice\n", fd); |
157 | printk("Irqs : %d, %d\n", irq_fd->irq, irq); | 139 | printk(KERN_ERR "Irqs : %d, %d\n", irq_fd->irq, irq); |
158 | printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id); | 140 | printk(KERN_ERR "Ids : 0x%p, 0x%p\n", irq_fd->id, |
141 | dev_id); | ||
159 | goto out_unlock; | 142 | goto out_unlock; |
160 | } | 143 | } |
161 | } | 144 | } |
@@ -171,7 +154,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
171 | if (n == 0) | 154 | if (n == 0) |
172 | break; | 155 | break; |
173 | 156 | ||
174 | /* n > 0 | 157 | /* |
158 | * n > 0 | ||
175 | * It means we couldn't put new pollfd to current pollfds | 159 | * It means we couldn't put new pollfd to current pollfds |
176 | * and tmp_fds is NULL or too small for new pollfds array. | 160 | * and tmp_fds is NULL or too small for new pollfds array. |
177 | * Needed size is equal to n as minimum. | 161 | * Needed size is equal to n as minimum. |
@@ -197,7 +181,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
197 | 181 | ||
198 | spin_unlock_irqrestore(&irq_lock, flags); | 182 | spin_unlock_irqrestore(&irq_lock, flags); |
199 | 183 | ||
200 | /* This calls activate_fd, so it has to be outside the critical | 184 | /* |
185 | * This calls activate_fd, so it has to be outside the critical | ||
201 | * section. | 186 | * section. |
202 | */ | 187 | */ |
203 | maybe_sigio_broken(fd, (type == IRQ_READ)); | 188 | maybe_sigio_broken(fd, (type == IRQ_READ)); |
@@ -264,13 +249,14 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) | |||
264 | i++; | 249 | i++; |
265 | } | 250 | } |
266 | if (irq == NULL) { | 251 | if (irq == NULL) { |
267 | printk("find_irq_by_fd doesn't have descriptor %d\n", fd); | 252 | printk(KERN_ERR "find_irq_by_fd doesn't have descriptor %d\n", |
253 | fd); | ||
268 | goto out; | 254 | goto out; |
269 | } | 255 | } |
270 | fdi = os_get_pollfd(i); | 256 | fdi = os_get_pollfd(i); |
271 | if ((fdi != -1) && (fdi != fd)) { | 257 | if ((fdi != -1) && (fdi != fd)) { |
272 | printk("find_irq_by_fd - mismatch between active_fds and " | 258 | printk(KERN_ERR "find_irq_by_fd - mismatch between active_fds " |
273 | "pollfds, fd %d vs %d, need %d\n", irq->fd, | 259 | "and pollfds, fd %d vs %d, need %d\n", irq->fd, |
274 | fdi, fd); | 260 | fdi, fd); |
275 | irq = NULL; | 261 | irq = NULL; |
276 | goto out; | 262 | goto out; |
@@ -306,7 +292,7 @@ void deactivate_fd(int fd, int irqnum) | |||
306 | 292 | ||
307 | spin_lock_irqsave(&irq_lock, flags); | 293 | spin_lock_irqsave(&irq_lock, flags); |
308 | irq = find_irq_by_fd(fd, irqnum, &i); | 294 | irq = find_irq_by_fd(fd, irqnum, &i); |
309 | if(irq == NULL){ | 295 | if (irq == NULL) { |
310 | spin_unlock_irqrestore(&irq_lock, flags); | 296 | spin_unlock_irqrestore(&irq_lock, flags); |
311 | return; | 297 | return; |
312 | } | 298 | } |
@@ -372,8 +358,10 @@ int um_request_irq(unsigned int irq, int fd, int type, | |||
372 | EXPORT_SYMBOL(um_request_irq); | 358 | EXPORT_SYMBOL(um_request_irq); |
373 | EXPORT_SYMBOL(reactivate_fd); | 359 | EXPORT_SYMBOL(reactivate_fd); |
374 | 360 | ||
375 | /* hw_interrupt_type must define (startup || enable) && | 361 | /* |
376 | * (shutdown || disable) && end */ | 362 | * hw_interrupt_type must define (startup || enable) && |
363 | * (shutdown || disable) && end | ||
364 | */ | ||
377 | static void dummy(unsigned int irq) | 365 | static void dummy(unsigned int irq) |
378 | { | 366 | { |
379 | } | 367 | } |
@@ -422,7 +410,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler) | |||
422 | 410 | ||
423 | err = os_pipe(fds, 1, 1); | 411 | err = os_pipe(fds, 1, 1); |
424 | if (err) { | 412 | if (err) { |
425 | printk("init_aio_irq - os_pipe failed, err = %d\n", -err); | 413 | printk(KERN_ERR "init_aio_irq - os_pipe failed, err = %d\n", |
414 | -err); | ||
426 | goto out; | 415 | goto out; |
427 | } | 416 | } |
428 | 417 | ||
@@ -430,7 +419,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler) | |||
430 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name, | 419 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name, |
431 | (void *) (long) fds[0]); | 420 | (void *) (long) fds[0]); |
432 | if (err) { | 421 | if (err) { |
433 | printk("init_aio_irq - : um_request_irq failed, err = %d\n", | 422 | printk(KERN_ERR "init_aio_irq - : um_request_irq failed, " |
423 | "err = %d\n", | ||
434 | err); | 424 | err); |
435 | goto out_close; | 425 | goto out_close; |
436 | } | 426 | } |
@@ -501,8 +491,9 @@ unsigned long to_irq_stack(unsigned long *mask_out) | |||
501 | int nested; | 491 | int nested; |
502 | 492 | ||
503 | mask = xchg(&pending_mask, *mask_out); | 493 | mask = xchg(&pending_mask, *mask_out); |
504 | if(mask != 0){ | 494 | if (mask != 0) { |
505 | /* If any interrupts come in at this point, we want to | 495 | /* |
496 | * If any interrupts come in at this point, we want to | ||
506 | * make sure that their bits aren't lost by our | 497 | * make sure that their bits aren't lost by our |
507 | * putting our bit in. So, this loop accumulates bits | 498 | * putting our bit in. So, this loop accumulates bits |
508 | * until xchg returns the same value that we put in. | 499 | * until xchg returns the same value that we put in. |
@@ -514,13 +505,13 @@ unsigned long to_irq_stack(unsigned long *mask_out) | |||
514 | do { | 505 | do { |
515 | old |= mask; | 506 | old |= mask; |
516 | mask = xchg(&pending_mask, old); | 507 | mask = xchg(&pending_mask, old); |
517 | } while(mask != old); | 508 | } while (mask != old); |
518 | return 1; | 509 | return 1; |
519 | } | 510 | } |
520 | 511 | ||
521 | ti = current_thread_info(); | 512 | ti = current_thread_info(); |
522 | nested = (ti->real_thread != NULL); | 513 | nested = (ti->real_thread != NULL); |
523 | if(!nested){ | 514 | if (!nested) { |
524 | struct task_struct *task; | 515 | struct task_struct *task; |
525 | struct thread_info *tti; | 516 | struct thread_info *tti; |
526 | 517 | ||
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 90e89e838173..a55d221d8a4c 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c | |||
@@ -75,7 +75,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, | |||
75 | err = os_map_memory((void *) virt, fd, offset, len, r, w, x); | 75 | err = os_map_memory((void *) virt, fd, offset, len, r, w, x); |
76 | if (err) { | 76 | if (err) { |
77 | if (err == -ENOMEM) | 77 | if (err == -ENOMEM) |
78 | printk("try increasing the host's " | 78 | printk(KERN_ERR "try increasing the host's " |
79 | "/proc/sys/vm/max_map_count to <physical " | 79 | "/proc/sys/vm/max_map_count to <physical " |
80 | "memory size>/4096\n"); | 80 | "memory size>/4096\n"); |
81 | panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, " | 81 | panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, " |
@@ -103,7 +103,8 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, | |||
103 | exit(1); | 103 | exit(1); |
104 | } | 104 | } |
105 | 105 | ||
106 | /* Special kludge - This page will be mapped in to userspace processes | 106 | /* |
107 | * Special kludge - This page will be mapped in to userspace processes | ||
107 | * from physmem_fd, so it needs to be written out there. | 108 | * from physmem_fd, so it needs to be written out there. |
108 | */ | 109 | */ |
109 | os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); | 110 | os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); |
@@ -202,8 +203,8 @@ int setup_iomem(void) | |||
202 | err = os_map_memory((void *) iomem_start, region->fd, 0, | 203 | err = os_map_memory((void *) iomem_start, region->fd, 0, |
203 | region->size, 1, 1, 0); | 204 | region->size, 1, 1, 0); |
204 | if (err) | 205 | if (err) |
205 | printk("Mapping iomem region for driver '%s' failed, " | 206 | printk(KERN_ERR "Mapping iomem region for driver '%s' " |
206 | "errno = %d\n", region->driver, -err); | 207 | "failed, errno = %d\n", region->driver, -err); |
207 | else { | 208 | else { |
208 | region->virt = iomem_start; | 209 | region->virt = iomem_start; |
209 | region->phys = __pa(region->virt); | 210 | region->phys = __pa(region->virt); |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index d3b9c62e73c7..7c037fa9c5b8 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -1,51 +1,29 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Copyright 2003 PathScale, Inc. | 3 | * Copyright 2003 PathScale, Inc. |
4 | * Licensed under the GPL | 4 | * Licensed under the GPL |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "linux/kernel.h" | 7 | #include "linux/stddef.h" |
8 | #include "linux/sched.h" | 8 | #include "linux/err.h" |
9 | #include "linux/interrupt.h" | 9 | #include "linux/hardirq.h" |
10 | #include "linux/string.h" | ||
11 | #include "linux/mm.h" | 10 | #include "linux/mm.h" |
12 | #include "linux/slab.h" | 11 | #include "linux/personality.h" |
13 | #include "linux/utsname.h" | ||
14 | #include "linux/fs.h" | ||
15 | #include "linux/utime.h" | ||
16 | #include "linux/smp_lock.h" | ||
17 | #include "linux/module.h" | ||
18 | #include "linux/init.h" | ||
19 | #include "linux/capability.h" | ||
20 | #include "linux/vmalloc.h" | ||
21 | #include "linux/spinlock.h" | ||
22 | #include "linux/proc_fs.h" | 12 | #include "linux/proc_fs.h" |
23 | #include "linux/ptrace.h" | 13 | #include "linux/ptrace.h" |
24 | #include "linux/random.h" | 14 | #include "linux/random.h" |
25 | #include "linux/personality.h" | 15 | #include "linux/sched.h" |
26 | #include "asm/unistd.h" | 16 | #include "linux/threads.h" |
27 | #include "asm/mman.h" | ||
28 | #include "asm/segment.h" | ||
29 | #include "asm/stat.h" | ||
30 | #include "asm/pgtable.h" | 17 | #include "asm/pgtable.h" |
31 | #include "asm/processor.h" | ||
32 | #include "asm/tlbflush.h" | ||
33 | #include "asm/uaccess.h" | 18 | #include "asm/uaccess.h" |
34 | #include "asm/user.h" | ||
35 | #include "kern_util.h" | ||
36 | #include "as-layout.h" | 19 | #include "as-layout.h" |
37 | #include "kern.h" | 20 | #include "kern_util.h" |
38 | #include "signal_kern.h" | ||
39 | #include "init.h" | ||
40 | #include "irq_user.h" | ||
41 | #include "mem_user.h" | ||
42 | #include "tlb.h" | ||
43 | #include "frame_kern.h" | ||
44 | #include "sigcontext.h" | ||
45 | #include "os.h" | 21 | #include "os.h" |
46 | #include "skas.h" | 22 | #include "skas.h" |
23 | #include "tlb.h" | ||
47 | 24 | ||
48 | /* This is a per-cpu array. A processor only modifies its entry and it only | 25 | /* |
26 | * This is a per-cpu array. A processor only modifies its entry and it only | ||
49 | * cares about its entry, so it's OK if another processor is modifying its | 27 | * cares about its entry, so it's OK if another processor is modifying its |
50 | * entry. | 28 | * entry. |
51 | */ | 29 | */ |
@@ -54,15 +32,15 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; | |||
54 | static inline int external_pid(struct task_struct *task) | 32 | static inline int external_pid(struct task_struct *task) |
55 | { | 33 | { |
56 | /* FIXME: Need to look up userspace_pid by cpu */ | 34 | /* FIXME: Need to look up userspace_pid by cpu */ |
57 | return(userspace_pid[0]); | 35 | return userspace_pid[0]; |
58 | } | 36 | } |
59 | 37 | ||
60 | int pid_to_processor_id(int pid) | 38 | int pid_to_processor_id(int pid) |
61 | { | 39 | { |
62 | int i; | 40 | int i; |
63 | 41 | ||
64 | for(i = 0; i < ncpus; i++){ | 42 | for(i = 0; i < ncpus; i++) { |
65 | if(cpu_tasks[i].pid == pid) | 43 | if (cpu_tasks[i].pid == pid) |
66 | return i; | 44 | return i; |
67 | } | 45 | } |
68 | return -1; | 46 | return -1; |
@@ -118,7 +96,7 @@ void *_switch_to(void *prev, void *next, void *last) | |||
118 | current->thread.saved_task = NULL; | 96 | current->thread.saved_task = NULL; |
119 | 97 | ||
120 | /* XXX need to check runqueues[cpu].idle */ | 98 | /* XXX need to check runqueues[cpu].idle */ |
121 | if(current->pid == 0) | 99 | if (current->pid == 0) |
122 | switch_timers(0); | 100 | switch_timers(0); |
123 | 101 | ||
124 | switch_threads(&from->thread.switch_buf, | 102 | switch_threads(&from->thread.switch_buf, |
@@ -126,10 +104,10 @@ void *_switch_to(void *prev, void *next, void *last) | |||
126 | 104 | ||
127 | arch_switch_to(current->thread.prev_sched, current); | 105 | arch_switch_to(current->thread.prev_sched, current); |
128 | 106 | ||
129 | if(current->pid == 0) | 107 | if (current->pid == 0) |
130 | switch_timers(1); | 108 | switch_timers(1); |
131 | 109 | ||
132 | if(current->thread.saved_task) | 110 | if (current->thread.saved_task) |
133 | show_regs(&(current->thread.regs)); | 111 | show_regs(&(current->thread.regs)); |
134 | next= current->thread.saved_task; | 112 | next= current->thread.saved_task; |
135 | prev= current; | 113 | prev= current; |
@@ -141,9 +119,9 @@ void *_switch_to(void *prev, void *next, void *last) | |||
141 | 119 | ||
142 | void interrupt_end(void) | 120 | void interrupt_end(void) |
143 | { | 121 | { |
144 | if(need_resched()) | 122 | if (need_resched()) |
145 | schedule(); | 123 | schedule(); |
146 | if(test_tsk_thread_flag(current, TIF_SIGPENDING)) | 124 | if (test_tsk_thread_flag(current, TIF_SIGPENDING)) |
147 | do_signal(); | 125 | do_signal(); |
148 | } | 126 | } |
149 | 127 | ||
@@ -158,7 +136,8 @@ void *get_current(void) | |||
158 | 136 | ||
159 | extern void schedule_tail(struct task_struct *prev); | 137 | extern void schedule_tail(struct task_struct *prev); |
160 | 138 | ||
161 | /* This is called magically, by its address being stuffed in a jmp_buf | 139 | /* |
140 | * This is called magically, by its address being stuffed in a jmp_buf | ||
162 | * and being longjmp-d to. | 141 | * and being longjmp-d to. |
163 | */ | 142 | */ |
164 | void new_thread_handler(void) | 143 | void new_thread_handler(void) |
@@ -166,18 +145,19 @@ void new_thread_handler(void) | |||
166 | int (*fn)(void *), n; | 145 | int (*fn)(void *), n; |
167 | void *arg; | 146 | void *arg; |
168 | 147 | ||
169 | if(current->thread.prev_sched != NULL) | 148 | if (current->thread.prev_sched != NULL) |
170 | schedule_tail(current->thread.prev_sched); | 149 | schedule_tail(current->thread.prev_sched); |
171 | current->thread.prev_sched = NULL; | 150 | current->thread.prev_sched = NULL; |
172 | 151 | ||
173 | fn = current->thread.request.u.thread.proc; | 152 | fn = current->thread.request.u.thread.proc; |
174 | arg = current->thread.request.u.thread.arg; | 153 | arg = current->thread.request.u.thread.arg; |
175 | 154 | ||
176 | /* The return value is 1 if the kernel thread execs a process, | 155 | /* |
156 | * The return value is 1 if the kernel thread execs a process, | ||
177 | * 0 if it just exits | 157 | * 0 if it just exits |
178 | */ | 158 | */ |
179 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); | 159 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); |
180 | if(n == 1){ | 160 | if (n == 1) { |
181 | /* Handle any immediate reschedules or signals */ | 161 | /* Handle any immediate reschedules or signals */ |
182 | interrupt_end(); | 162 | interrupt_end(); |
183 | userspace(¤t->thread.regs.regs); | 163 | userspace(¤t->thread.regs.regs); |
@@ -189,14 +169,16 @@ void new_thread_handler(void) | |||
189 | void fork_handler(void) | 169 | void fork_handler(void) |
190 | { | 170 | { |
191 | force_flush_all(); | 171 | force_flush_all(); |
192 | if(current->thread.prev_sched == NULL) | 172 | if (current->thread.prev_sched == NULL) |
193 | panic("blech"); | 173 | panic("blech"); |
194 | 174 | ||
195 | schedule_tail(current->thread.prev_sched); | 175 | schedule_tail(current->thread.prev_sched); |
196 | 176 | ||
197 | /* XXX: if interrupt_end() calls schedule, this call to | 177 | /* |
178 | * XXX: if interrupt_end() calls schedule, this call to | ||
198 | * arch_switch_to isn't needed. We could want to apply this to | 179 | * arch_switch_to isn't needed. We could want to apply this to |
199 | * improve performance. -bb */ | 180 | * improve performance. -bb |
181 | */ | ||
200 | arch_switch_to(current->thread.prev_sched, current); | 182 | arch_switch_to(current->thread.prev_sched, current); |
201 | 183 | ||
202 | current->thread.prev_sched = NULL; | 184 | current->thread.prev_sched = NULL; |
@@ -216,11 +198,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | |||
216 | 198 | ||
217 | p->thread = (struct thread_struct) INIT_THREAD; | 199 | p->thread = (struct thread_struct) INIT_THREAD; |
218 | 200 | ||
219 | if(current->thread.forking){ | 201 | if (current->thread.forking) { |
220 | memcpy(&p->thread.regs.regs, ®s->regs, | 202 | memcpy(&p->thread.regs.regs, ®s->regs, |
221 | sizeof(p->thread.regs.regs)); | 203 | sizeof(p->thread.regs.regs)); |
222 | REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.regs, 0); | 204 | REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.regs, 0); |
223 | if(sp != 0) | 205 | if (sp != 0) |
224 | REGS_SP(p->thread.regs.regs.regs) = sp; | 206 | REGS_SP(p->thread.regs.regs.regs) = sp; |
225 | 207 | ||
226 | handler = fork_handler; | 208 | handler = fork_handler; |
@@ -259,14 +241,14 @@ void initial_thread_cb(void (*proc)(void *), void *arg) | |||
259 | 241 | ||
260 | void default_idle(void) | 242 | void default_idle(void) |
261 | { | 243 | { |
262 | while(1){ | 244 | while(1) { |
263 | /* endless idle loop with no priority at all */ | 245 | /* endless idle loop with no priority at all */ |
264 | 246 | ||
265 | /* | 247 | /* |
266 | * although we are an idle CPU, we do not want to | 248 | * although we are an idle CPU, we do not want to |
267 | * get into the scheduler unnecessarily. | 249 | * get into the scheduler unnecessarily. |
268 | */ | 250 | */ |
269 | if(need_resched()) | 251 | if (need_resched()) |
270 | schedule(); | 252 | schedule(); |
271 | 253 | ||
272 | idle_sleep(10); | 254 | idle_sleep(10); |
@@ -288,26 +270,26 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | |||
288 | pte_t *pte; | 270 | pte_t *pte; |
289 | pte_t ptent; | 271 | pte_t ptent; |
290 | 272 | ||
291 | if(task->mm == NULL) | 273 | if (task->mm == NULL) |
292 | return ERR_PTR(-EINVAL); | 274 | return ERR_PTR(-EINVAL); |
293 | pgd = pgd_offset(task->mm, addr); | 275 | pgd = pgd_offset(task->mm, addr); |
294 | if(!pgd_present(*pgd)) | 276 | if (!pgd_present(*pgd)) |
295 | return ERR_PTR(-EINVAL); | 277 | return ERR_PTR(-EINVAL); |
296 | 278 | ||
297 | pud = pud_offset(pgd, addr); | 279 | pud = pud_offset(pgd, addr); |
298 | if(!pud_present(*pud)) | 280 | if (!pud_present(*pud)) |
299 | return ERR_PTR(-EINVAL); | 281 | return ERR_PTR(-EINVAL); |
300 | 282 | ||
301 | pmd = pmd_offset(pud, addr); | 283 | pmd = pmd_offset(pud, addr); |
302 | if(!pmd_present(*pmd)) | 284 | if (!pmd_present(*pmd)) |
303 | return ERR_PTR(-EINVAL); | 285 | return ERR_PTR(-EINVAL); |
304 | 286 | ||
305 | pte = pte_offset_kernel(pmd, addr); | 287 | pte = pte_offset_kernel(pmd, addr); |
306 | ptent = *pte; | 288 | ptent = *pte; |
307 | if(!pte_present(ptent)) | 289 | if (!pte_present(ptent)) |
308 | return ERR_PTR(-EINVAL); | 290 | return ERR_PTR(-EINVAL); |
309 | 291 | ||
310 | if(pte_out != NULL) | 292 | if (pte_out != NULL) |
311 | *pte_out = ptent; | 293 | *pte_out = ptent; |
312 | return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); | 294 | return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); |
313 | } | 295 | } |
@@ -380,7 +362,7 @@ int smp_sigio_handler(void) | |||
380 | #ifdef CONFIG_SMP | 362 | #ifdef CONFIG_SMP |
381 | int cpu = current_thread->cpu; | 363 | int cpu = current_thread->cpu; |
382 | IPI_handler(cpu); | 364 | IPI_handler(cpu); |
383 | if(cpu != 0) | 365 | if (cpu != 0) |
384 | return 1; | 366 | return 1; |
385 | #endif | 367 | #endif |
386 | return 0; | 368 | return 0; |
@@ -408,7 +390,8 @@ int get_using_sysemu(void) | |||
408 | 390 | ||
409 | static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) | 391 | static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) |
410 | { | 392 | { |
411 | if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ | 393 | if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) |
394 | /* No overflow */ | ||
412 | *eof = 1; | 395 | *eof = 1; |
413 | 396 | ||
414 | return strlen(buf); | 397 | return strlen(buf); |
@@ -423,7 +406,8 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned | |||
423 | 406 | ||
424 | if (tmp[0] >= '0' && tmp[0] <= '2') | 407 | if (tmp[0] >= '0' && tmp[0] <= '2') |
425 | set_using_sysemu(tmp[0] - '0'); | 408 | set_using_sysemu(tmp[0] - '0'); |
426 | return count; /*We use the first char, but pretend to write everything*/ | 409 | /* We use the first char, but pretend to write everything */ |
410 | return count; | ||
427 | } | 411 | } |
428 | 412 | ||
429 | int __init make_proc_sysemu(void) | 413 | int __init make_proc_sysemu(void) |
@@ -453,10 +437,10 @@ int singlestepping(void * t) | |||
453 | struct task_struct *task = t ? t : current; | 437 | struct task_struct *task = t ? t : current; |
454 | 438 | ||
455 | if ( ! (task->ptrace & PT_DTRACE) ) | 439 | if ( ! (task->ptrace & PT_DTRACE) ) |
456 | return(0); | 440 | return 0; |
457 | 441 | ||
458 | if (task->thread.singlestep_syscall) | 442 | if (task->thread.singlestep_syscall) |
459 | return(1); | 443 | return 1; |
460 | 444 | ||
461 | return 2; | 445 | return 2; |
462 | } | 446 | } |
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index bbc3a4a9a0fa..db55a017e9b9 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -1,35 +1,27 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/sched.h" | ||
7 | #include "linux/mm.h" | ||
8 | #include "linux/errno.h" | ||
9 | #include "linux/smp_lock.h" | ||
10 | #include "linux/security.h" | ||
11 | #include "linux/ptrace.h" | ||
12 | #include "linux/audit.h" | 6 | #include "linux/audit.h" |
7 | #include "linux/ptrace.h" | ||
8 | #include "linux/sched.h" | ||
9 | #include "asm/uaccess.h" | ||
13 | #ifdef CONFIG_PROC_MM | 10 | #ifdef CONFIG_PROC_MM |
14 | #include "linux/proc_mm.h" | 11 | #include "proc_mm.h" |
15 | #endif | 12 | #endif |
16 | #include "asm/ptrace.h" | ||
17 | #include "asm/uaccess.h" | ||
18 | #include "kern_util.h" | ||
19 | #include "skas_ptrace.h" | 13 | #include "skas_ptrace.h" |
20 | #include "sysdep/ptrace.h" | ||
21 | #include "os.h" | ||
22 | 14 | ||
23 | static inline void set_singlestepping(struct task_struct *child, int on) | 15 | static inline void set_singlestepping(struct task_struct *child, int on) |
24 | { | 16 | { |
25 | if (on) | 17 | if (on) |
26 | child->ptrace |= PT_DTRACE; | 18 | child->ptrace |= PT_DTRACE; |
27 | else | 19 | else |
28 | child->ptrace &= ~PT_DTRACE; | 20 | child->ptrace &= ~PT_DTRACE; |
29 | child->thread.singlestep_syscall = 0; | 21 | child->thread.singlestep_syscall = 0; |
30 | 22 | ||
31 | #ifdef SUBARCH_SET_SINGLESTEPPING | 23 | #ifdef SUBARCH_SET_SINGLESTEPPING |
32 | SUBARCH_SET_SINGLESTEPPING(child, on); | 24 | SUBARCH_SET_SINGLESTEPPING(child, on); |
33 | #endif | 25 | #endif |
34 | } | 26 | } |
35 | 27 | ||
@@ -37,8 +29,8 @@ static inline void set_singlestepping(struct task_struct *child, int on) | |||
37 | * Called by kernel/ptrace.c when detaching.. | 29 | * Called by kernel/ptrace.c when detaching.. |
38 | */ | 30 | */ |
39 | void ptrace_disable(struct task_struct *child) | 31 | void ptrace_disable(struct task_struct *child) |
40 | { | 32 | { |
41 | set_singlestepping(child,0); | 33 | set_singlestepping(child,0); |
42 | } | 34 | } |
43 | 35 | ||
44 | extern int peek_user(struct task_struct * child, long addr, long data); | 36 | extern int peek_user(struct task_struct * child, long addr, long data); |
@@ -50,40 +42,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
50 | unsigned long __user *p = (void __user *)(unsigned long)data; | 42 | unsigned long __user *p = (void __user *)(unsigned long)data; |
51 | 43 | ||
52 | switch (request) { | 44 | switch (request) { |
53 | /* when I and D space are separate, these will need to be fixed. */ | 45 | /* read word at location addr. */ |
54 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | 46 | case PTRACE_PEEKTEXT: |
55 | case PTRACE_PEEKDATA: | 47 | case PTRACE_PEEKDATA: |
56 | ret = generic_ptrace_peekdata(child, addr, data); | 48 | ret = generic_ptrace_peekdata(child, addr, data); |
57 | break; | 49 | break; |
58 | 50 | ||
59 | /* read the word at location addr in the USER area. */ | 51 | /* read the word at location addr in the USER area. */ |
60 | case PTRACE_PEEKUSR: | 52 | case PTRACE_PEEKUSR: |
61 | ret = peek_user(child, addr, data); | 53 | ret = peek_user(child, addr, data); |
62 | break; | 54 | break; |
63 | 55 | ||
64 | /* when I and D space are separate, this will have to be fixed. */ | 56 | /* write the word at location addr. */ |
65 | case PTRACE_POKETEXT: /* write the word at location addr. */ | 57 | case PTRACE_POKETEXT: |
66 | case PTRACE_POKEDATA: | 58 | case PTRACE_POKEDATA: |
67 | ret = generic_ptrace_pokedata(child, addr, data); | 59 | ret = generic_ptrace_pokedata(child, addr, data); |
68 | break; | 60 | break; |
69 | 61 | ||
70 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 62 | /* write the word at location addr in the USER area */ |
71 | ret = poke_user(child, addr, data); | 63 | case PTRACE_POKEUSR: |
72 | break; | 64 | ret = poke_user(child, addr, data); |
65 | break; | ||
73 | 66 | ||
74 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 67 | /* continue and stop at next (return from) syscall */ |
75 | case PTRACE_CONT: { /* restart after signal. */ | 68 | case PTRACE_SYSCALL: |
69 | /* restart after signal. */ | ||
70 | case PTRACE_CONT: { | ||
76 | ret = -EIO; | 71 | ret = -EIO; |
77 | if (!valid_signal(data)) | 72 | if (!valid_signal(data)) |
78 | break; | 73 | break; |
79 | 74 | ||
80 | set_singlestepping(child, 0); | 75 | set_singlestepping(child, 0); |
81 | if (request == PTRACE_SYSCALL) { | 76 | if (request == PTRACE_SYSCALL) |
82 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 77 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
83 | } | 78 | else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
84 | else { | ||
85 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
86 | } | ||
87 | child->exit_code = data; | 79 | child->exit_code = data; |
88 | wake_up_process(child); | 80 | wake_up_process(child); |
89 | ret = 0; | 81 | ret = 0; |
@@ -91,8 +83,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
91 | } | 83 | } |
92 | 84 | ||
93 | /* | 85 | /* |
94 | * make the child exit. Best I can do is send it a sigkill. | 86 | * make the child exit. Best I can do is send it a sigkill. |
95 | * perhaps it should be put in the status that it wants to | 87 | * perhaps it should be put in the status that it wants to |
96 | * exit. | 88 | * exit. |
97 | */ | 89 | */ |
98 | case PTRACE_KILL: { | 90 | case PTRACE_KILL: { |
@@ -100,7 +92,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
100 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | 92 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ |
101 | break; | 93 | break; |
102 | 94 | ||
103 | set_singlestepping(child, 0); | 95 | set_singlestepping(child, 0); |
104 | child->exit_code = SIGKILL; | 96 | child->exit_code = SIGKILL; |
105 | wake_up_process(child); | 97 | wake_up_process(child); |
106 | break; | 98 | break; |
@@ -111,7 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
111 | if (!valid_signal(data)) | 103 | if (!valid_signal(data)) |
112 | break; | 104 | break; |
113 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 105 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
114 | set_singlestepping(child, 1); | 106 | set_singlestepping(child, 1); |
115 | child->exit_code = data; | 107 | child->exit_code = data; |
116 | /* give it a chance to run. */ | 108 | /* give it a chance to run. */ |
117 | wake_up_process(child); | 109 | wake_up_process(child); |
@@ -180,13 +172,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
180 | break; | 172 | break; |
181 | 173 | ||
182 | case PTRACE_FAULTINFO: { | 174 | case PTRACE_FAULTINFO: { |
183 | /* Take the info from thread->arch->faultinfo, | 175 | /* |
176 | * Take the info from thread->arch->faultinfo, | ||
184 | * but transfer max. sizeof(struct ptrace_faultinfo). | 177 | * but transfer max. sizeof(struct ptrace_faultinfo). |
185 | * On i386, ptrace_faultinfo is smaller! | 178 | * On i386, ptrace_faultinfo is smaller! |
186 | */ | 179 | */ |
187 | ret = copy_to_user(p, &child->thread.arch.faultinfo, | 180 | ret = copy_to_user(p, &child->thread.arch.faultinfo, |
188 | sizeof(struct ptrace_faultinfo)); | 181 | sizeof(struct ptrace_faultinfo)); |
189 | if(ret) | 182 | if (ret) |
190 | break; | 183 | break; |
191 | break; | 184 | break; |
192 | } | 185 | } |
@@ -195,12 +188,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
195 | case PTRACE_LDT: { | 188 | case PTRACE_LDT: { |
196 | struct ptrace_ldt ldt; | 189 | struct ptrace_ldt ldt; |
197 | 190 | ||
198 | if(copy_from_user(&ldt, p, sizeof(ldt))){ | 191 | if (copy_from_user(&ldt, p, sizeof(ldt))) { |
199 | ret = -EIO; | 192 | ret = -EIO; |
200 | break; | 193 | break; |
201 | } | 194 | } |
202 | 195 | ||
203 | /* This one is confusing, so just punt and return -EIO for | 196 | /* |
197 | * This one is confusing, so just punt and return -EIO for | ||
204 | * now | 198 | * now |
205 | */ | 199 | */ |
206 | ret = -EIO; | 200 | ret = -EIO; |
@@ -212,7 +206,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
212 | struct mm_struct *old = child->mm; | 206 | struct mm_struct *old = child->mm; |
213 | struct mm_struct *new = proc_mm_get_mm(data); | 207 | struct mm_struct *new = proc_mm_get_mm(data); |
214 | 208 | ||
215 | if(IS_ERR(new)){ | 209 | if (IS_ERR(new)) { |
216 | ret = PTR_ERR(new); | 210 | ret = PTR_ERR(new); |
217 | break; | 211 | break; |
218 | } | 212 | } |
@@ -226,10 +220,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
226 | } | 220 | } |
227 | #endif | 221 | #endif |
228 | #ifdef PTRACE_ARCH_PRCTL | 222 | #ifdef PTRACE_ARCH_PRCTL |
229 | case PTRACE_ARCH_PRCTL: | 223 | case PTRACE_ARCH_PRCTL: |
230 | /* XXX Calls ptrace on the host - needs some SMP thinking */ | 224 | /* XXX Calls ptrace on the host - needs some SMP thinking */ |
231 | ret = arch_prctl(child, data, (void *) addr); | 225 | ret = arch_prctl(child, data, (void *) addr); |
232 | break; | 226 | break; |
233 | #endif | 227 | #endif |
234 | default: | 228 | default: |
235 | ret = ptrace_request(child, request, addr, data); | 229 | ret = ptrace_request(child, request, addr, data); |
@@ -255,7 +249,8 @@ void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, | |||
255 | force_sig_info(SIGTRAP, &info, tsk); | 249 | force_sig_info(SIGTRAP, &info, tsk); |
256 | } | 250 | } |
257 | 251 | ||
258 | /* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and | 252 | /* |
253 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and | ||
259 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check | 254 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check |
260 | */ | 255 | */ |
261 | void syscall_trace(struct uml_pt_regs *regs, int entryexit) | 256 | void syscall_trace(struct uml_pt_regs *regs, int entryexit) |
@@ -272,7 +267,7 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit) | |||
272 | UPT_SYSCALL_ARG3(regs), | 267 | UPT_SYSCALL_ARG3(regs), |
273 | UPT_SYSCALL_ARG4(regs)); | 268 | UPT_SYSCALL_ARG4(regs)); |
274 | else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), | 269 | else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), |
275 | UPT_SYSCALL_RET(regs)); | 270 | UPT_SYSCALL_RET(regs)); |
276 | } | 271 | } |
277 | 272 | ||
278 | /* Fake a debug trap */ | 273 | /* Fake a debug trap */ |
@@ -285,15 +280,18 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit) | |||
285 | if (!(current->ptrace & PT_PTRACED)) | 280 | if (!(current->ptrace & PT_PTRACED)) |
286 | return; | 281 | return; |
287 | 282 | ||
288 | /* the 0x80 provides a way for the tracing parent to distinguish | 283 | /* |
289 | between a syscall stop and SIGTRAP delivery */ | 284 | * the 0x80 provides a way for the tracing parent to distinguish |
285 | * between a syscall stop and SIGTRAP delivery | ||
286 | */ | ||
290 | tracesysgood = (current->ptrace & PT_TRACESYSGOOD); | 287 | tracesysgood = (current->ptrace & PT_TRACESYSGOOD); |
291 | ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); | 288 | ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); |
292 | 289 | ||
293 | if (entryexit) /* force do_signal() --> is_syscall() */ | 290 | if (entryexit) /* force do_signal() --> is_syscall() */ |
294 | set_thread_flag(TIF_SIGPENDING); | 291 | set_thread_flag(TIF_SIGPENDING); |
295 | 292 | ||
296 | /* this isn't the same as continuing with a signal, but it will do | 293 | /* |
294 | * this isn't the same as continuing with a signal, but it will do | ||
297 | * for normal use. strace only continues with a signal if the | 295 | * for normal use. strace only continues with a signal if the |
298 | * stopping signal is not SIGTRAP. -brl | 296 | * stopping signal is not SIGTRAP. -brl |
299 | */ | 297 | */ |
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index f3bd18bbf07f..9d8eea47a0fc 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c | |||
@@ -1,13 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/module.h" | ||
7 | #include "linux/sched.h" | 6 | #include "linux/sched.h" |
8 | #include "asm/smp.h" | ||
9 | #include "kern_util.h" | ||
10 | #include "kern.h" | ||
11 | #include "os.h" | 7 | #include "os.h" |
12 | #include "skas.h" | 8 | #include "skas.h" |
13 | 9 | ||
@@ -37,20 +33,20 @@ static void kill_off_processes(void) | |||
37 | 33 | ||
38 | void uml_cleanup(void) | 34 | void uml_cleanup(void) |
39 | { | 35 | { |
40 | kmalloc_ok = 0; | 36 | kmalloc_ok = 0; |
41 | do_uml_exitcalls(); | 37 | do_uml_exitcalls(); |
42 | kill_off_processes(); | 38 | kill_off_processes(); |
43 | } | 39 | } |
44 | 40 | ||
45 | void machine_restart(char * __unused) | 41 | void machine_restart(char * __unused) |
46 | { | 42 | { |
47 | uml_cleanup(); | 43 | uml_cleanup(); |
48 | reboot_skas(); | 44 | reboot_skas(); |
49 | } | 45 | } |
50 | 46 | ||
51 | void machine_power_off(void) | 47 | void machine_power_off(void) |
52 | { | 48 | { |
53 | uml_cleanup(); | 49 | uml_cleanup(); |
54 | halt_skas(); | 50 | halt_skas(); |
55 | } | 51 | } |
56 | 52 | ||
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index 4dab7e417ba9..19cb97733937 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c | |||
@@ -1,27 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/stddef.h" | ||
7 | #include "linux/sys.h" | ||
8 | #include "linux/sched.h" | ||
9 | #include "linux/wait.h" | ||
10 | #include "linux/kernel.h" | ||
11 | #include "linux/smp_lock.h" | ||
12 | #include "linux/module.h" | 6 | #include "linux/module.h" |
13 | #include "linux/slab.h" | ||
14 | #include "linux/tty.h" | ||
15 | #include "linux/binfmts.h" | ||
16 | #include "linux/ptrace.h" | 7 | #include "linux/ptrace.h" |
8 | #include "linux/sched.h" | ||
9 | #include "asm/siginfo.h" | ||
17 | #include "asm/signal.h" | 10 | #include "asm/signal.h" |
18 | #include "asm/uaccess.h" | ||
19 | #include "asm/unistd.h" | 11 | #include "asm/unistd.h" |
20 | #include "asm/ucontext.h" | ||
21 | #include "kern_util.h" | ||
22 | #include "signal_kern.h" | ||
23 | #include "kern.h" | ||
24 | #include "frame_kern.h" | 12 | #include "frame_kern.h" |
13 | #include "kern_util.h" | ||
25 | #include "sigcontext.h" | 14 | #include "sigcontext.h" |
26 | 15 | ||
27 | EXPORT_SYMBOL(block_signals); | 16 | EXPORT_SYMBOL(block_signals); |
@@ -45,9 +34,9 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, | |||
45 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 34 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
46 | 35 | ||
47 | /* Did we come from a system call? */ | 36 | /* Did we come from a system call? */ |
48 | if(PT_REGS_SYSCALL_NR(regs) >= 0){ | 37 | if (PT_REGS_SYSCALL_NR(regs) >= 0) { |
49 | /* If so, check system call restarting.. */ | 38 | /* If so, check system call restarting.. */ |
50 | switch(PT_REGS_SYSCALL_RET(regs)){ | 39 | switch(PT_REGS_SYSCALL_RET(regs)) { |
51 | case -ERESTART_RESTARTBLOCK: | 40 | case -ERESTART_RESTARTBLOCK: |
52 | case -ERESTARTNOHAND: | 41 | case -ERESTARTNOHAND: |
53 | PT_REGS_SYSCALL_RET(regs) = -EINTR; | 42 | PT_REGS_SYSCALL_RET(regs) = -EINTR; |
@@ -67,17 +56,17 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, | |||
67 | } | 56 | } |
68 | 57 | ||
69 | sp = PT_REGS_SP(regs); | 58 | sp = PT_REGS_SP(regs); |
70 | if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) | 59 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) |
71 | sp = current->sas_ss_sp + current->sas_ss_size; | 60 | sp = current->sas_ss_sp + current->sas_ss_size; |
72 | 61 | ||
73 | #ifdef CONFIG_ARCH_HAS_SC_SIGNALS | 62 | #ifdef CONFIG_ARCH_HAS_SC_SIGNALS |
74 | if(!(ka->sa.sa_flags & SA_SIGINFO)) | 63 | if (!(ka->sa.sa_flags & SA_SIGINFO)) |
75 | err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); | 64 | err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); |
76 | else | 65 | else |
77 | #endif | 66 | #endif |
78 | err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); | 67 | err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); |
79 | 68 | ||
80 | if(err){ | 69 | if (err) { |
81 | spin_lock_irq(¤t->sighand->siglock); | 70 | spin_lock_irq(¤t->sighand->siglock); |
82 | current->blocked = *oldset; | 71 | current->blocked = *oldset; |
83 | recalc_sigpending(); | 72 | recalc_sigpending(); |
@@ -87,7 +76,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, | |||
87 | spin_lock_irq(¤t->sighand->siglock); | 76 | spin_lock_irq(¤t->sighand->siglock); |
88 | sigorsets(¤t->blocked, ¤t->blocked, | 77 | sigorsets(¤t->blocked, ¤t->blocked, |
89 | &ka->sa.sa_mask); | 78 | &ka->sa.sa_mask); |
90 | if(!(ka->sa.sa_flags & SA_NODEFER)) | 79 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
91 | sigaddset(¤t->blocked, signr); | 80 | sigaddset(¤t->blocked, signr); |
92 | recalc_sigpending(); | 81 | recalc_sigpending(); |
93 | spin_unlock_irq(¤t->sighand->siglock); | 82 | spin_unlock_irq(¤t->sighand->siglock); |
@@ -108,14 +97,16 @@ static int kern_do_signal(struct pt_regs *regs) | |||
108 | else | 97 | else |
109 | oldset = ¤t->blocked; | 98 | oldset = ¤t->blocked; |
110 | 99 | ||
111 | while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){ | 100 | while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { |
112 | handled_sig = 1; | 101 | handled_sig = 1; |
113 | /* Whee! Actually deliver the signal. */ | 102 | /* Whee! Actually deliver the signal. */ |
114 | if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){ | 103 | if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) { |
115 | /* a signal was successfully delivered; the saved | 104 | /* |
105 | * a signal was successfully delivered; the saved | ||
116 | * sigmask will have been stored in the signal frame, | 106 | * sigmask will have been stored in the signal frame, |
117 | * and will be restored by sigreturn, so we can simply | 107 | * and will be restored by sigreturn, so we can simply |
118 | * clear the TIF_RESTORE_SIGMASK flag */ | 108 | * clear the TIF_RESTORE_SIGMASK flag |
109 | */ | ||
119 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 110 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
120 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 111 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
121 | break; | 112 | break; |
@@ -123,9 +114,9 @@ static int kern_do_signal(struct pt_regs *regs) | |||
123 | } | 114 | } |
124 | 115 | ||
125 | /* Did we come from a system call? */ | 116 | /* Did we come from a system call? */ |
126 | if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){ | 117 | if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { |
127 | /* Restart the system call - no handlers present */ | 118 | /* Restart the system call - no handlers present */ |
128 | switch(PT_REGS_SYSCALL_RET(regs)){ | 119 | switch(PT_REGS_SYSCALL_RET(regs)) { |
129 | case -ERESTARTNOHAND: | 120 | case -ERESTARTNOHAND: |
130 | case -ERESTARTSYS: | 121 | case -ERESTARTSYS: |
131 | case -ERESTARTNOINTR: | 122 | case -ERESTARTNOINTR: |
@@ -136,22 +127,25 @@ static int kern_do_signal(struct pt_regs *regs) | |||
136 | PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; | 127 | PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; |
137 | PT_REGS_RESTART_SYSCALL(regs); | 128 | PT_REGS_RESTART_SYSCALL(regs); |
138 | break; | 129 | break; |
139 | } | 130 | } |
140 | } | 131 | } |
141 | 132 | ||
142 | /* This closes a way to execute a system call on the host. If | 133 | /* |
134 | * This closes a way to execute a system call on the host. If | ||
143 | * you set a breakpoint on a system call instruction and singlestep | 135 | * you set a breakpoint on a system call instruction and singlestep |
144 | * from it, the tracing thread used to PTRACE_SINGLESTEP the process | 136 | * from it, the tracing thread used to PTRACE_SINGLESTEP the process |
145 | * rather than PTRACE_SYSCALL it, allowing the system call to execute | 137 | * rather than PTRACE_SYSCALL it, allowing the system call to execute |
146 | * on the host. The tracing thread will check this flag and | 138 | * on the host. The tracing thread will check this flag and |
147 | * PTRACE_SYSCALL if necessary. | 139 | * PTRACE_SYSCALL if necessary. |
148 | */ | 140 | */ |
149 | if(current->ptrace & PT_DTRACE) | 141 | if (current->ptrace & PT_DTRACE) |
150 | current->thread.singlestep_syscall = | 142 | current->thread.singlestep_syscall = |
151 | is_syscall(PT_REGS_IP(¤t->thread.regs)); | 143 | is_syscall(PT_REGS_IP(¤t->thread.regs)); |
152 | 144 | ||
153 | /* if there's no signal to deliver, we just put the saved sigmask | 145 | /* |
154 | * back */ | 146 | * if there's no signal to deliver, we just put the saved sigmask |
147 | * back | ||
148 | */ | ||
155 | if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { | 149 | if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { |
156 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 150 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
157 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 151 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index b2823cdd783e..0b76d8869c94 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # | 1 | # |
2 | # Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) | 2 | # Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | # Licensed under the GPL | 3 | # Licensed under the GPL |
4 | # | 4 | # |
5 | 5 | ||
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 902d74138952..c5475ecd9fd4 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c | |||
@@ -1,20 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/sched.h" | ||
7 | #include "linux/list.h" | ||
8 | #include "linux/spinlock.h" | ||
9 | #include "linux/slab.h" | ||
10 | #include "linux/errno.h" | ||
11 | #include "linux/mm.h" | 6 | #include "linux/mm.h" |
12 | #include "asm/current.h" | 7 | #include "linux/sched.h" |
13 | #include "asm/segment.h" | ||
14 | #include "asm/mmu.h" | ||
15 | #include "asm/pgalloc.h" | 8 | #include "asm/pgalloc.h" |
16 | #include "asm/pgtable.h" | 9 | #include "asm/pgtable.h" |
17 | #include "asm/ldt.h" | ||
18 | #include "os.h" | 10 | #include "os.h" |
19 | #include "skas.h" | 11 | #include "skas.h" |
20 | 12 | ||
@@ -41,10 +33,11 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, | |||
41 | if (!pte) | 33 | if (!pte) |
42 | goto out_pte; | 34 | goto out_pte; |
43 | 35 | ||
44 | /* There's an interaction between the skas0 stub pages, stack | 36 | /* |
37 | * There's an interaction between the skas0 stub pages, stack | ||
45 | * randomization, and the BUG at the end of exit_mmap. exit_mmap | 38 | * randomization, and the BUG at the end of exit_mmap. exit_mmap |
46 | * checks that the number of page tables freed is the same as had | 39 | * checks that the number of page tables freed is the same as had |
47 | * been allocated. If the stack is on the last page table page, | 40 | * been allocated. If the stack is on the last page table page, |
48 | * then the stack pte page will be freed, and if not, it won't. To | 41 | * then the stack pte page will be freed, and if not, it won't. To |
49 | * avoid having to know where the stack is, or if the process mapped | 42 | * avoid having to know where the stack is, or if the process mapped |
50 | * something at the top of its address space for some other reason, | 43 | * something at the top of its address space for some other reason, |
@@ -54,36 +47,37 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, | |||
54 | * destroy_context_skas. | 47 | * destroy_context_skas. |
55 | */ | 48 | */ |
56 | 49 | ||
57 | mm->context.skas.last_page_table = pmd_page_vaddr(*pmd); | 50 | mm->context.skas.last_page_table = pmd_page_vaddr(*pmd); |
58 | #ifdef CONFIG_3_LEVEL_PGTABLES | 51 | #ifdef CONFIG_3_LEVEL_PGTABLES |
59 | mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); | 52 | mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); |
60 | #endif | 53 | #endif |
61 | 54 | ||
62 | *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); | 55 | *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); |
63 | *pte = pte_mkread(*pte); | 56 | *pte = pte_mkread(*pte); |
64 | return(0); | 57 | return 0; |
65 | 58 | ||
66 | out_pmd: | 59 | out_pmd: |
67 | pud_free(pud); | 60 | pud_free(pud); |
68 | out_pte: | 61 | out_pte: |
69 | pmd_free(pmd); | 62 | pmd_free(pmd); |
70 | out: | 63 | out: |
71 | return(-ENOMEM); | 64 | return -ENOMEM; |
72 | } | 65 | } |
73 | 66 | ||
74 | int init_new_context(struct task_struct *task, struct mm_struct *mm) | 67 | int init_new_context(struct task_struct *task, struct mm_struct *mm) |
75 | { | 68 | { |
76 | struct mmu_context_skas *from_mm = NULL; | 69 | struct mmu_context_skas *from_mm = NULL; |
77 | struct mmu_context_skas *to_mm = &mm->context.skas; | 70 | struct mmu_context_skas *to_mm = &mm->context.skas; |
78 | unsigned long stack = 0; | 71 | unsigned long stack = 0; |
79 | int ret = -ENOMEM; | 72 | int ret = -ENOMEM; |
80 | 73 | ||
81 | if(skas_needs_stub){ | 74 | if (skas_needs_stub) { |
82 | stack = get_zeroed_page(GFP_KERNEL); | 75 | stack = get_zeroed_page(GFP_KERNEL); |
83 | if(stack == 0) | 76 | if (stack == 0) |
84 | goto out; | 77 | goto out; |
85 | 78 | ||
86 | /* This zeros the entry that pgd_alloc didn't, needed since | 79 | /* |
80 | * This zeros the entry that pgd_alloc didn't, needed since | ||
87 | * we are about to reinitialize it, and want mm.nr_ptes to | 81 | * we are about to reinitialize it, and want mm.nr_ptes to |
88 | * be accurate. | 82 | * be accurate. |
89 | */ | 83 | */ |
@@ -91,39 +85,39 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) | |||
91 | 85 | ||
92 | ret = init_stub_pte(mm, CONFIG_STUB_CODE, | 86 | ret = init_stub_pte(mm, CONFIG_STUB_CODE, |
93 | (unsigned long) &__syscall_stub_start); | 87 | (unsigned long) &__syscall_stub_start); |
94 | if(ret) | 88 | if (ret) |
95 | goto out_free; | 89 | goto out_free; |
96 | 90 | ||
97 | ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); | 91 | ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); |
98 | if(ret) | 92 | if (ret) |
99 | goto out_free; | 93 | goto out_free; |
100 | 94 | ||
101 | mm->nr_ptes--; | 95 | mm->nr_ptes--; |
102 | } | 96 | } |
103 | 97 | ||
104 | to_mm->id.stack = stack; | 98 | to_mm->id.stack = stack; |
105 | if(current->mm != NULL && current->mm != &init_mm) | 99 | if (current->mm != NULL && current->mm != &init_mm) |
106 | from_mm = ¤t->mm->context.skas; | 100 | from_mm = ¤t->mm->context.skas; |
107 | 101 | ||
108 | if(proc_mm){ | 102 | if (proc_mm) { |
109 | ret = new_mm(stack); | 103 | ret = new_mm(stack); |
110 | if(ret < 0){ | 104 | if (ret < 0) { |
111 | printk("init_new_context_skas - new_mm failed, " | 105 | printk(KERN_ERR "init_new_context_skas - " |
112 | "errno = %d\n", ret); | 106 | "new_mm failed, errno = %d\n", ret); |
113 | goto out_free; | 107 | goto out_free; |
114 | } | 108 | } |
115 | to_mm->id.u.mm_fd = ret; | 109 | to_mm->id.u.mm_fd = ret; |
116 | } | 110 | } |
117 | else { | 111 | else { |
118 | if(from_mm) | 112 | if (from_mm) |
119 | to_mm->id.u.pid = copy_context_skas0(stack, | 113 | to_mm->id.u.pid = copy_context_skas0(stack, |
120 | from_mm->id.u.pid); | 114 | from_mm->id.u.pid); |
121 | else to_mm->id.u.pid = start_userspace(stack); | 115 | else to_mm->id.u.pid = start_userspace(stack); |
122 | } | 116 | } |
123 | 117 | ||
124 | ret = init_new_ldt(to_mm, from_mm); | 118 | ret = init_new_ldt(to_mm, from_mm); |
125 | if(ret < 0){ | 119 | if (ret < 0) { |
126 | printk("init_new_context_skas - init_ldt" | 120 | printk(KERN_ERR "init_new_context_skas - init_ldt" |
127 | " failed, errno = %d\n", ret); | 121 | " failed, errno = %d\n", ret); |
128 | goto out_free; | 122 | goto out_free; |
129 | } | 123 | } |
@@ -131,7 +125,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) | |||
131 | return 0; | 125 | return 0; |
132 | 126 | ||
133 | out_free: | 127 | out_free: |
134 | if(to_mm->id.stack != 0) | 128 | if (to_mm->id.stack != 0) |
135 | free_page(to_mm->id.stack); | 129 | free_page(to_mm->id.stack); |
136 | out: | 130 | out: |
137 | return ret; | 131 | return ret; |
@@ -141,12 +135,12 @@ void destroy_context(struct mm_struct *mm) | |||
141 | { | 135 | { |
142 | struct mmu_context_skas *mmu = &mm->context.skas; | 136 | struct mmu_context_skas *mmu = &mm->context.skas; |
143 | 137 | ||
144 | if(proc_mm) | 138 | if (proc_mm) |
145 | os_close_file(mmu->id.u.mm_fd); | 139 | os_close_file(mmu->id.u.mm_fd); |
146 | else | 140 | else |
147 | os_kill_ptraced_process(mmu->id.u.pid, 1); | 141 | os_kill_ptraced_process(mmu->id.u.pid, 1); |
148 | 142 | ||
149 | if(!proc_mm || !ptrace_faultinfo){ | 143 | if (!proc_mm || !ptrace_faultinfo) { |
150 | free_page(mmu->id.stack); | 144 | free_page(mmu->id.stack); |
151 | pte_lock_deinit(virt_to_page(mmu->last_page_table)); | 145 | pte_lock_deinit(virt_to_page(mmu->last_page_table)); |
152 | pte_free_kernel((pte_t *) mmu->last_page_table); | 146 | pte_free_kernel((pte_t *) mmu->last_page_table); |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index dabae62d52be..9ce1c49421f8 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -1,36 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/sched.h" | ||
7 | #include "linux/slab.h" | ||
8 | #include "linux/ptrace.h" | ||
9 | #include "linux/proc_fs.h" | ||
10 | #include "linux/file.h" | ||
11 | #include "linux/errno.h" | ||
12 | #include "linux/init.h" | 6 | #include "linux/init.h" |
13 | #include "asm/uaccess.h" | 7 | #include "linux/sched.h" |
14 | #include "asm/atomic.h" | ||
15 | #include "kern_util.h" | ||
16 | #include "as-layout.h" | 8 | #include "as-layout.h" |
17 | #include "skas.h" | ||
18 | #include "os.h" | 9 | #include "os.h" |
19 | #include "tlb.h" | 10 | #include "skas.h" |
20 | #include "kern.h" | ||
21 | #include "registers.h" | ||
22 | |||
23 | extern void schedule_tail(struct task_struct *prev); | ||
24 | 11 | ||
25 | int new_mm(unsigned long stack) | 12 | int new_mm(unsigned long stack) |
26 | { | 13 | { |
27 | int fd; | 14 | int fd; |
28 | 15 | ||
29 | fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); | 16 | fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); |
30 | if(fd < 0) | 17 | if (fd < 0) |
31 | return fd; | 18 | return fd; |
32 | 19 | ||
33 | if(skas_needs_stub) | 20 | if (skas_needs_stub) |
34 | map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); | 21 | map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); |
35 | 22 | ||
36 | return fd; | 23 | return fd; |
@@ -62,7 +49,7 @@ int __init start_uml(void) | |||
62 | { | 49 | { |
63 | stack_protections((unsigned long) &cpu0_irqstack); | 50 | stack_protections((unsigned long) &cpu0_irqstack); |
64 | set_sigstack(cpu0_irqstack, THREAD_SIZE); | 51 | set_sigstack(cpu0_irqstack, THREAD_SIZE); |
65 | if(proc_mm) | 52 | if (proc_mm) |
66 | userspace_pid[0] = start_userspace(0); | 53 | userspace_pid[0] = start_userspace(0); |
67 | 54 | ||
68 | init_new_thread_signals(); | 55 | init_new_thread_signals(); |
@@ -75,7 +62,7 @@ int __init start_uml(void) | |||
75 | 62 | ||
76 | unsigned long current_stub_stack(void) | 63 | unsigned long current_stub_stack(void) |
77 | { | 64 | { |
78 | if(current->mm == NULL) | 65 | if (current->mm == NULL) |
79 | return 0; | 66 | return 0; |
80 | 67 | ||
81 | return current->mm->context.skas.id.stack; | 68 | return current->mm->context.skas.id.stack; |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index e183da633c89..8582c1331048 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -1,17 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/sys.h" | 6 | #include "linux/kernel.h" |
7 | #include "linux/ptrace.h" | 7 | #include "linux/ptrace.h" |
8 | #include "asm/errno.h" | ||
9 | #include "asm/unistd.h" | ||
10 | #include "asm/ptrace.h" | ||
11 | #include "asm/current.h" | ||
12 | #include "sysdep/syscalls.h" | ||
13 | #include "kern_util.h" | 8 | #include "kern_util.h" |
14 | #include "syscall.h" | 9 | #include "sysdep/ptrace.h" |
10 | #include "sysdep/syscalls.h" | ||
15 | 11 | ||
16 | void handle_syscall(struct uml_pt_regs *r) | 12 | void handle_syscall(struct uml_pt_regs *r) |
17 | { | 13 | { |
@@ -24,7 +20,8 @@ void handle_syscall(struct uml_pt_regs *r) | |||
24 | current->thread.nsyscalls++; | 20 | current->thread.nsyscalls++; |
25 | nsyscalls++; | 21 | nsyscalls++; |
26 | 22 | ||
27 | /* This should go in the declaration of syscall, but when I do that, | 23 | /* |
24 | * This should go in the declaration of syscall, but when I do that, | ||
28 | * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing | 25 | * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing |
29 | * children at all, sometimes hanging when bash doesn't see the first | 26 | * children at all, sometimes hanging when bash doesn't see the first |
30 | * ls exit. | 27 | * ls exit. |
@@ -33,7 +30,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
33 | * in case it's a compiler bug. | 30 | * in case it's a compiler bug. |
34 | */ | 31 | */ |
35 | syscall = UPT_SYSCALL_NR(r); | 32 | syscall = UPT_SYSCALL_NR(r); |
36 | if((syscall >= NR_syscalls) || (syscall < 0)) | 33 | if ((syscall >= NR_syscalls) || (syscall < 0)) |
37 | result = -ENOSYS; | 34 | result = -ENOSYS; |
38 | else result = EXECUTE_SYSCALL(syscall, regs); | 35 | else result = EXECUTE_SYSCALL(syscall, regs); |
39 | 36 | ||
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index ebb29f5259a9..b9d92b2089ae 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -1,25 +1,17 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.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" | 6 | #include "linux/file.h" |
8 | #include "linux/smp_lock.h" | ||
9 | #include "linux/mm.h" | ||
10 | #include "linux/fs.h" | 7 | #include "linux/fs.h" |
8 | #include "linux/mm.h" | ||
9 | #include "linux/sched.h" | ||
11 | #include "linux/utsname.h" | 10 | #include "linux/utsname.h" |
12 | #include "linux/msg.h" | 11 | #include "asm/current.h" |
13 | #include "linux/shm.h" | ||
14 | #include "linux/sys.h" | ||
15 | #include "linux/syscalls.h" | ||
16 | #include "linux/unistd.h" | ||
17 | #include "linux/slab.h" | ||
18 | #include "linux/utime.h" | ||
19 | #include "asm/mman.h" | 12 | #include "asm/mman.h" |
20 | #include "asm/uaccess.h" | 13 | #include "asm/uaccess.h" |
21 | #include "kern_util.h" | 14 | #include "asm/unistd.h" |
22 | #include "sysdep/syscalls.h" | ||
23 | 15 | ||
24 | /* Unlocked, I don't care if this is a bit off */ | 16 | /* Unlocked, I don't care if this is a bit off */ |
25 | int nsyscalls = 0; | 17 | int nsyscalls = 0; |
@@ -32,7 +24,7 @@ long sys_fork(void) | |||
32 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), | 24 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), |
33 | ¤t->thread.regs, 0, NULL, NULL); | 25 | ¤t->thread.regs, 0, NULL, NULL); |
34 | current->thread.forking = 0; | 26 | current->thread.forking = 0; |
35 | return(ret); | 27 | return ret; |
36 | } | 28 | } |
37 | 29 | ||
38 | long sys_vfork(void) | 30 | long sys_vfork(void) |
@@ -44,7 +36,7 @@ long sys_vfork(void) | |||
44 | UPT_SP(¤t->thread.regs.regs), | 36 | UPT_SP(¤t->thread.regs.regs), |
45 | ¤t->thread.regs, 0, NULL, NULL); | 37 | ¤t->thread.regs, 0, NULL, NULL); |
46 | current->thread.forking = 0; | 38 | current->thread.forking = 0; |
47 | return(ret); | 39 | return ret; |
48 | } | 40 | } |
49 | 41 | ||
50 | /* common code for old and new mmaps */ | 42 | /* common code for old and new mmaps */ |
@@ -90,15 +82,15 @@ long old_mmap(unsigned long addr, unsigned long len, | |||
90 | */ | 82 | */ |
91 | long sys_pipe(unsigned long __user * fildes) | 83 | long sys_pipe(unsigned long __user * fildes) |
92 | { | 84 | { |
93 | int fd[2]; | 85 | int fd[2]; |
94 | long error; | 86 | long error; |
95 | 87 | ||
96 | error = do_pipe(fd); | 88 | error = do_pipe(fd); |
97 | if (!error) { | 89 | if (!error) { |
98 | if (copy_to_user(fildes, fd, sizeof(fd))) | 90 | if (copy_to_user(fildes, fd, sizeof(fd))) |
99 | error = -EFAULT; | 91 | error = -EFAULT; |
100 | } | 92 | } |
101 | return error; | 93 | return error; |
102 | } | 94 | } |
103 | 95 | ||
104 | 96 | ||
@@ -122,7 +114,7 @@ long sys_olduname(struct oldold_utsname __user * name) | |||
122 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) | 114 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) |
123 | return -EFAULT; | 115 | return -EFAULT; |
124 | 116 | ||
125 | down_read(&uts_sem); | 117 | down_read(&uts_sem); |
126 | 118 | ||
127 | error = __copy_to_user(&name->sysname, &utsname()->sysname, | 119 | error = __copy_to_user(&name->sysname, &utsname()->sysname, |
128 | __OLD_UTS_LEN); | 120 | __OLD_UTS_LEN); |
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 90e24e2dbeaa..4fc8c2586b70 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -1,28 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/kernel.h" | ||
7 | #include "linux/module.h" | ||
8 | #include "linux/unistd.h" | ||
9 | #include "linux/stddef.h" | ||
10 | #include "linux/spinlock.h" | ||
11 | #include "linux/time.h" | ||
12 | #include "linux/sched.h" | ||
13 | #include "linux/interrupt.h" | 6 | #include "linux/interrupt.h" |
14 | #include "linux/init.h" | 7 | #include "linux/jiffies.h" |
15 | #include "linux/delay.h" | 8 | #include "linux/threads.h" |
16 | #include "linux/hrtimer.h" | ||
17 | #include "asm/irq.h" | 9 | #include "asm/irq.h" |
18 | #include "asm/param.h" | 10 | #include "asm/param.h" |
19 | #include "asm/current.h" | ||
20 | #include "kern_util.h" | 11 | #include "kern_util.h" |
21 | #include "os.h" | 12 | #include "os.h" |
22 | 13 | ||
23 | int hz(void) | 14 | int hz(void) |
24 | { | 15 | { |
25 | return(HZ); | 16 | return HZ; |
26 | } | 17 | } |
27 | 18 | ||
28 | /* | 19 | /* |
@@ -43,7 +34,7 @@ void timer_irq(struct uml_pt_regs *regs) | |||
43 | unsigned long long ticks = 0; | 34 | unsigned long long ticks = 0; |
44 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | 35 | #ifdef CONFIG_UML_REAL_TIME_CLOCK |
45 | int c = cpu(); | 36 | int c = cpu(); |
46 | if(prev_nsecs[c]){ | 37 | if (prev_nsecs[c]) { |
47 | /* We've had 1 tick */ | 38 | /* We've had 1 tick */ |
48 | unsigned long long nsecs = os_nsecs(); | 39 | unsigned long long nsecs = os_nsecs(); |
49 | 40 | ||
@@ -51,7 +42,7 @@ void timer_irq(struct uml_pt_regs *regs) | |||
51 | prev_nsecs[c] = nsecs; | 42 | prev_nsecs[c] = nsecs; |
52 | 43 | ||
53 | /* Protect against the host clock being set backwards */ | 44 | /* Protect against the host clock being set backwards */ |
54 | if(delta[c] < 0) | 45 | if (delta[c] < 0) |
55 | delta[c] = 0; | 46 | delta[c] = 0; |
56 | 47 | ||
57 | ticks += (delta[c] * HZ) / BILLION; | 48 | ticks += (delta[c] * HZ) / BILLION; |
@@ -61,7 +52,7 @@ void timer_irq(struct uml_pt_regs *regs) | |||
61 | #else | 52 | #else |
62 | ticks = 1; | 53 | ticks = 1; |
63 | #endif | 54 | #endif |
64 | while(ticks > 0){ | 55 | while (ticks > 0) { |
65 | do_IRQ(TIMER_IRQ, regs); | 56 | do_IRQ(TIMER_IRQ, regs); |
66 | ticks--; | 57 | ticks--; |
67 | } | 58 | } |
@@ -112,12 +103,12 @@ static void register_timer(void) | |||
112 | int err; | 103 | int err; |
113 | 104 | ||
114 | err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); | 105 | err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); |
115 | if(err != 0) | 106 | if (err != 0) |
116 | printk(KERN_ERR "register_timer : request_irq failed - " | 107 | printk(KERN_ERR "register_timer : request_irq failed - " |
117 | "errno = %d\n", -err); | 108 | "errno = %d\n", -err); |
118 | 109 | ||
119 | err = set_interval(1); | 110 | err = set_interval(1); |
120 | if(err != 0) | 111 | if (err != 0) |
121 | printk(KERN_ERR "register_timer : set_interval failed - " | 112 | printk(KERN_ERR "register_timer : set_interval failed - " |
122 | "errno = %d\n", -err); | 113 | "errno = %d\n", -err); |
123 | } | 114 | } |
@@ -144,7 +135,8 @@ void do_gettimeofday(struct timeval *tv) | |||
144 | xtime.tv_nsec; | 135 | xtime.tv_nsec; |
145 | #endif | 136 | #endif |
146 | tv->tv_sec = nsecs / NSEC_PER_SEC; | 137 | tv->tv_sec = nsecs / NSEC_PER_SEC; |
147 | /* Careful about calculations here - this was originally done as | 138 | /* |
139 | * Careful about calculations here - this was originally done as | ||
148 | * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC | 140 | * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC |
149 | * which gave bogus (> 1000000) values. Dunno why, suspect gcc | 141 | * which gave bogus (> 1000000) values. Dunno why, suspect gcc |
150 | * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion | 142 | * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion |
@@ -176,7 +168,7 @@ int do_settimeofday(struct timespec *tv) | |||
176 | 168 | ||
177 | void timer_handler(int sig, struct uml_pt_regs *regs) | 169 | void timer_handler(int sig, struct uml_pt_regs *regs) |
178 | { | 170 | { |
179 | if(current_thread->cpu == 0) | 171 | if (current_thread->cpu == 0) |
180 | timer_irq(regs); | 172 | timer_irq(regs); |
181 | local_irq_disable(); | 173 | local_irq_disable(); |
182 | irq_enter(); | 174 | irq_enter(); |
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 12b8c637527d..849922fcfb60 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c | |||
@@ -1,19 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/mm.h" | 6 | #include "linux/mm.h" |
7 | #include "asm/page.h" | ||
8 | #include "asm/pgalloc.h" | ||
9 | #include "asm/pgtable.h" | 7 | #include "asm/pgtable.h" |
10 | #include "asm/tlbflush.h" | 8 | #include "asm/tlbflush.h" |
11 | #include "as-layout.h" | 9 | #include "as-layout.h" |
12 | #include "tlb.h" | ||
13 | #include "mem.h" | ||
14 | #include "mem_user.h" | 10 | #include "mem_user.h" |
15 | #include "os.h" | 11 | #include "os.h" |
16 | #include "skas.h" | 12 | #include "skas.h" |
13 | #include "tlb.h" | ||
17 | 14 | ||
18 | static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, | 15 | static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, |
19 | unsigned int prot, struct host_vm_op *ops, int *index, | 16 | unsigned int prot, struct host_vm_op *ops, int *index, |
@@ -26,18 +23,18 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, | |||
26 | int fd, ret = 0; | 23 | int fd, ret = 0; |
27 | 24 | ||
28 | fd = phys_mapping(phys, &offset); | 25 | fd = phys_mapping(phys, &offset); |
29 | if(*index != -1){ | 26 | if (*index != -1) { |
30 | last = &ops[*index]; | 27 | last = &ops[*index]; |
31 | if((last->type == MMAP) && | 28 | if ((last->type == MMAP) && |
32 | (last->u.mmap.addr + last->u.mmap.len == virt) && | 29 | (last->u.mmap.addr + last->u.mmap.len == virt) && |
33 | (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && | 30 | (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && |
34 | (last->u.mmap.offset + last->u.mmap.len == offset)){ | 31 | (last->u.mmap.offset + last->u.mmap.len == offset)) { |
35 | last->u.mmap.len += len; | 32 | last->u.mmap.len += len; |
36 | return 0; | 33 | return 0; |
37 | } | 34 | } |
38 | } | 35 | } |
39 | 36 | ||
40 | if(*index == last_filled){ | 37 | if (*index == last_filled) { |
41 | ret = (*do_ops)(mmu, ops, last_filled, 0, flush); | 38 | ret = (*do_ops)(mmu, ops, last_filled, 0, flush); |
42 | *index = -1; | 39 | *index = -1; |
43 | } | 40 | } |
@@ -62,16 +59,16 @@ static int add_munmap(unsigned long addr, unsigned long len, | |||
62 | struct host_vm_op *last; | 59 | struct host_vm_op *last; |
63 | int ret = 0; | 60 | int ret = 0; |
64 | 61 | ||
65 | if(*index != -1){ | 62 | if (*index != -1) { |
66 | last = &ops[*index]; | 63 | last = &ops[*index]; |
67 | if((last->type == MUNMAP) && | 64 | if ((last->type == MUNMAP) && |
68 | (last->u.munmap.addr + last->u.mmap.len == addr)){ | 65 | (last->u.munmap.addr + last->u.mmap.len == addr)) { |
69 | last->u.munmap.len += len; | 66 | last->u.munmap.len += len; |
70 | return 0; | 67 | return 0; |
71 | } | 68 | } |
72 | } | 69 | } |
73 | 70 | ||
74 | if(*index == last_filled){ | 71 | if (*index == last_filled) { |
75 | ret = (*do_ops)(mmu, ops, last_filled, 0, flush); | 72 | ret = (*do_ops)(mmu, ops, last_filled, 0, flush); |
76 | *index = -1; | 73 | *index = -1; |
77 | } | 74 | } |
@@ -92,17 +89,17 @@ static int add_mprotect(unsigned long addr, unsigned long len, | |||
92 | struct host_vm_op *last; | 89 | struct host_vm_op *last; |
93 | int ret = 0; | 90 | int ret = 0; |
94 | 91 | ||
95 | if(*index != -1){ | 92 | if (*index != -1) { |
96 | last = &ops[*index]; | 93 | last = &ops[*index]; |
97 | if((last->type == MPROTECT) && | 94 | if ((last->type == MPROTECT) && |
98 | (last->u.mprotect.addr + last->u.mprotect.len == addr) && | 95 | (last->u.mprotect.addr + last->u.mprotect.len == addr) && |
99 | (last->u.mprotect.prot == prot)){ | 96 | (last->u.mprotect.prot == prot)) { |
100 | last->u.mprotect.len += len; | 97 | last->u.mprotect.len += len; |
101 | return 0; | 98 | return 0; |
102 | } | 99 | } |
103 | } | 100 | } |
104 | 101 | ||
105 | if(*index == last_filled){ | 102 | if (*index == last_filled) { |
106 | ret = (*do_ops)(mmu, ops, last_filled, 0, flush); | 103 | ret = (*do_ops)(mmu, ops, last_filled, 0, flush); |
107 | *index = -1; | 104 | *index = -1; |
108 | } | 105 | } |
@@ -141,15 +138,15 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr, | |||
141 | } | 138 | } |
142 | prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | | 139 | prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | |
143 | (x ? UM_PROT_EXEC : 0)); | 140 | (x ? UM_PROT_EXEC : 0)); |
144 | if(force || pte_newpage(*pte)){ | 141 | if (force || pte_newpage(*pte)) { |
145 | if(pte_present(*pte)) | 142 | if (pte_present(*pte)) |
146 | ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, | 143 | ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, |
147 | PAGE_SIZE, prot, ops, op_index, | 144 | PAGE_SIZE, prot, ops, op_index, |
148 | last_op, mmu, flush, do_ops); | 145 | last_op, mmu, flush, do_ops); |
149 | else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, | 146 | else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, |
150 | last_op, mmu, flush, do_ops); | 147 | last_op, mmu, flush, do_ops); |
151 | } | 148 | } |
152 | else if(pte_newprot(*pte)) | 149 | else if (pte_newprot(*pte)) |
153 | ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, | 150 | ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, |
154 | last_op, mmu, flush, do_ops); | 151 | last_op, mmu, flush, do_ops); |
155 | *pte = pte_mkuptodate(*pte); | 152 | *pte = pte_mkuptodate(*pte); |
@@ -172,8 +169,8 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr, | |||
172 | pmd = pmd_offset(pud, addr); | 169 | pmd = pmd_offset(pud, addr); |
173 | do { | 170 | do { |
174 | next = pmd_addr_end(addr, end); | 171 | next = pmd_addr_end(addr, end); |
175 | if(!pmd_present(*pmd)){ | 172 | if (!pmd_present(*pmd)) { |
176 | if(force || pmd_newpage(*pmd)){ | 173 | if (force || pmd_newpage(*pmd)) { |
177 | ret = add_munmap(addr, next - addr, ops, | 174 | ret = add_munmap(addr, next - addr, ops, |
178 | op_index, last_op, mmu, | 175 | op_index, last_op, mmu, |
179 | flush, do_ops); | 176 | flush, do_ops); |
@@ -202,8 +199,8 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr, | |||
202 | pud = pud_offset(pgd, addr); | 199 | pud = pud_offset(pgd, addr); |
203 | do { | 200 | do { |
204 | next = pud_addr_end(addr, end); | 201 | next = pud_addr_end(addr, end); |
205 | if(!pud_present(*pud)){ | 202 | if (!pud_present(*pud)) { |
206 | if(force || pud_newpage(*pud)){ | 203 | if (force || pud_newpage(*pud)) { |
207 | ret = add_munmap(addr, next - addr, ops, | 204 | ret = add_munmap(addr, next - addr, ops, |
208 | op_index, last_op, mmu, | 205 | op_index, last_op, mmu, |
209 | flush, do_ops); | 206 | flush, do_ops); |
@@ -233,8 +230,8 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, | |||
233 | pgd = pgd_offset(mm, addr); | 230 | pgd = pgd_offset(mm, addr); |
234 | do { | 231 | do { |
235 | next = pgd_addr_end(addr, end_addr); | 232 | next = pgd_addr_end(addr, end_addr); |
236 | if(!pgd_present(*pgd)){ | 233 | if (!pgd_present(*pgd)) { |
237 | if (force || pgd_newpage(*pgd)){ | 234 | if (force || pgd_newpage(*pgd)) { |
238 | ret = add_munmap(addr, next - addr, ops, | 235 | ret = add_munmap(addr, next - addr, ops, |
239 | &op_index, last_op, mmu, | 236 | &op_index, last_op, mmu, |
240 | &flush, do_ops); | 237 | &flush, do_ops); |
@@ -246,12 +243,13 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, | |||
246 | do_ops); | 243 | do_ops); |
247 | } while (pgd++, addr = next, ((addr != end_addr) && !ret)); | 244 | } while (pgd++, addr = next, ((addr != end_addr) && !ret)); |
248 | 245 | ||
249 | if(!ret) | 246 | if (!ret) |
250 | ret = (*do_ops)(mmu, ops, op_index, 1, &flush); | 247 | ret = (*do_ops)(mmu, ops, op_index, 1, &flush); |
251 | 248 | ||
252 | /* This is not an else because ret is modified above */ | 249 | /* This is not an else because ret is modified above */ |
253 | if(ret) { | 250 | if (ret) { |
254 | printk("fix_range_common: failed, killing current process\n"); | 251 | printk(KERN_ERR "fix_range_common: failed, killing current " |
252 | "process\n"); | ||
255 | force_sig(SIGKILL, current); | 253 | force_sig(SIGKILL, current); |
256 | } | 254 | } |
257 | } | 255 | } |
@@ -267,17 +265,17 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) | |||
267 | int updated = 0, err; | 265 | int updated = 0, err; |
268 | 266 | ||
269 | mm = &init_mm; | 267 | mm = &init_mm; |
270 | for(addr = start; addr < end;){ | 268 | for (addr = start; addr < end;) { |
271 | pgd = pgd_offset(mm, addr); | 269 | pgd = pgd_offset(mm, addr); |
272 | if(!pgd_present(*pgd)){ | 270 | if (!pgd_present(*pgd)) { |
273 | last = ADD_ROUND(addr, PGDIR_SIZE); | 271 | last = ADD_ROUND(addr, PGDIR_SIZE); |
274 | if(last > end) | 272 | if (last > end) |
275 | last = end; | 273 | last = end; |
276 | if(pgd_newpage(*pgd)){ | 274 | if (pgd_newpage(*pgd)) { |
277 | updated = 1; | 275 | updated = 1; |
278 | err = os_unmap_memory((void *) addr, | 276 | err = os_unmap_memory((void *) addr, |
279 | last - addr); | 277 | last - addr); |
280 | if(err < 0) | 278 | if (err < 0) |
281 | panic("munmap failed, errno = %d\n", | 279 | panic("munmap failed, errno = %d\n", |
282 | -err); | 280 | -err); |
283 | } | 281 | } |
@@ -286,15 +284,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) | |||
286 | } | 284 | } |
287 | 285 | ||
288 | pud = pud_offset(pgd, addr); | 286 | pud = pud_offset(pgd, addr); |
289 | if(!pud_present(*pud)){ | 287 | if (!pud_present(*pud)) { |
290 | last = ADD_ROUND(addr, PUD_SIZE); | 288 | last = ADD_ROUND(addr, PUD_SIZE); |
291 | if(last > end) | 289 | if (last > end) |
292 | last = end; | 290 | last = end; |
293 | if(pud_newpage(*pud)){ | 291 | if (pud_newpage(*pud)) { |
294 | updated = 1; | 292 | updated = 1; |
295 | err = os_unmap_memory((void *) addr, | 293 | err = os_unmap_memory((void *) addr, |
296 | last - addr); | 294 | last - addr); |
297 | if(err < 0) | 295 | if (err < 0) |
298 | panic("munmap failed, errno = %d\n", | 296 | panic("munmap failed, errno = %d\n", |
299 | -err); | 297 | -err); |
300 | } | 298 | } |
@@ -303,15 +301,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) | |||
303 | } | 301 | } |
304 | 302 | ||
305 | pmd = pmd_offset(pud, addr); | 303 | pmd = pmd_offset(pud, addr); |
306 | if(!pmd_present(*pmd)){ | 304 | if (!pmd_present(*pmd)) { |
307 | last = ADD_ROUND(addr, PMD_SIZE); | 305 | last = ADD_ROUND(addr, PMD_SIZE); |
308 | if(last > end) | 306 | if (last > end) |
309 | last = end; | 307 | last = end; |
310 | if(pmd_newpage(*pmd)){ | 308 | if (pmd_newpage(*pmd)) { |
311 | updated = 1; | 309 | updated = 1; |
312 | err = os_unmap_memory((void *) addr, | 310 | err = os_unmap_memory((void *) addr, |
313 | last - addr); | 311 | last - addr); |
314 | if(err < 0) | 312 | if (err < 0) |
315 | panic("munmap failed, errno = %d\n", | 313 | panic("munmap failed, errno = %d\n", |
316 | -err); | 314 | -err); |
317 | } | 315 | } |
@@ -320,25 +318,25 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) | |||
320 | } | 318 | } |
321 | 319 | ||
322 | pte = pte_offset_kernel(pmd, addr); | 320 | pte = pte_offset_kernel(pmd, addr); |
323 | if(!pte_present(*pte) || pte_newpage(*pte)){ | 321 | if (!pte_present(*pte) || pte_newpage(*pte)) { |
324 | updated = 1; | 322 | updated = 1; |
325 | err = os_unmap_memory((void *) addr, | 323 | err = os_unmap_memory((void *) addr, |
326 | PAGE_SIZE); | 324 | PAGE_SIZE); |
327 | if(err < 0) | 325 | if (err < 0) |
328 | panic("munmap failed, errno = %d\n", | 326 | panic("munmap failed, errno = %d\n", |
329 | -err); | 327 | -err); |
330 | if(pte_present(*pte)) | 328 | if (pte_present(*pte)) |
331 | map_memory(addr, | 329 | map_memory(addr, |
332 | pte_val(*pte) & PAGE_MASK, | 330 | pte_val(*pte) & PAGE_MASK, |
333 | PAGE_SIZE, 1, 1, 1); | 331 | PAGE_SIZE, 1, 1, 1); |
334 | } | 332 | } |
335 | else if(pte_newprot(*pte)){ | 333 | else if (pte_newprot(*pte)) { |
336 | updated = 1; | 334 | updated = 1; |
337 | os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1); | 335 | os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1); |
338 | } | 336 | } |
339 | addr += PAGE_SIZE; | 337 | addr += PAGE_SIZE; |
340 | } | 338 | } |
341 | return(updated); | 339 | return updated; |
342 | } | 340 | } |
343 | 341 | ||
344 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) | 342 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) |
@@ -354,15 +352,15 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) | |||
354 | 352 | ||
355 | address &= PAGE_MASK; | 353 | address &= PAGE_MASK; |
356 | pgd = pgd_offset(mm, address); | 354 | pgd = pgd_offset(mm, address); |
357 | if(!pgd_present(*pgd)) | 355 | if (!pgd_present(*pgd)) |
358 | goto kill; | 356 | goto kill; |
359 | 357 | ||
360 | pud = pud_offset(pgd, address); | 358 | pud = pud_offset(pgd, address); |
361 | if(!pud_present(*pud)) | 359 | if (!pud_present(*pud)) |
362 | goto kill; | 360 | goto kill; |
363 | 361 | ||
364 | pmd = pmd_offset(pud, address); | 362 | pmd = pmd_offset(pud, address); |
365 | if(!pmd_present(*pmd)) | 363 | if (!pmd_present(*pmd)) |
366 | goto kill; | 364 | goto kill; |
367 | 365 | ||
368 | pte = pte_offset_kernel(pmd, address); | 366 | pte = pte_offset_kernel(pmd, address); |
@@ -380,8 +378,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) | |||
380 | mm_id = &mm->context.skas.id; | 378 | mm_id = &mm->context.skas.id; |
381 | prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | | 379 | prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | |
382 | (x ? UM_PROT_EXEC : 0)); | 380 | (x ? UM_PROT_EXEC : 0)); |
383 | if(pte_newpage(*pte)){ | 381 | if (pte_newpage(*pte)) { |
384 | if(pte_present(*pte)){ | 382 | if (pte_present(*pte)) { |
385 | unsigned long long offset; | 383 | unsigned long long offset; |
386 | int fd; | 384 | int fd; |
387 | 385 | ||
@@ -391,10 +389,10 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) | |||
391 | } | 389 | } |
392 | else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); | 390 | else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); |
393 | } | 391 | } |
394 | else if(pte_newprot(*pte)) | 392 | else if (pte_newprot(*pte)) |
395 | err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); | 393 | err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); |
396 | 394 | ||
397 | if(err) | 395 | if (err) |
398 | goto kill; | 396 | goto kill; |
399 | 397 | ||
400 | *pte = pte_mkuptodate(*pte); | 398 | *pte = pte_mkuptodate(*pte); |
@@ -402,28 +400,28 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) | |||
402 | return; | 400 | return; |
403 | 401 | ||
404 | kill: | 402 | kill: |
405 | printk("Failed to flush page for address 0x%lx\n", address); | 403 | printk(KERN_ERR "Failed to flush page for address 0x%lx\n", address); |
406 | force_sig(SIGKILL, current); | 404 | force_sig(SIGKILL, current); |
407 | } | 405 | } |
408 | 406 | ||
409 | pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) | 407 | pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) |
410 | { | 408 | { |
411 | return(pgd_offset(mm, address)); | 409 | return pgd_offset(mm, address); |
412 | } | 410 | } |
413 | 411 | ||
414 | pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address) | 412 | pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address) |
415 | { | 413 | { |
416 | return(pud_offset(pgd, address)); | 414 | return pud_offset(pgd, address); |
417 | } | 415 | } |
418 | 416 | ||
419 | pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address) | 417 | pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address) |
420 | { | 418 | { |
421 | return(pmd_offset(pud, address)); | 419 | return pmd_offset(pud, address); |
422 | } | 420 | } |
423 | 421 | ||
424 | pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address) | 422 | pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address) |
425 | { | 423 | { |
426 | return(pte_offset_kernel(pmd, address)); | 424 | return pte_offset_kernel(pmd, address); |
427 | } | 425 | } |
428 | 426 | ||
429 | pte_t *addr_pte(struct task_struct *task, unsigned long addr) | 427 | pte_t *addr_pte(struct task_struct *task, unsigned long addr) |
@@ -432,7 +430,7 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) | |||
432 | pud_t *pud = pud_offset(pgd, addr); | 430 | pud_t *pud = pud_offset(pgd, addr); |
433 | pmd_t *pmd = pmd_offset(pud, addr); | 431 | pmd_t *pmd = pmd_offset(pud, addr); |
434 | 432 | ||
435 | return(pte_offset_map(pmd, addr)); | 433 | return pte_offset_map(pmd, addr); |
436 | } | 434 | } |
437 | 435 | ||
438 | void flush_tlb_all(void) | 436 | void flush_tlb_all(void) |
@@ -452,18 +450,18 @@ void flush_tlb_kernel_vm(void) | |||
452 | 450 | ||
453 | void __flush_tlb_one(unsigned long addr) | 451 | void __flush_tlb_one(unsigned long addr) |
454 | { | 452 | { |
455 | flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE); | 453 | flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE); |
456 | } | 454 | } |
457 | 455 | ||
458 | static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, | 456 | static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, |
459 | int finished, void **flush) | 457 | int finished, void **flush) |
460 | { | 458 | { |
461 | struct host_vm_op *op; | 459 | struct host_vm_op *op; |
462 | int i, ret = 0; | 460 | int i, ret = 0; |
463 | 461 | ||
464 | for(i = 0; i <= last && !ret; i++){ | 462 | for (i = 0; i <= last && !ret; i++) { |
465 | op = &ops[i]; | 463 | op = &ops[i]; |
466 | switch(op->type){ | 464 | switch(op->type) { |
467 | case MMAP: | 465 | case MMAP: |
468 | ret = map(&mmu->skas.id, op->u.mmap.addr, | 466 | ret = map(&mmu->skas.id, op->u.mmap.addr, |
469 | op->u.mmap.len, op->u.mmap.prot, | 467 | op->u.mmap.len, op->u.mmap.prot, |
@@ -480,7 +478,8 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, | |||
480 | finished, flush); | 478 | finished, flush); |
481 | break; | 479 | break; |
482 | default: | 480 | default: |
483 | printk("Unknown op type %d in do_ops\n", op->type); | 481 | printk(KERN_ERR "Unknown op type %d in do_ops\n", |
482 | op->type); | ||
484 | break; | 483 | break; |
485 | } | 484 | } |
486 | } | 485 | } |
@@ -491,32 +490,33 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, | |||
491 | static void fix_range(struct mm_struct *mm, unsigned long start_addr, | 490 | static void fix_range(struct mm_struct *mm, unsigned long start_addr, |
492 | unsigned long end_addr, int force) | 491 | unsigned long end_addr, int force) |
493 | { | 492 | { |
494 | if(!proc_mm && (end_addr > CONFIG_STUB_START)) | 493 | if (!proc_mm && (end_addr > CONFIG_STUB_START)) |
495 | end_addr = CONFIG_STUB_START; | 494 | end_addr = CONFIG_STUB_START; |
496 | 495 | ||
497 | fix_range_common(mm, start_addr, end_addr, force, do_ops); | 496 | fix_range_common(mm, start_addr, end_addr, force, do_ops); |
498 | } | 497 | } |
499 | 498 | ||
500 | void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | 499 | void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, |
501 | unsigned long end) | 500 | unsigned long end) |
502 | { | 501 | { |
503 | if(vma->vm_mm == NULL) | 502 | if (vma->vm_mm == NULL) |
504 | flush_tlb_kernel_range_common(start, end); | 503 | flush_tlb_kernel_range_common(start, end); |
505 | else fix_range(vma->vm_mm, start, end, 0); | 504 | else fix_range(vma->vm_mm, start, end, 0); |
506 | } | 505 | } |
507 | 506 | ||
508 | void flush_tlb_mm(struct mm_struct *mm) | 507 | void flush_tlb_mm(struct mm_struct *mm) |
509 | { | 508 | { |
510 | unsigned long end; | 509 | unsigned long end; |
511 | 510 | ||
512 | /* Don't bother flushing if this address space is about to be | 511 | /* |
513 | * destroyed. | 512 | * Don't bother flushing if this address space is about to be |
514 | */ | 513 | * destroyed. |
515 | if(atomic_read(&mm->mm_users) == 0) | 514 | */ |
516 | return; | 515 | if (atomic_read(&mm->mm_users) == 0) |
516 | return; | ||
517 | 517 | ||
518 | end = proc_mm ? task_size : CONFIG_STUB_START; | 518 | end = proc_mm ? task_size : CONFIG_STUB_START; |
519 | fix_range(mm, 0, end, 0); | 519 | fix_range(mm, 0, end, 0); |
520 | } | 520 | } |
521 | 521 | ||
522 | void force_flush_all(void) | 522 | void force_flush_all(void) |
@@ -524,7 +524,7 @@ void force_flush_all(void) | |||
524 | struct mm_struct *mm = current->mm; | 524 | struct mm_struct *mm = current->mm; |
525 | struct vm_area_struct *vma = mm->mmap; | 525 | struct vm_area_struct *vma = mm->mmap; |
526 | 526 | ||
527 | while(vma != NULL) { | 527 | while (vma != NULL) { |
528 | fix_range(mm, vma->vm_start, vma->vm_end, 1); | 528 | fix_range(mm, vma->vm_start, vma->vm_end, 1); |
529 | vma = vma->vm_next; | 529 | vma = vma->vm_next; |
530 | } | 530 | } |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 5f3e13c365e5..1993e5e12256 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -1,39 +1,22 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/kernel.h" | ||
7 | #include "linux/sched.h" | ||
8 | #include "linux/notifier.h" | ||
9 | #include "linux/mm.h" | ||
10 | #include "linux/types.h" | ||
11 | #include "linux/tty.h" | ||
12 | #include "linux/init.h" | ||
13 | #include "linux/bootmem.h" | ||
14 | #include "linux/spinlock.h" | ||
15 | #include "linux/utsname.h" | ||
16 | #include "linux/sysrq.h" | ||
17 | #include "linux/seq_file.h" | ||
18 | #include "linux/delay.h" | 6 | #include "linux/delay.h" |
7 | #include "linux/mm.h" | ||
19 | #include "linux/module.h" | 8 | #include "linux/module.h" |
9 | #include "linux/seq_file.h" | ||
10 | #include "linux/string.h" | ||
20 | #include "linux/utsname.h" | 11 | #include "linux/utsname.h" |
21 | #include "asm/page.h" | ||
22 | #include "asm/pgtable.h" | 12 | #include "asm/pgtable.h" |
23 | #include "asm/ptrace.h" | 13 | #include "asm/processor.h" |
24 | #include "asm/elf.h" | ||
25 | #include "asm/user.h" | ||
26 | #include "asm/setup.h" | 14 | #include "asm/setup.h" |
27 | #include "ubd_user.h" | ||
28 | #include "asm/current.h" | ||
29 | #include "kern_util.h" | ||
30 | #include "as-layout.h" | ||
31 | #include "arch.h" | 15 | #include "arch.h" |
16 | #include "as-layout.h" | ||
17 | #include "init.h" | ||
32 | #include "kern.h" | 18 | #include "kern.h" |
33 | #include "mem_user.h" | 19 | #include "mem_user.h" |
34 | #include "mem.h" | ||
35 | #include "initrd.h" | ||
36 | #include "init.h" | ||
37 | #include "os.h" | 20 | #include "os.h" |
38 | #include "skas.h" | 21 | #include "skas.h" |
39 | 22 | ||
@@ -48,7 +31,7 @@ static void __init add_arg(char *arg) | |||
48 | printf("add_arg: Too many command line arguments!\n"); | 31 | printf("add_arg: Too many command line arguments!\n"); |
49 | exit(1); | 32 | exit(1); |
50 | } | 33 | } |
51 | if(strlen(command_line) > 0) | 34 | if (strlen(command_line) > 0) |
52 | strcat(command_line, " "); | 35 | strcat(command_line, " "); |
53 | strcat(command_line, arg); | 36 | strcat(command_line, arg); |
54 | } | 37 | } |
@@ -133,7 +116,7 @@ static int have_root __initdata = 0; | |||
133 | /* Set in uml_mem_setup and modified in linux_main */ | 116 | /* Set in uml_mem_setup and modified in linux_main */ |
134 | long long physmem_size = 32 * 1024 * 1024; | 117 | long long physmem_size = 32 * 1024 * 1024; |
135 | 118 | ||
136 | static char *usage_string = | 119 | static char *usage_string = |
137 | "User Mode Linux v%s\n" | 120 | "User Mode Linux v%s\n" |
138 | " available at http://user-mode-linux.sourceforge.net/\n\n"; | 121 | " available at http://user-mode-linux.sourceforge.net/\n\n"; |
139 | 122 | ||
@@ -191,7 +174,7 @@ static int __init uml_ncpus_setup(char *line, int *add) | |||
191 | 174 | ||
192 | __uml_setup("ncpus=", uml_ncpus_setup, | 175 | __uml_setup("ncpus=", uml_ncpus_setup, |
193 | "ncpus=<# of desired CPUs>\n" | 176 | "ncpus=<# of desired CPUs>\n" |
194 | " This tells an SMP kernel how many virtual processors to start.\n\n" | 177 | " This tells an SMP kernel how many virtual processors to start.\n\n" |
195 | ); | 178 | ); |
196 | #endif | 179 | #endif |
197 | 180 | ||
@@ -223,9 +206,8 @@ static int __init uml_checksetup(char *line, int *add) | |||
223 | int n; | 206 | int n; |
224 | 207 | ||
225 | n = strlen(p->str); | 208 | n = strlen(p->str); |
226 | if(!strncmp(line, p->str, n)){ | 209 | if (!strncmp(line, p->str, n) && p->setup_func(line + n, add)) |
227 | if (p->setup_func(line + n, add)) return 1; | 210 | return 1; |
228 | } | ||
229 | p++; | 211 | p++; |
230 | } | 212 | } |
231 | return 0; | 213 | return 0; |
@@ -236,7 +218,7 @@ static void __init uml_postsetup(void) | |||
236 | initcall_t *p; | 218 | initcall_t *p; |
237 | 219 | ||
238 | p = &__uml_postsetup_start; | 220 | p = &__uml_postsetup_start; |
239 | while(p < &__uml_postsetup_end){ | 221 | while(p < &__uml_postsetup_end) { |
240 | (*p)(); | 222 | (*p)(); |
241 | p++; | 223 | p++; |
242 | } | 224 | } |
@@ -272,16 +254,18 @@ int __init linux_main(int argc, char **argv) | |||
272 | unsigned int i, add; | 254 | unsigned int i, add; |
273 | char * mode; | 255 | char * mode; |
274 | 256 | ||
275 | for (i = 1; i < argc; i++){ | 257 | for (i = 1; i < argc; i++) { |
276 | if((i == 1) && (argv[i][0] == ' ')) continue; | 258 | if ((i == 1) && (argv[i][0] == ' ')) |
259 | continue; | ||
277 | add = 1; | 260 | add = 1; |
278 | uml_checksetup(argv[i], &add); | 261 | uml_checksetup(argv[i], &add); |
279 | if (add) | 262 | if (add) |
280 | add_arg(argv[i]); | 263 | add_arg(argv[i]); |
281 | } | 264 | } |
282 | if(have_root == 0) | 265 | if (have_root == 0) |
283 | add_arg(DEFAULT_COMMAND_LINE); | 266 | add_arg(DEFAULT_COMMAND_LINE); |
284 | 267 | ||
268 | /* OS sanity checks that need to happen before the kernel runs */ | ||
285 | os_early_checks(); | 269 | os_early_checks(); |
286 | 270 | ||
287 | can_do_skas(); | 271 | can_do_skas(); |
@@ -302,12 +286,14 @@ int __init linux_main(int argc, char **argv) | |||
302 | 286 | ||
303 | brk_start = (unsigned long) sbrk(0); | 287 | brk_start = (unsigned long) sbrk(0); |
304 | 288 | ||
305 | /* Increase physical memory size for exec-shield users | 289 | /* |
306 | so they actually get what they asked for. This should | 290 | * Increase physical memory size for exec-shield users |
307 | add zero for non-exec shield users */ | 291 | * so they actually get what they asked for. This should |
292 | * add zero for non-exec shield users | ||
293 | */ | ||
308 | 294 | ||
309 | diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); | 295 | diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); |
310 | if(diff > 1024 * 1024){ | 296 | if (diff > 1024 * 1024) { |
311 | printf("Adding %ld bytes to physical memory to account for " | 297 | printf("Adding %ld bytes to physical memory to account for " |
312 | "exec-shield gap\n", diff); | 298 | "exec-shield gap\n", diff); |
313 | physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); | 299 | physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); |
@@ -324,11 +310,12 @@ int __init linux_main(int argc, char **argv) | |||
324 | iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; | 310 | iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; |
325 | max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; | 311 | max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; |
326 | 312 | ||
327 | /* Zones have to begin on a 1 << MAX_ORDER page boundary, | 313 | /* |
314 | * Zones have to begin on a 1 << MAX_ORDER page boundary, | ||
328 | * so this makes sure that's true for highmem | 315 | * so this makes sure that's true for highmem |
329 | */ | 316 | */ |
330 | max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); | 317 | max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); |
331 | if(physmem_size + iomem_size > max_physmem){ | 318 | if (physmem_size + iomem_size > max_physmem) { |
332 | highmem = physmem_size + iomem_size - max_physmem; | 319 | highmem = physmem_size + iomem_size - max_physmem; |
333 | physmem_size -= highmem; | 320 | physmem_size -= highmem; |
334 | #ifndef CONFIG_HIGHMEM | 321 | #ifndef CONFIG_HIGHMEM |
@@ -345,7 +332,7 @@ int __init linux_main(int argc, char **argv) | |||
345 | start_vm = VMALLOC_START; | 332 | start_vm = VMALLOC_START; |
346 | 333 | ||
347 | setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); | 334 | setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); |
348 | if(init_maps(physmem_size, iomem_size, highmem)){ | 335 | if (init_maps(physmem_size, iomem_size, highmem)) { |
349 | printf("Failed to allocate mem_map for %Lu bytes of physical " | 336 | printf("Failed to allocate mem_map for %Lu bytes of physical " |
350 | "memory and %Lu bytes of highmem\n", physmem_size, | 337 | "memory and %Lu bytes of highmem\n", physmem_size, |
351 | highmem); | 338 | highmem); |
@@ -354,10 +341,11 @@ int __init linux_main(int argc, char **argv) | |||
354 | 341 | ||
355 | virtmem_size = physmem_size; | 342 | virtmem_size = physmem_size; |
356 | avail = get_kmem_end() - start_vm; | 343 | avail = get_kmem_end() - start_vm; |
357 | if(physmem_size > avail) virtmem_size = avail; | 344 | if (physmem_size > avail) |
345 | virtmem_size = avail; | ||
358 | end_vm = start_vm + virtmem_size; | 346 | end_vm = start_vm + virtmem_size; |
359 | 347 | ||
360 | if(virtmem_size < physmem_size) | 348 | if (virtmem_size < physmem_size) |
361 | printf("Kernel virtual memory size shrunk to %lu bytes\n", | 349 | printf("Kernel virtual memory size shrunk to %lu bytes\n", |
362 | virtmem_size); | 350 | virtmem_size); |
363 | 351 | ||