diff options
Diffstat (limited to 'arch/um/kernel')
36 files changed, 385 insertions, 613 deletions
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 121166400e25..356e50f5aaed 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c | |||
@@ -10,8 +10,8 @@ | |||
10 | #include "asm/pgtable.h" | 10 | #include "asm/pgtable.h" |
11 | #include "asm/tlbflush.h" | 11 | #include "asm/tlbflush.h" |
12 | #include "asm/uaccess.h" | 12 | #include "asm/uaccess.h" |
13 | #include "user_util.h" | ||
14 | #include "kern_util.h" | 13 | #include "kern_util.h" |
14 | #include "as-layout.h" | ||
15 | #include "mem_user.h" | 15 | #include "mem_user.h" |
16 | #include "kern.h" | 16 | #include "kern.h" |
17 | #include "irq_user.h" | 17 | #include "irq_user.h" |
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index 8cde431348cc..cda91aa8e703 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "linux/mqueue.h" | 10 | #include "linux/mqueue.h" |
11 | #include "asm/uaccess.h" | 11 | #include "asm/uaccess.h" |
12 | #include "asm/pgtable.h" | 12 | #include "asm/pgtable.h" |
13 | #include "user_util.h" | ||
14 | #include "mem_user.h" | 13 | #include "mem_user.h" |
15 | #include "os.h" | 14 | #include "os.h" |
16 | 15 | ||
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index 82ecf904b09c..16dc43e9d940 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include "linux/bootmem.h" | 7 | #include "linux/bootmem.h" |
8 | #include "linux/initrd.h" | 8 | #include "linux/initrd.h" |
9 | #include "asm/types.h" | 9 | #include "asm/types.h" |
10 | #include "user_util.h" | ||
11 | #include "kern_util.h" | 10 | #include "kern_util.h" |
12 | #include "initrd.h" | 11 | #include "initrd.h" |
13 | #include "init.h" | 12 | #include "init.h" |
@@ -22,12 +21,20 @@ static int __init read_initrd(void) | |||
22 | long long size; | 21 | long long size; |
23 | int err; | 22 | int err; |
24 | 23 | ||
25 | if(initrd == NULL) return 0; | 24 | if(initrd == NULL) |
25 | return 0; | ||
26 | |||
26 | err = os_file_size(initrd, &size); | 27 | err = os_file_size(initrd, &size); |
27 | if(err) return 0; | 28 | if(err) |
29 | return 0; | ||
30 | |||
28 | area = alloc_bootmem(size); | 31 | area = alloc_bootmem(size); |
29 | if(area == NULL) return 0; | 32 | if(area == NULL) |
30 | if(load_initrd(initrd, area, size) == -1) return 0; | 33 | return 0; |
34 | |||
35 | if(load_initrd(initrd, area, size) == -1) | ||
36 | return 0; | ||
37 | |||
31 | initrd_start = (unsigned long) area; | 38 | initrd_start = (unsigned long) area; |
32 | initrd_end = initrd_start + size; | 39 | initrd_end = initrd_start + size; |
33 | return 0; | 40 | return 0; |
@@ -54,25 +61,15 @@ int load_initrd(char *filename, void *buf, int size) | |||
54 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | 61 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); |
55 | if(fd < 0){ | 62 | if(fd < 0){ |
56 | printk("Opening '%s' failed - err = %d\n", filename, -fd); | 63 | printk("Opening '%s' failed - err = %d\n", filename, -fd); |
57 | return(-1); | 64 | return -1; |
58 | } | 65 | } |
59 | n = os_read_file(fd, buf, size); | 66 | n = os_read_file(fd, buf, size); |
60 | if(n != size){ | 67 | if(n != size){ |
61 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, | 68 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, |
62 | filename, -n); | 69 | filename, -n); |
63 | return(-1); | 70 | return -1; |
64 | } | 71 | } |
65 | 72 | ||
66 | os_close_file(fd); | 73 | os_close_file(fd); |
67 | return(0); | 74 | return 0; |
68 | } | 75 | } |
69 | /* | ||
70 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
71 | * Emacs will notice this stuff at the end of the file and automatically | ||
72 | * adjust the settings for this buffer only. This must remain at the end | ||
73 | * of the file. | ||
74 | * --------------------------------------------------------------------------- | ||
75 | * Local variables: | ||
76 | * c-file-style: "linux" | ||
77 | * End: | ||
78 | */ | ||
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index dbf2f5bc842f..8f2ed3690315 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "asm/system.h" | 25 | #include "asm/system.h" |
26 | #include "asm/errno.h" | 26 | #include "asm/errno.h" |
27 | #include "asm/uaccess.h" | 27 | #include "asm/uaccess.h" |
28 | #include "user_util.h" | ||
29 | #include "kern_util.h" | 28 | #include "kern_util.h" |
30 | #include "irq_user.h" | 29 | #include "irq_user.h" |
31 | #include "irq_kern.h" | 30 | #include "irq_kern.h" |
@@ -79,6 +78,14 @@ skip: | |||
79 | return 0; | 78 | return 0; |
80 | } | 79 | } |
81 | 80 | ||
81 | /* | ||
82 | * This list is accessed under irq_lock, except in sigio_handler, | ||
83 | * where it is safe from being modified. IRQ handlers won't change it - | ||
84 | * if an IRQ source has vanished, it will be freed by free_irqs just | ||
85 | * before returning from sigio_handler. That will process a separate | ||
86 | * list of irqs to free, with its own locking, coming back here to | ||
87 | * remove list elements, taking the irq_lock to do so. | ||
88 | */ | ||
82 | static struct irq_fd *active_fds = NULL; | 89 | static struct irq_fd *active_fds = NULL; |
83 | static struct irq_fd **last_irq_ptr = &active_fds; | 90 | static struct irq_fd **last_irq_ptr = &active_fds; |
84 | 91 | ||
@@ -244,6 +251,7 @@ void free_irq_by_fd(int fd) | |||
244 | free_irq_by_cb(same_fd, &fd); | 251 | free_irq_by_cb(same_fd, &fd); |
245 | } | 252 | } |
246 | 253 | ||
254 | /* Must be called with irq_lock held */ | ||
247 | static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) | 255 | static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) |
248 | { | 256 | { |
249 | struct irq_fd *irq; | 257 | struct irq_fd *irq; |
@@ -309,6 +317,12 @@ void deactivate_fd(int fd, int irqnum) | |||
309 | ignore_sigio_fd(fd); | 317 | ignore_sigio_fd(fd); |
310 | } | 318 | } |
311 | 319 | ||
320 | /* | ||
321 | * Called just before shutdown in order to provide a clean exec | ||
322 | * environment in case the system is rebooting. No locking because | ||
323 | * that would cause a pointless shutdown hang if something hadn't | ||
324 | * released the lock. | ||
325 | */ | ||
312 | int deactivate_all_fds(void) | 326 | int deactivate_all_fds(void) |
313 | { | 327 | { |
314 | struct irq_fd *irq; | 328 | struct irq_fd *irq; |
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 0e00cf93f900..7b3e53fb8070 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include "asm/page.h" | 16 | #include "asm/page.h" |
17 | #include "asm/tlbflush.h" | 17 | #include "asm/tlbflush.h" |
18 | #include "kern_util.h" | 18 | #include "kern_util.h" |
19 | #include "user_util.h" | 19 | #include "as-layout.h" |
20 | #include "mem_user.h" | 20 | #include "mem_user.h" |
21 | #include "os.h" | 21 | #include "os.h" |
22 | 22 | ||
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index df7d662b98ce..72ff85693a39 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c | |||
@@ -13,8 +13,8 @@ | |||
13 | #include "asm/page.h" | 13 | #include "asm/page.h" |
14 | #include "asm/fixmap.h" | 14 | #include "asm/fixmap.h" |
15 | #include "asm/pgalloc.h" | 15 | #include "asm/pgalloc.h" |
16 | #include "user_util.h" | ||
17 | #include "kern_util.h" | 16 | #include "kern_util.h" |
17 | #include "as-layout.h" | ||
18 | #include "kern.h" | 18 | #include "kern.h" |
19 | #include "mem_user.h" | 19 | #include "mem_user.h" |
20 | #include "uml_uaccess.h" | 20 | #include "uml_uaccess.h" |
@@ -216,7 +216,7 @@ static void __init fixaddr_user_init( void) | |||
216 | #endif | 216 | #endif |
217 | } | 217 | } |
218 | 218 | ||
219 | void paging_init(void) | 219 | void __init paging_init(void) |
220 | { | 220 | { |
221 | unsigned long zones_size[MAX_NR_ZONES], vaddr; | 221 | unsigned long zones_size[MAX_NR_ZONES], vaddr; |
222 | int i; | 222 | int i; |
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 638f3b5f6094..3ba6e4c841da 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "asm/types.h" | 13 | #include "asm/types.h" |
14 | #include "asm/pgtable.h" | 14 | #include "asm/pgtable.h" |
15 | #include "kern_util.h" | 15 | #include "kern_util.h" |
16 | #include "user_util.h" | 16 | #include "as-layout.h" |
17 | #include "mode_kern.h" | 17 | #include "mode_kern.h" |
18 | #include "mem.h" | 18 | #include "mem.h" |
19 | #include "mem_user.h" | 19 | #include "mem_user.h" |
@@ -21,229 +21,8 @@ | |||
21 | #include "kern.h" | 21 | #include "kern.h" |
22 | #include "init.h" | 22 | #include "init.h" |
23 | 23 | ||
24 | struct phys_desc { | ||
25 | struct rb_node rb; | ||
26 | int fd; | ||
27 | __u64 offset; | ||
28 | void *virt; | ||
29 | unsigned long phys; | ||
30 | struct list_head list; | ||
31 | }; | ||
32 | |||
33 | static struct rb_root phys_mappings = RB_ROOT; | ||
34 | |||
35 | static struct rb_node **find_rb(void *virt) | ||
36 | { | ||
37 | struct rb_node **n = &phys_mappings.rb_node; | ||
38 | struct phys_desc *d; | ||
39 | |||
40 | while(*n != NULL){ | ||
41 | d = rb_entry(*n, struct phys_desc, rb); | ||
42 | if(d->virt == virt) | ||
43 | return n; | ||
44 | |||
45 | if(d->virt > virt) | ||
46 | n = &(*n)->rb_left; | ||
47 | else | ||
48 | n = &(*n)->rb_right; | ||
49 | } | ||
50 | |||
51 | return n; | ||
52 | } | ||
53 | |||
54 | static struct phys_desc *find_phys_mapping(void *virt) | ||
55 | { | ||
56 | struct rb_node **n = find_rb(virt); | ||
57 | |||
58 | if(*n == NULL) | ||
59 | return NULL; | ||
60 | |||
61 | return rb_entry(*n, struct phys_desc, rb); | ||
62 | } | ||
63 | |||
64 | static void insert_phys_mapping(struct phys_desc *desc) | ||
65 | { | ||
66 | struct rb_node **n = find_rb(desc->virt); | ||
67 | |||
68 | if(*n != NULL) | ||
69 | panic("Physical remapping for %p already present", | ||
70 | desc->virt); | ||
71 | |||
72 | rb_link_node(&desc->rb, rb_parent(*n), n); | ||
73 | rb_insert_color(&desc->rb, &phys_mappings); | ||
74 | } | ||
75 | |||
76 | LIST_HEAD(descriptor_mappings); | ||
77 | |||
78 | struct desc_mapping { | ||
79 | int fd; | ||
80 | struct list_head list; | ||
81 | struct list_head pages; | ||
82 | }; | ||
83 | |||
84 | static struct desc_mapping *find_mapping(int fd) | ||
85 | { | ||
86 | struct desc_mapping *desc; | ||
87 | struct list_head *ele; | ||
88 | |||
89 | list_for_each(ele, &descriptor_mappings){ | ||
90 | desc = list_entry(ele, struct desc_mapping, list); | ||
91 | if(desc->fd == fd) | ||
92 | return desc; | ||
93 | } | ||
94 | |||
95 | return NULL; | ||
96 | } | ||
97 | |||
98 | static struct desc_mapping *descriptor_mapping(int fd) | ||
99 | { | ||
100 | struct desc_mapping *desc; | ||
101 | |||
102 | desc = find_mapping(fd); | ||
103 | if(desc != NULL) | ||
104 | return desc; | ||
105 | |||
106 | desc = kmalloc(sizeof(*desc), GFP_ATOMIC); | ||
107 | if(desc == NULL) | ||
108 | return NULL; | ||
109 | |||
110 | *desc = ((struct desc_mapping) | ||
111 | { .fd = fd, | ||
112 | .list = LIST_HEAD_INIT(desc->list), | ||
113 | .pages = LIST_HEAD_INIT(desc->pages) }); | ||
114 | list_add(&desc->list, &descriptor_mappings); | ||
115 | |||
116 | return desc; | ||
117 | } | ||
118 | |||
119 | int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) | ||
120 | { | ||
121 | struct desc_mapping *fd_maps; | ||
122 | struct phys_desc *desc; | ||
123 | unsigned long phys; | ||
124 | int err; | ||
125 | |||
126 | fd_maps = descriptor_mapping(fd); | ||
127 | if(fd_maps == NULL) | ||
128 | return -ENOMEM; | ||
129 | |||
130 | phys = __pa(virt); | ||
131 | desc = find_phys_mapping(virt); | ||
132 | if(desc != NULL) | ||
133 | panic("Address 0x%p is already substituted\n", virt); | ||
134 | |||
135 | err = -ENOMEM; | ||
136 | desc = kmalloc(sizeof(*desc), GFP_ATOMIC); | ||
137 | if(desc == NULL) | ||
138 | goto out; | ||
139 | |||
140 | *desc = ((struct phys_desc) | ||
141 | { .fd = fd, | ||
142 | .offset = offset, | ||
143 | .virt = virt, | ||
144 | .phys = __pa(virt), | ||
145 | .list = LIST_HEAD_INIT(desc->list) }); | ||
146 | insert_phys_mapping(desc); | ||
147 | |||
148 | list_add(&desc->list, &fd_maps->pages); | ||
149 | |||
150 | virt = (void *) ((unsigned long) virt & PAGE_MASK); | ||
151 | err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0); | ||
152 | if(!err) | ||
153 | goto out; | ||
154 | |||
155 | rb_erase(&desc->rb, &phys_mappings); | ||
156 | kfree(desc); | ||
157 | out: | ||
158 | return err; | ||
159 | } | ||
160 | |||
161 | static int physmem_fd = -1; | 24 | static int physmem_fd = -1; |
162 | 25 | ||
163 | static void remove_mapping(struct phys_desc *desc) | ||
164 | { | ||
165 | void *virt = desc->virt; | ||
166 | int err; | ||
167 | |||
168 | rb_erase(&desc->rb, &phys_mappings); | ||
169 | list_del(&desc->list); | ||
170 | kfree(desc); | ||
171 | |||
172 | err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0); | ||
173 | if(err) | ||
174 | panic("Failed to unmap block device page from physical memory, " | ||
175 | "errno = %d", -err); | ||
176 | } | ||
177 | |||
178 | int physmem_remove_mapping(void *virt) | ||
179 | { | ||
180 | struct phys_desc *desc; | ||
181 | |||
182 | virt = (void *) ((unsigned long) virt & PAGE_MASK); | ||
183 | desc = find_phys_mapping(virt); | ||
184 | if(desc == NULL) | ||
185 | return 0; | ||
186 | |||
187 | remove_mapping(desc); | ||
188 | return 1; | ||
189 | } | ||
190 | |||
191 | void physmem_forget_descriptor(int fd) | ||
192 | { | ||
193 | struct desc_mapping *desc; | ||
194 | struct phys_desc *page; | ||
195 | struct list_head *ele, *next; | ||
196 | __u64 offset; | ||
197 | void *addr; | ||
198 | int err; | ||
199 | |||
200 | desc = find_mapping(fd); | ||
201 | if(desc == NULL) | ||
202 | return; | ||
203 | |||
204 | list_for_each_safe(ele, next, &desc->pages){ | ||
205 | page = list_entry(ele, struct phys_desc, list); | ||
206 | offset = page->offset; | ||
207 | addr = page->virt; | ||
208 | remove_mapping(page); | ||
209 | err = os_seek_file(fd, offset); | ||
210 | if(err) | ||
211 | panic("physmem_forget_descriptor - failed to seek " | ||
212 | "to %lld in fd %d, error = %d\n", | ||
213 | offset, fd, -err); | ||
214 | err = os_read_file(fd, addr, PAGE_SIZE); | ||
215 | if(err < 0) | ||
216 | panic("physmem_forget_descriptor - failed to read " | ||
217 | "from fd %d to 0x%p, error = %d\n", | ||
218 | fd, addr, -err); | ||
219 | } | ||
220 | |||
221 | list_del(&desc->list); | ||
222 | kfree(desc); | ||
223 | } | ||
224 | |||
225 | EXPORT_SYMBOL(physmem_forget_descriptor); | ||
226 | EXPORT_SYMBOL(physmem_remove_mapping); | ||
227 | EXPORT_SYMBOL(physmem_subst_mapping); | ||
228 | |||
229 | void arch_free_page(struct page *page, int order) | ||
230 | { | ||
231 | void *virt; | ||
232 | int i; | ||
233 | |||
234 | for(i = 0; i < (1 << order); i++){ | ||
235 | virt = __va(page_to_phys(page + i)); | ||
236 | physmem_remove_mapping(virt); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | int is_remapped(void *virt) | ||
241 | { | ||
242 | struct phys_desc *desc = find_phys_mapping(virt); | ||
243 | |||
244 | return desc != NULL; | ||
245 | } | ||
246 | |||
247 | /* Changed during early boot */ | 26 | /* Changed during early boot */ |
248 | unsigned long high_physmem; | 27 | unsigned long high_physmem; |
249 | 28 | ||
@@ -350,14 +129,9 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, | |||
350 | 129 | ||
351 | int phys_mapping(unsigned long phys, __u64 *offset_out) | 130 | int phys_mapping(unsigned long phys, __u64 *offset_out) |
352 | { | 131 | { |
353 | struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK)); | ||
354 | int fd = -1; | 132 | int fd = -1; |
355 | 133 | ||
356 | if(desc != NULL){ | 134 | if(phys < physmem_size){ |
357 | fd = desc->fd; | ||
358 | *offset_out = desc->offset; | ||
359 | } | ||
360 | else if(phys < physmem_size){ | ||
361 | fd = physmem_fd; | 135 | fd = physmem_fd; |
362 | *offset_out = phys; | 136 | *offset_out = phys; |
363 | } | 137 | } |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 348b272bb766..8d2c5496532b 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -32,8 +32,8 @@ | |||
32 | #include "asm/tlbflush.h" | 32 | #include "asm/tlbflush.h" |
33 | #include "asm/uaccess.h" | 33 | #include "asm/uaccess.h" |
34 | #include "asm/user.h" | 34 | #include "asm/user.h" |
35 | #include "user_util.h" | ||
36 | #include "kern_util.h" | 35 | #include "kern_util.h" |
36 | #include "as-layout.h" | ||
37 | #include "kern.h" | 37 | #include "kern.h" |
38 | #include "signal_kern.h" | 38 | #include "signal_kern.h" |
39 | #include "init.h" | 39 | #include "init.h" |
@@ -54,11 +54,9 @@ | |||
54 | */ | 54 | */ |
55 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; | 55 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; |
56 | 56 | ||
57 | int external_pid(void *t) | 57 | static inline int external_pid(struct task_struct *task) |
58 | { | 58 | { |
59 | struct task_struct *task = t ? t : current; | 59 | return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task); |
60 | |||
61 | return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task)); | ||
62 | } | 60 | } |
63 | 61 | ||
64 | int pid_to_processor_id(int pid) | 62 | int pid_to_processor_id(int pid) |
@@ -66,9 +64,10 @@ int pid_to_processor_id(int pid) | |||
66 | int i; | 64 | int i; |
67 | 65 | ||
68 | for(i = 0; i < ncpus; i++){ | 66 | for(i = 0; i < ncpus; i++){ |
69 | if(cpu_tasks[i].pid == pid) return(i); | 67 | if(cpu_tasks[i].pid == pid) |
68 | return i; | ||
70 | } | 69 | } |
71 | return(-1); | 70 | return -1; |
72 | } | 71 | } |
73 | 72 | ||
74 | void free_stack(unsigned long stack, int order) | 73 | void free_stack(unsigned long stack, int order) |
@@ -85,9 +84,9 @@ unsigned long alloc_stack(int order, int atomic) | |||
85 | flags = GFP_ATOMIC; | 84 | flags = GFP_ATOMIC; |
86 | page = __get_free_pages(flags, order); | 85 | page = __get_free_pages(flags, order); |
87 | if(page == 0) | 86 | if(page == 0) |
88 | return(0); | 87 | return 0; |
89 | stack_protections(page); | 88 | stack_protections(page); |
90 | return(page); | 89 | return page; |
91 | } | 90 | } |
92 | 91 | ||
93 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | 92 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) |
@@ -98,15 +97,11 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
98 | current->thread.request.u.thread.arg = arg; | 97 | current->thread.request.u.thread.arg = arg; |
99 | pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, | 98 | pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, |
100 | ¤t->thread.regs, 0, NULL, NULL); | 99 | ¤t->thread.regs, 0, NULL, NULL); |
101 | if(pid < 0) | 100 | return pid; |
102 | panic("do_fork failed in kernel_thread, errno = %d", pid); | ||
103 | return(pid); | ||
104 | } | 101 | } |
105 | 102 | ||
106 | void set_current(void *t) | 103 | static inline void set_current(struct task_struct *task) |
107 | { | 104 | { |
108 | struct task_struct *task = t; | ||
109 | |||
110 | cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) | 105 | cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) |
111 | { external_pid(task), task }); | 106 | { external_pid(task), task }); |
112 | } | 107 | } |
@@ -128,14 +123,16 @@ void *_switch_to(void *prev, void *next, void *last) | |||
128 | prev= current; | 123 | prev= current; |
129 | } while(current->thread.saved_task); | 124 | } while(current->thread.saved_task); |
130 | 125 | ||
131 | return(current->thread.prev_sched); | 126 | return current->thread.prev_sched; |
132 | 127 | ||
133 | } | 128 | } |
134 | 129 | ||
135 | void interrupt_end(void) | 130 | void interrupt_end(void) |
136 | { | 131 | { |
137 | if(need_resched()) schedule(); | 132 | if(need_resched()) |
138 | if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal(); | 133 | schedule(); |
134 | if(test_tsk_thread_flag(current, TIF_SIGPENDING)) | ||
135 | do_signal(); | ||
139 | } | 136 | } |
140 | 137 | ||
141 | void release_thread(struct task_struct *task) | 138 | void release_thread(struct task_struct *task) |
@@ -150,7 +147,7 @@ void exit_thread(void) | |||
150 | 147 | ||
151 | void *get_current(void) | 148 | void *get_current(void) |
152 | { | 149 | { |
153 | return(current); | 150 | return current; |
154 | } | 151 | } |
155 | 152 | ||
156 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | 153 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, |
@@ -188,15 +185,12 @@ void initial_thread_cb(void (*proc)(void *), void *arg) | |||
188 | kmalloc_ok = save_kmalloc_ok; | 185 | kmalloc_ok = save_kmalloc_ok; |
189 | } | 186 | } |
190 | 187 | ||
188 | #ifdef CONFIG_MODE_TT | ||
191 | unsigned long stack_sp(unsigned long page) | 189 | unsigned long stack_sp(unsigned long page) |
192 | { | 190 | { |
193 | return(page + PAGE_SIZE - sizeof(void *)); | 191 | return page + PAGE_SIZE - sizeof(void *); |
194 | } | ||
195 | |||
196 | int current_pid(void) | ||
197 | { | ||
198 | return(current->pid); | ||
199 | } | 192 | } |
193 | #endif | ||
200 | 194 | ||
201 | void default_idle(void) | 195 | void default_idle(void) |
202 | { | 196 | { |
@@ -221,11 +215,6 @@ void cpu_idle(void) | |||
221 | CHOOSE_MODE(init_idle_tt(), init_idle_skas()); | 215 | CHOOSE_MODE(init_idle_tt(), init_idle_skas()); |
222 | } | 216 | } |
223 | 217 | ||
224 | int page_size(void) | ||
225 | { | ||
226 | return(PAGE_SIZE); | ||
227 | } | ||
228 | |||
229 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | 218 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, |
230 | pte_t *pte_out) | 219 | pte_t *pte_out) |
231 | { | 220 | { |
@@ -236,68 +225,43 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | |||
236 | pte_t ptent; | 225 | pte_t ptent; |
237 | 226 | ||
238 | if(task->mm == NULL) | 227 | if(task->mm == NULL) |
239 | return(ERR_PTR(-EINVAL)); | 228 | return ERR_PTR(-EINVAL); |
240 | pgd = pgd_offset(task->mm, addr); | 229 | pgd = pgd_offset(task->mm, addr); |
241 | if(!pgd_present(*pgd)) | 230 | if(!pgd_present(*pgd)) |
242 | return(ERR_PTR(-EINVAL)); | 231 | return ERR_PTR(-EINVAL); |
243 | 232 | ||
244 | pud = pud_offset(pgd, addr); | 233 | pud = pud_offset(pgd, addr); |
245 | if(!pud_present(*pud)) | 234 | if(!pud_present(*pud)) |
246 | return(ERR_PTR(-EINVAL)); | 235 | return ERR_PTR(-EINVAL); |
247 | 236 | ||
248 | pmd = pmd_offset(pud, addr); | 237 | pmd = pmd_offset(pud, addr); |
249 | if(!pmd_present(*pmd)) | 238 | if(!pmd_present(*pmd)) |
250 | return(ERR_PTR(-EINVAL)); | 239 | return ERR_PTR(-EINVAL); |
251 | 240 | ||
252 | pte = pte_offset_kernel(pmd, addr); | 241 | pte = pte_offset_kernel(pmd, addr); |
253 | ptent = *pte; | 242 | ptent = *pte; |
254 | if(!pte_present(ptent)) | 243 | if(!pte_present(ptent)) |
255 | return(ERR_PTR(-EINVAL)); | 244 | return ERR_PTR(-EINVAL); |
256 | 245 | ||
257 | if(pte_out != NULL) | 246 | if(pte_out != NULL) |
258 | *pte_out = ptent; | 247 | *pte_out = ptent; |
259 | return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK)); | 248 | return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); |
260 | } | 249 | } |
261 | 250 | ||
262 | char *current_cmd(void) | 251 | char *current_cmd(void) |
263 | { | 252 | { |
264 | #if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM) | 253 | #if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM) |
265 | return("(Unknown)"); | 254 | return "(Unknown)"; |
266 | #else | 255 | #else |
267 | void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL); | 256 | void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL); |
268 | return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr); | 257 | return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr); |
269 | #endif | 258 | #endif |
270 | } | 259 | } |
271 | 260 | ||
272 | void force_sigbus(void) | ||
273 | { | ||
274 | printk(KERN_ERR "Killing pid %d because of a lack of memory\n", | ||
275 | current->pid); | ||
276 | lock_kernel(); | ||
277 | sigaddset(¤t->pending.signal, SIGBUS); | ||
278 | recalc_sigpending(); | ||
279 | current->flags |= PF_SIGNALED; | ||
280 | do_exit(SIGBUS | 0x80); | ||
281 | } | ||
282 | |||
283 | void dump_thread(struct pt_regs *regs, struct user *u) | 261 | void dump_thread(struct pt_regs *regs, struct user *u) |
284 | { | 262 | { |
285 | } | 263 | } |
286 | 264 | ||
287 | void enable_hlt(void) | ||
288 | { | ||
289 | panic("enable_hlt"); | ||
290 | } | ||
291 | |||
292 | EXPORT_SYMBOL(enable_hlt); | ||
293 | |||
294 | void disable_hlt(void) | ||
295 | { | ||
296 | panic("disable_hlt"); | ||
297 | } | ||
298 | |||
299 | EXPORT_SYMBOL(disable_hlt); | ||
300 | |||
301 | void *um_kmalloc(int size) | 265 | void *um_kmalloc(int size) |
302 | { | 266 | { |
303 | return kmalloc(size, GFP_KERNEL); | 267 | return kmalloc(size, GFP_KERNEL); |
@@ -313,36 +277,17 @@ void *um_vmalloc(int size) | |||
313 | return vmalloc(size); | 277 | return vmalloc(size); |
314 | } | 278 | } |
315 | 279 | ||
316 | void *um_vmalloc_atomic(int size) | ||
317 | { | ||
318 | return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL); | ||
319 | } | ||
320 | |||
321 | int __cant_sleep(void) { | 280 | int __cant_sleep(void) { |
322 | return in_atomic() || irqs_disabled() || in_interrupt(); | 281 | return in_atomic() || irqs_disabled() || in_interrupt(); |
323 | /* Is in_interrupt() really needed? */ | 282 | /* Is in_interrupt() really needed? */ |
324 | } | 283 | } |
325 | 284 | ||
326 | unsigned long get_fault_addr(void) | ||
327 | { | ||
328 | return((unsigned long) current->thread.fault_addr); | ||
329 | } | ||
330 | |||
331 | EXPORT_SYMBOL(get_fault_addr); | ||
332 | |||
333 | void not_implemented(void) | ||
334 | { | ||
335 | printk(KERN_DEBUG "Something isn't implemented in here\n"); | ||
336 | } | ||
337 | |||
338 | EXPORT_SYMBOL(not_implemented); | ||
339 | |||
340 | int user_context(unsigned long sp) | 285 | int user_context(unsigned long sp) |
341 | { | 286 | { |
342 | unsigned long stack; | 287 | unsigned long stack; |
343 | 288 | ||
344 | stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); | 289 | stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); |
345 | return(stack != (unsigned long) current_thread); | 290 | return stack != (unsigned long) current_thread; |
346 | } | 291 | } |
347 | 292 | ||
348 | extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; | 293 | extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; |
@@ -363,22 +308,22 @@ char *uml_strdup(char *string) | |||
363 | 308 | ||
364 | int copy_to_user_proc(void __user *to, void *from, int size) | 309 | int copy_to_user_proc(void __user *to, void *from, int size) |
365 | { | 310 | { |
366 | return(copy_to_user(to, from, size)); | 311 | return copy_to_user(to, from, size); |
367 | } | 312 | } |
368 | 313 | ||
369 | int copy_from_user_proc(void *to, void __user *from, int size) | 314 | int copy_from_user_proc(void *to, void __user *from, int size) |
370 | { | 315 | { |
371 | return(copy_from_user(to, from, size)); | 316 | return copy_from_user(to, from, size); |
372 | } | 317 | } |
373 | 318 | ||
374 | int clear_user_proc(void __user *buf, int size) | 319 | int clear_user_proc(void __user *buf, int size) |
375 | { | 320 | { |
376 | return(clear_user(buf, size)); | 321 | return clear_user(buf, size); |
377 | } | 322 | } |
378 | 323 | ||
379 | int strlen_user_proc(char __user *str) | 324 | int strlen_user_proc(char __user *str) |
380 | { | 325 | { |
381 | return(strlen_user(str)); | 326 | return strlen_user(str); |
382 | } | 327 | } |
383 | 328 | ||
384 | int smp_sigio_handler(void) | 329 | int smp_sigio_handler(void) |
@@ -387,14 +332,14 @@ int smp_sigio_handler(void) | |||
387 | int cpu = current_thread->cpu; | 332 | int cpu = current_thread->cpu; |
388 | IPI_handler(cpu); | 333 | IPI_handler(cpu); |
389 | if(cpu != 0) | 334 | if(cpu != 0) |
390 | return(1); | 335 | return 1; |
391 | #endif | 336 | #endif |
392 | return(0); | 337 | return 0; |
393 | } | 338 | } |
394 | 339 | ||
395 | int cpu(void) | 340 | int cpu(void) |
396 | { | 341 | { |
397 | return(current_thread->cpu); | 342 | return current_thread->cpu; |
398 | } | 343 | } |
399 | 344 | ||
400 | static atomic_t using_sysemu = ATOMIC_INIT(0); | 345 | static atomic_t using_sysemu = ATOMIC_INIT(0); |
@@ -443,7 +388,7 @@ int __init make_proc_sysemu(void) | |||
443 | if (ent == NULL) | 388 | if (ent == NULL) |
444 | { | 389 | { |
445 | printk(KERN_WARNING "Failed to register /proc/sysemu\n"); | 390 | printk(KERN_WARNING "Failed to register /proc/sysemu\n"); |
446 | return(0); | 391 | return 0; |
447 | } | 392 | } |
448 | 393 | ||
449 | ent->read_proc = proc_read_sysemu; | 394 | ent->read_proc = proc_read_sysemu; |
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index f602623644aa..7e4305a1fd3c 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include "linux/module.h" | 6 | #include "linux/module.h" |
7 | #include "linux/sched.h" | 7 | #include "linux/sched.h" |
8 | #include "asm/smp.h" | 8 | #include "asm/smp.h" |
9 | #include "user_util.h" | ||
10 | #include "kern_util.h" | 9 | #include "kern_util.h" |
11 | #include "kern.h" | 10 | #include "kern.h" |
12 | #include "os.h" | 11 | #include "os.h" |
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index 3c798cdde550..c4020c3d7857 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include "asm/signal.h" | 17 | #include "asm/signal.h" |
18 | #include "asm/uaccess.h" | 18 | #include "asm/uaccess.h" |
19 | #include "asm/unistd.h" | 19 | #include "asm/unistd.h" |
20 | #include "user_util.h" | ||
21 | #include "asm/ucontext.h" | 20 | #include "asm/ucontext.h" |
22 | #include "kern_util.h" | 21 | #include "kern_util.h" |
23 | #include "signal_kern.h" | 22 | #include "signal_kern.h" |
diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c index 54b795951372..580eb6468949 100644 --- a/arch/um/kernel/skas/exec.c +++ b/arch/um/kernel/skas/exec.c | |||
@@ -17,7 +17,17 @@ | |||
17 | 17 | ||
18 | void flush_thread_skas(void) | 18 | void flush_thread_skas(void) |
19 | { | 19 | { |
20 | force_flush_all(); | 20 | void *data = NULL; |
21 | unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; | ||
22 | int ret; | ||
23 | |||
24 | ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data); | ||
25 | if(ret){ | ||
26 | printk("flush_thread_skas - clearing address space failed, " | ||
27 | "err = %d\n", ret); | ||
28 | force_sig(SIGKILL, current); | ||
29 | } | ||
30 | |||
21 | switch_mm_skas(¤t->mm->context.skas.id); | 31 | switch_mm_skas(¤t->mm->context.skas.id); |
22 | } | 32 | } |
23 | 33 | ||
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index ae4fa71d3b8b..ef36facd8fe9 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -13,9 +13,9 @@ | |||
13 | #include "asm/uaccess.h" | 13 | #include "asm/uaccess.h" |
14 | #include "asm/atomic.h" | 14 | #include "asm/atomic.h" |
15 | #include "kern_util.h" | 15 | #include "kern_util.h" |
16 | #include "as-layout.h" | ||
16 | #include "skas.h" | 17 | #include "skas.h" |
17 | #include "os.h" | 18 | #include "os.h" |
18 | #include "user_util.h" | ||
19 | #include "tlb.h" | 19 | #include "tlb.h" |
20 | #include "kern.h" | 20 | #include "kern.h" |
21 | #include "mode.h" | 21 | #include "mode.h" |
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index 27eb29ce666b..c0f0693743ba 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "asm/page.h" | 10 | #include "asm/page.h" |
11 | #include "asm/pgtable.h" | 11 | #include "asm/pgtable.h" |
12 | #include "asm/mmu.h" | 12 | #include "asm/mmu.h" |
13 | #include "user_util.h" | ||
14 | #include "mem_user.h" | 13 | #include "mem_user.h" |
15 | #include "mem.h" | 14 | #include "mem.h" |
16 | #include "skas.h" | 15 | #include "skas.h" |
@@ -28,19 +27,17 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, | |||
28 | switch(op->type){ | 27 | switch(op->type){ |
29 | case MMAP: | 28 | case MMAP: |
30 | ret = map(&mmu->skas.id, op->u.mmap.addr, | 29 | ret = map(&mmu->skas.id, op->u.mmap.addr, |
31 | op->u.mmap.len, op->u.mmap.r, op->u.mmap.w, | 30 | op->u.mmap.len, op->u.mmap.prot, |
32 | op->u.mmap.x, op->u.mmap.fd, | 31 | op->u.mmap.fd, op->u.mmap.offset, finished, |
33 | op->u.mmap.offset, finished, flush); | 32 | flush); |
34 | break; | 33 | break; |
35 | case MUNMAP: | 34 | case MUNMAP: |
36 | ret = unmap(&mmu->skas.id, | 35 | ret = unmap(&mmu->skas.id, op->u.munmap.addr, |
37 | (void *) op->u.munmap.addr, | ||
38 | op->u.munmap.len, finished, flush); | 36 | op->u.munmap.len, finished, flush); |
39 | break; | 37 | break; |
40 | case MPROTECT: | 38 | case MPROTECT: |
41 | ret = protect(&mmu->skas.id, op->u.mprotect.addr, | 39 | ret = protect(&mmu->skas.id, op->u.mprotect.addr, |
42 | op->u.mprotect.len, op->u.mprotect.r, | 40 | op->u.mprotect.len, op->u.mprotect.prot, |
43 | op->u.mprotect.w, op->u.mprotect.x, | ||
44 | finished, flush); | 41 | finished, flush); |
45 | break; | 42 | break; |
46 | default: | 43 | default: |
@@ -92,6 +89,76 @@ void flush_tlb_mm_skas(struct mm_struct *mm) | |||
92 | 89 | ||
93 | void force_flush_all_skas(void) | 90 | void force_flush_all_skas(void) |
94 | { | 91 | { |
95 | unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; | 92 | struct mm_struct *mm = current->mm; |
96 | fix_range(current->mm, 0, end, 1); | 93 | struct vm_area_struct *vma = mm->mmap; |
94 | |||
95 | while(vma != NULL) { | ||
96 | fix_range(mm, vma->vm_start, vma->vm_end, 1); | ||
97 | vma = vma->vm_next; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) | ||
102 | { | ||
103 | pgd_t *pgd; | ||
104 | pud_t *pud; | ||
105 | pmd_t *pmd; | ||
106 | pte_t *pte; | ||
107 | struct mm_struct *mm = vma->vm_mm; | ||
108 | void *flush = NULL; | ||
109 | int r, w, x, prot, err = 0; | ||
110 | struct mm_id *mm_id; | ||
111 | |||
112 | pgd = pgd_offset(mm, address); | ||
113 | if(!pgd_present(*pgd)) | ||
114 | goto kill; | ||
115 | |||
116 | pud = pud_offset(pgd, address); | ||
117 | if(!pud_present(*pud)) | ||
118 | goto kill; | ||
119 | |||
120 | pmd = pmd_offset(pud, address); | ||
121 | if(!pmd_present(*pmd)) | ||
122 | goto kill; | ||
123 | |||
124 | pte = pte_offset_kernel(pmd, address); | ||
125 | |||
126 | r = pte_read(*pte); | ||
127 | w = pte_write(*pte); | ||
128 | x = pte_exec(*pte); | ||
129 | if (!pte_young(*pte)) { | ||
130 | r = 0; | ||
131 | w = 0; | ||
132 | } else if (!pte_dirty(*pte)) { | ||
133 | w = 0; | ||
134 | } | ||
135 | |||
136 | mm_id = &mm->context.skas.id; | ||
137 | prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | | ||
138 | (x ? UM_PROT_EXEC : 0)); | ||
139 | if(pte_newpage(*pte)){ | ||
140 | if(pte_present(*pte)){ | ||
141 | unsigned long long offset; | ||
142 | int fd; | ||
143 | |||
144 | fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); | ||
145 | err = map(mm_id, address, PAGE_SIZE, prot, fd, offset, | ||
146 | 1, &flush); | ||
147 | } | ||
148 | else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); | ||
149 | } | ||
150 | else if(pte_newprot(*pte)) | ||
151 | err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); | ||
152 | |||
153 | if(err) | ||
154 | goto kill; | ||
155 | |||
156 | *pte = pte_mkuptodate(*pte); | ||
157 | |||
158 | return; | ||
159 | |||
160 | kill: | ||
161 | printk("Failed to flush page for address 0x%lx\n", address); | ||
162 | force_sig(SIGKILL, current); | ||
97 | } | 163 | } |
164 | |||
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 759b07053160..e6a7778006ad 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c | |||
@@ -21,7 +21,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | |||
21 | #include "asm/smp.h" | 21 | #include "asm/smp.h" |
22 | #include "asm/processor.h" | 22 | #include "asm/processor.h" |
23 | #include "asm/spinlock.h" | 23 | #include "asm/spinlock.h" |
24 | #include "user_util.h" | ||
25 | #include "kern_util.h" | 24 | #include "kern_util.h" |
26 | #include "kern.h" | 25 | #include "kern.h" |
27 | #include "irq_user.h" | 26 | #include "irq_user.h" |
@@ -90,7 +89,7 @@ static int idle_proc(void *cpup) | |||
90 | 89 | ||
91 | cpu_set(cpu, cpu_online_map); | 90 | cpu_set(cpu, cpu_online_map); |
92 | default_idle(); | 91 | default_idle(); |
93 | return(0); | 92 | return 0; |
94 | } | 93 | } |
95 | 94 | ||
96 | static struct task_struct *idle_thread(int cpu) | 95 | static struct task_struct *idle_thread(int cpu) |
@@ -98,8 +97,8 @@ static struct task_struct *idle_thread(int cpu) | |||
98 | struct task_struct *new_task; | 97 | struct task_struct *new_task; |
99 | unsigned char c; | 98 | unsigned char c; |
100 | 99 | ||
101 | current->thread.request.u.thread.proc = idle_proc; | 100 | current->thread.request.u.thread.proc = idle_proc; |
102 | current->thread.request.u.thread.arg = (void *) cpu; | 101 | current->thread.request.u.thread.arg = (void *) cpu; |
103 | new_task = fork_idle(cpu); | 102 | new_task = fork_idle(cpu); |
104 | if(IS_ERR(new_task)) | 103 | if(IS_ERR(new_task)) |
105 | panic("copy_process failed in idle_thread, error = %ld", | 104 | panic("copy_process failed in idle_thread, error = %ld", |
@@ -110,9 +109,9 @@ static struct task_struct *idle_thread(int cpu) | |||
110 | .task = new_task } ); | 109 | .task = new_task } ); |
111 | idle_threads[cpu] = new_task; | 110 | idle_threads[cpu] = new_task; |
112 | CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, | 111 | CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, |
113 | sizeof(c)), | 112 | sizeof(c)), |
114 | ({ panic("skas mode doesn't support SMP"); })); | 113 | ({ panic("skas mode doesn't support SMP"); })); |
115 | return(new_task); | 114 | return new_task; |
116 | } | 115 | } |
117 | 116 | ||
118 | void smp_prepare_cpus(unsigned int maxcpus) | 117 | void smp_prepare_cpus(unsigned int maxcpus) |
@@ -163,13 +162,13 @@ int __cpu_up(unsigned int cpu) | |||
163 | cpu_set(cpu, smp_commenced_mask); | 162 | cpu_set(cpu, smp_commenced_mask); |
164 | while (!cpu_isset(cpu, cpu_online_map)) | 163 | while (!cpu_isset(cpu, cpu_online_map)) |
165 | mb(); | 164 | mb(); |
166 | return(0); | 165 | return 0; |
167 | } | 166 | } |
168 | 167 | ||
169 | int setup_profiling_timer(unsigned int multiplier) | 168 | int setup_profiling_timer(unsigned int multiplier) |
170 | { | 169 | { |
171 | printk(KERN_INFO "setup_profiling_timer\n"); | 170 | printk(KERN_INFO "setup_profiling_timer\n"); |
172 | return(0); | 171 | return 0; |
173 | } | 172 | } |
174 | 173 | ||
175 | void smp_call_function_slave(int cpu); | 174 | void smp_call_function_slave(int cpu); |
@@ -205,7 +204,7 @@ void IPI_handler(int cpu) | |||
205 | 204 | ||
206 | int hard_smp_processor_id(void) | 205 | int hard_smp_processor_id(void) |
207 | { | 206 | { |
208 | return(pid_to_processor_id(os_getpid())); | 207 | return pid_to_processor_id(os_getpid()); |
209 | } | 208 | } |
210 | 209 | ||
211 | static DEFINE_SPINLOCK(call_lock); | 210 | static DEFINE_SPINLOCK(call_lock); |
@@ -254,14 +253,3 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, | |||
254 | } | 253 | } |
255 | 254 | ||
256 | #endif | 255 | #endif |
257 | |||
258 | /* | ||
259 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
260 | * Emacs will notice this stuff at the end of the file and automatically | ||
261 | * adjust the settings for this buffer only. This must remain at the end | ||
262 | * of the file. | ||
263 | * --------------------------------------------------------------------------- | ||
264 | * Local variables: | ||
265 | * c-file-style: "linux" | ||
266 | * End: | ||
267 | */ | ||
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 2828c5283227..237c4eab7cfd 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include "asm/mman.h" | 18 | #include "asm/mman.h" |
19 | #include "asm/uaccess.h" | 19 | #include "asm/uaccess.h" |
20 | #include "kern_util.h" | 20 | #include "kern_util.h" |
21 | #include "user_util.h" | ||
22 | #include "sysdep/syscalls.h" | 21 | #include "sysdep/syscalls.h" |
23 | #include "mode_kern.h" | 22 | #include "mode_kern.h" |
24 | #include "choose-mode.h" | 23 | #include "choose-mode.h" |
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index f9e02b31a97a..93263571d813 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "asm/page.h" | 10 | #include "asm/page.h" |
11 | #include "asm/processor.h" | 11 | #include "asm/processor.h" |
12 | #include "sysrq.h" | 12 | #include "sysrq.h" |
13 | #include "user_util.h" | ||
14 | 13 | ||
15 | /* Catch non-i386 SUBARCH's. */ | 14 | /* Catch non-i386 SUBARCH's. */ |
16 | #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) | 15 | #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) |
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index b1f8b0752419..cd7349de8ca6 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include "asm/param.h" | 18 | #include "asm/param.h" |
19 | #include "asm/current.h" | 19 | #include "asm/current.h" |
20 | #include "kern_util.h" | 20 | #include "kern_util.h" |
21 | #include "user_util.h" | ||
22 | #include "mode.h" | 21 | #include "mode.h" |
23 | #include "os.h" | 22 | #include "os.h" |
24 | 23 | ||
@@ -35,8 +34,8 @@ unsigned long long sched_clock(void) | |||
35 | return (unsigned long long)jiffies_64 * (1000000000 / HZ); | 34 | return (unsigned long long)jiffies_64 * (1000000000 / HZ); |
36 | } | 35 | } |
37 | 36 | ||
38 | static unsigned long long prev_nsecs[NR_CPUS]; | ||
39 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | 37 | #ifdef CONFIG_UML_REAL_TIME_CLOCK |
38 | static unsigned long long prev_nsecs[NR_CPUS]; | ||
40 | static long long delta[NR_CPUS]; /* Deviation per interval */ | 39 | static long long delta[NR_CPUS]; /* Deviation per interval */ |
41 | #endif | 40 | #endif |
42 | 41 | ||
@@ -95,7 +94,12 @@ irqreturn_t um_timer(int irq, void *dev) | |||
95 | 94 | ||
96 | do_timer(1); | 95 | do_timer(1); |
97 | 96 | ||
97 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | ||
98 | nsecs = get_time(); | 98 | nsecs = get_time(); |
99 | #else | ||
100 | nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec + | ||
101 | BILLION / HZ; | ||
102 | #endif | ||
99 | xtime.tv_sec = nsecs / NSEC_PER_SEC; | 103 | xtime.tv_sec = nsecs / NSEC_PER_SEC; |
100 | xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; | 104 | xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; |
101 | 105 | ||
@@ -128,13 +132,18 @@ void time_init(void) | |||
128 | nsecs = os_nsecs(); | 132 | nsecs = os_nsecs(); |
129 | set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, | 133 | set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, |
130 | -nsecs % BILLION); | 134 | -nsecs % BILLION); |
135 | set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION); | ||
131 | late_time_init = register_timer; | 136 | late_time_init = register_timer; |
132 | } | 137 | } |
133 | 138 | ||
134 | void do_gettimeofday(struct timeval *tv) | 139 | void do_gettimeofday(struct timeval *tv) |
135 | { | 140 | { |
141 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | ||
136 | unsigned long long nsecs = get_time(); | 142 | unsigned long long nsecs = get_time(); |
137 | 143 | #else | |
144 | unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION + | ||
145 | xtime.tv_nsec; | ||
146 | #endif | ||
138 | tv->tv_sec = nsecs / NSEC_PER_SEC; | 147 | tv->tv_sec = nsecs / NSEC_PER_SEC; |
139 | /* Careful about calculations here - this was originally done as | 148 | /* Careful about calculations here - this was originally done as |
140 | * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC | 149 | * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC |
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 54a5ff25645a..8a8d52851443 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c | |||
@@ -6,17 +6,18 @@ | |||
6 | #include "linux/mm.h" | 6 | #include "linux/mm.h" |
7 | #include "asm/page.h" | 7 | #include "asm/page.h" |
8 | #include "asm/pgalloc.h" | 8 | #include "asm/pgalloc.h" |
9 | #include "asm/pgtable.h" | ||
9 | #include "asm/tlbflush.h" | 10 | #include "asm/tlbflush.h" |
10 | #include "choose-mode.h" | 11 | #include "choose-mode.h" |
11 | #include "mode_kern.h" | 12 | #include "mode_kern.h" |
12 | #include "user_util.h" | 13 | #include "as-layout.h" |
13 | #include "tlb.h" | 14 | #include "tlb.h" |
14 | #include "mem.h" | 15 | #include "mem.h" |
15 | #include "mem_user.h" | 16 | #include "mem_user.h" |
16 | #include "os.h" | 17 | #include "os.h" |
17 | 18 | ||
18 | static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, | 19 | static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, |
19 | int r, int w, int x, struct host_vm_op *ops, int *index, | 20 | unsigned int prot, struct host_vm_op *ops, int *index, |
20 | int last_filled, union mm_context *mmu, void **flush, | 21 | int last_filled, union mm_context *mmu, void **flush, |
21 | int (*do_ops)(union mm_context *, struct host_vm_op *, | 22 | int (*do_ops)(union mm_context *, struct host_vm_op *, |
22 | int, int, void **)) | 23 | int, int, void **)) |
@@ -30,8 +31,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, | |||
30 | last = &ops[*index]; | 31 | last = &ops[*index]; |
31 | if((last->type == MMAP) && | 32 | if((last->type == MMAP) && |
32 | (last->u.mmap.addr + last->u.mmap.len == virt) && | 33 | (last->u.mmap.addr + last->u.mmap.len == virt) && |
33 | (last->u.mmap.r == r) && (last->u.mmap.w == w) && | 34 | (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && |
34 | (last->u.mmap.x == x) && (last->u.mmap.fd == fd) && | ||
35 | (last->u.mmap.offset + last->u.mmap.len == offset)){ | 35 | (last->u.mmap.offset + last->u.mmap.len == offset)){ |
36 | last->u.mmap.len += len; | 36 | last->u.mmap.len += len; |
37 | return 0; | 37 | return 0; |
@@ -47,9 +47,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, | |||
47 | .u = { .mmap = { | 47 | .u = { .mmap = { |
48 | .addr = virt, | 48 | .addr = virt, |
49 | .len = len, | 49 | .len = len, |
50 | .r = r, | 50 | .prot = prot, |
51 | .w = w, | ||
52 | .x = x, | ||
53 | .fd = fd, | 51 | .fd = fd, |
54 | .offset = offset } | 52 | .offset = offset } |
55 | } }); | 53 | } }); |
@@ -86,8 +84,8 @@ static int add_munmap(unsigned long addr, unsigned long len, | |||
86 | return ret; | 84 | return ret; |
87 | } | 85 | } |
88 | 86 | ||
89 | static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, | 87 | static int add_mprotect(unsigned long addr, unsigned long len, |
90 | int x, struct host_vm_op *ops, int *index, | 88 | unsigned int prot, struct host_vm_op *ops, int *index, |
91 | int last_filled, union mm_context *mmu, void **flush, | 89 | int last_filled, union mm_context *mmu, void **flush, |
92 | int (*do_ops)(union mm_context *, struct host_vm_op *, | 90 | int (*do_ops)(union mm_context *, struct host_vm_op *, |
93 | int, int, void **)) | 91 | int, int, void **)) |
@@ -99,8 +97,7 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, | |||
99 | last = &ops[*index]; | 97 | last = &ops[*index]; |
100 | if((last->type == MPROTECT) && | 98 | if((last->type == MPROTECT) && |
101 | (last->u.mprotect.addr + last->u.mprotect.len == addr) && | 99 | (last->u.mprotect.addr + last->u.mprotect.len == addr) && |
102 | (last->u.mprotect.r == r) && (last->u.mprotect.w == w) && | 100 | (last->u.mprotect.prot == prot)){ |
103 | (last->u.mprotect.x == x)){ | ||
104 | last->u.mprotect.len += len; | 101 | last->u.mprotect.len += len; |
105 | return 0; | 102 | return 0; |
106 | } | 103 | } |
@@ -115,114 +112,145 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, | |||
115 | .u = { .mprotect = { | 112 | .u = { .mprotect = { |
116 | .addr = addr, | 113 | .addr = addr, |
117 | .len = len, | 114 | .len = len, |
118 | .r = r, | 115 | .prot = prot } } }); |
119 | .w = w, | ||
120 | .x = x } } }); | ||
121 | return ret; | 116 | return ret; |
122 | } | 117 | } |
123 | 118 | ||
124 | #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) | 119 | #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) |
125 | 120 | ||
121 | static inline int update_pte_range(pmd_t *pmd, unsigned long addr, | ||
122 | unsigned long end, struct host_vm_op *ops, | ||
123 | int last_op, int *op_index, int force, | ||
124 | union mm_context *mmu, void **flush, | ||
125 | int (*do_ops)(union mm_context *, | ||
126 | struct host_vm_op *, int, int, | ||
127 | void **)) | ||
128 | { | ||
129 | pte_t *pte; | ||
130 | int r, w, x, prot, ret = 0; | ||
131 | |||
132 | pte = pte_offset_kernel(pmd, addr); | ||
133 | do { | ||
134 | r = pte_read(*pte); | ||
135 | w = pte_write(*pte); | ||
136 | x = pte_exec(*pte); | ||
137 | if (!pte_young(*pte)) { | ||
138 | r = 0; | ||
139 | w = 0; | ||
140 | } else if (!pte_dirty(*pte)) { | ||
141 | w = 0; | ||
142 | } | ||
143 | prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | | ||
144 | (x ? UM_PROT_EXEC : 0)); | ||
145 | if(force || pte_newpage(*pte)){ | ||
146 | if(pte_present(*pte)) | ||
147 | ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, | ||
148 | PAGE_SIZE, prot, ops, op_index, | ||
149 | last_op, mmu, flush, do_ops); | ||
150 | else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, | ||
151 | last_op, mmu, flush, do_ops); | ||
152 | } | ||
153 | else if(pte_newprot(*pte)) | ||
154 | ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, | ||
155 | last_op, mmu, flush, do_ops); | ||
156 | *pte = pte_mkuptodate(*pte); | ||
157 | } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | static inline int update_pmd_range(pud_t *pud, unsigned long addr, | ||
162 | unsigned long end, struct host_vm_op *ops, | ||
163 | int last_op, int *op_index, int force, | ||
164 | union mm_context *mmu, void **flush, | ||
165 | int (*do_ops)(union mm_context *, | ||
166 | struct host_vm_op *, int, int, | ||
167 | void **)) | ||
168 | { | ||
169 | pmd_t *pmd; | ||
170 | unsigned long next; | ||
171 | int ret = 0; | ||
172 | |||
173 | pmd = pmd_offset(pud, addr); | ||
174 | do { | ||
175 | next = pmd_addr_end(addr, end); | ||
176 | if(!pmd_present(*pmd)){ | ||
177 | if(force || pmd_newpage(*pmd)){ | ||
178 | ret = add_munmap(addr, next - addr, ops, | ||
179 | op_index, last_op, mmu, | ||
180 | flush, do_ops); | ||
181 | pmd_mkuptodate(*pmd); | ||
182 | } | ||
183 | } | ||
184 | else ret = update_pte_range(pmd, addr, next, ops, last_op, | ||
185 | op_index, force, mmu, flush, | ||
186 | do_ops); | ||
187 | } while (pmd++, addr = next, ((addr != end) && !ret)); | ||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static inline int update_pud_range(pgd_t *pgd, unsigned long addr, | ||
192 | unsigned long end, struct host_vm_op *ops, | ||
193 | int last_op, int *op_index, int force, | ||
194 | union mm_context *mmu, void **flush, | ||
195 | int (*do_ops)(union mm_context *, | ||
196 | struct host_vm_op *, int, int, | ||
197 | void **)) | ||
198 | { | ||
199 | pud_t *pud; | ||
200 | unsigned long next; | ||
201 | int ret = 0; | ||
202 | |||
203 | pud = pud_offset(pgd, addr); | ||
204 | do { | ||
205 | next = pud_addr_end(addr, end); | ||
206 | if(!pud_present(*pud)){ | ||
207 | if(force || pud_newpage(*pud)){ | ||
208 | ret = add_munmap(addr, next - addr, ops, | ||
209 | op_index, last_op, mmu, | ||
210 | flush, do_ops); | ||
211 | pud_mkuptodate(*pud); | ||
212 | } | ||
213 | } | ||
214 | else ret = update_pmd_range(pud, addr, next, ops, last_op, | ||
215 | op_index, force, mmu, flush, | ||
216 | do_ops); | ||
217 | } while (pud++, addr = next, ((addr != end) && !ret)); | ||
218 | return ret; | ||
219 | } | ||
220 | |||
126 | void fix_range_common(struct mm_struct *mm, unsigned long start_addr, | 221 | void fix_range_common(struct mm_struct *mm, unsigned long start_addr, |
127 | unsigned long end_addr, int force, | 222 | unsigned long end_addr, int force, |
128 | int (*do_ops)(union mm_context *, struct host_vm_op *, | 223 | int (*do_ops)(union mm_context *, struct host_vm_op *, |
129 | int, int, void **)) | 224 | int, int, void **)) |
130 | { | 225 | { |
131 | pgd_t *npgd; | 226 | pgd_t *pgd; |
132 | pud_t *npud; | ||
133 | pmd_t *npmd; | ||
134 | pte_t *npte; | ||
135 | union mm_context *mmu = &mm->context; | 227 | union mm_context *mmu = &mm->context; |
136 | unsigned long addr, end; | ||
137 | int r, w, x; | ||
138 | struct host_vm_op ops[1]; | 228 | struct host_vm_op ops[1]; |
229 | unsigned long addr = start_addr, next; | ||
230 | int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; | ||
139 | void *flush = NULL; | 231 | void *flush = NULL; |
140 | int op_index = -1, last_op = ARRAY_SIZE(ops) - 1; | ||
141 | int ret = 0; | ||
142 | |||
143 | if(mm == NULL) | ||
144 | return; | ||
145 | 232 | ||
146 | ops[0].type = NONE; | 233 | ops[0].type = NONE; |
147 | for(addr = start_addr; addr < end_addr && !ret;){ | 234 | pgd = pgd_offset(mm, addr); |
148 | npgd = pgd_offset(mm, addr); | 235 | do { |
149 | if(!pgd_present(*npgd)){ | 236 | next = pgd_addr_end(addr, end_addr); |
150 | end = ADD_ROUND(addr, PGDIR_SIZE); | 237 | if(!pgd_present(*pgd)){ |
151 | if(end > end_addr) | 238 | if (force || pgd_newpage(*pgd)){ |
152 | end = end_addr; | 239 | ret = add_munmap(addr, next - addr, ops, |
153 | if(force || pgd_newpage(*npgd)){ | ||
154 | ret = add_munmap(addr, end - addr, ops, | ||
155 | &op_index, last_op, mmu, | ||
156 | &flush, do_ops); | ||
157 | pgd_mkuptodate(*npgd); | ||
158 | } | ||
159 | addr = end; | ||
160 | continue; | ||
161 | } | ||
162 | |||
163 | npud = pud_offset(npgd, addr); | ||
164 | if(!pud_present(*npud)){ | ||
165 | end = ADD_ROUND(addr, PUD_SIZE); | ||
166 | if(end > end_addr) | ||
167 | end = end_addr; | ||
168 | if(force || pud_newpage(*npud)){ | ||
169 | ret = add_munmap(addr, end - addr, ops, | ||
170 | &op_index, last_op, mmu, | ||
171 | &flush, do_ops); | ||
172 | pud_mkuptodate(*npud); | ||
173 | } | ||
174 | addr = end; | ||
175 | continue; | ||
176 | } | ||
177 | |||
178 | npmd = pmd_offset(npud, addr); | ||
179 | if(!pmd_present(*npmd)){ | ||
180 | end = ADD_ROUND(addr, PMD_SIZE); | ||
181 | if(end > end_addr) | ||
182 | end = end_addr; | ||
183 | if(force || pmd_newpage(*npmd)){ | ||
184 | ret = add_munmap(addr, end - addr, ops, | ||
185 | &op_index, last_op, mmu, | 240 | &op_index, last_op, mmu, |
186 | &flush, do_ops); | 241 | &flush, do_ops); |
187 | pmd_mkuptodate(*npmd); | 242 | pgd_mkuptodate(*pgd); |
188 | } | 243 | } |
189 | addr = end; | ||
190 | continue; | ||
191 | } | ||
192 | |||
193 | npte = pte_offset_kernel(npmd, addr); | ||
194 | r = pte_read(*npte); | ||
195 | w = pte_write(*npte); | ||
196 | x = pte_exec(*npte); | ||
197 | if (!pte_young(*npte)) { | ||
198 | r = 0; | ||
199 | w = 0; | ||
200 | } else if (!pte_dirty(*npte)) { | ||
201 | w = 0; | ||
202 | } | ||
203 | if(force || pte_newpage(*npte)){ | ||
204 | if(pte_present(*npte)) | ||
205 | ret = add_mmap(addr, | ||
206 | pte_val(*npte) & PAGE_MASK, | ||
207 | PAGE_SIZE, r, w, x, ops, | ||
208 | &op_index, last_op, mmu, | ||
209 | &flush, do_ops); | ||
210 | else ret = add_munmap(addr, PAGE_SIZE, ops, | ||
211 | &op_index, last_op, mmu, | ||
212 | &flush, do_ops); | ||
213 | } | 244 | } |
214 | else if(pte_newprot(*npte)) | 245 | else ret = update_pud_range(pgd, addr, next, ops, last_op, |
215 | ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, | 246 | &op_index, force, mmu, &flush, |
216 | &op_index, last_op, mmu, | 247 | do_ops); |
217 | &flush, do_ops); | 248 | } while (pgd++, addr = next, ((addr != end_addr) && !ret)); |
218 | 249 | ||
219 | *npte = pte_mkuptodate(*npte); | ||
220 | addr += PAGE_SIZE; | ||
221 | } | ||
222 | if(!ret) | 250 | if(!ret) |
223 | ret = (*do_ops)(mmu, ops, op_index, 1, &flush); | 251 | ret = (*do_ops)(mmu, ops, op_index, 1, &flush); |
224 | 252 | ||
225 | /* This is not an else because ret is modified above */ | 253 | /* This is not an else because ret is modified above */ |
226 | if(ret) { | 254 | if(ret) { |
227 | printk("fix_range_common: failed, killing current process\n"); | 255 | printk("fix_range_common: failed, killing current process\n"); |
228 | force_sig(SIGKILL, current); | 256 | force_sig(SIGKILL, current); |
@@ -343,12 +371,6 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) | |||
343 | return(pte_offset_map(pmd, addr)); | 371 | return(pte_offset_map(pmd, addr)); |
344 | } | 372 | } |
345 | 373 | ||
346 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) | ||
347 | { | ||
348 | address &= PAGE_MASK; | ||
349 | flush_tlb_range(vma, address, address + PAGE_SIZE); | ||
350 | } | ||
351 | |||
352 | void flush_tlb_all(void) | 374 | void flush_tlb_all(void) |
353 | { | 375 | { |
354 | flush_tlb_mm(current->mm); | 376 | flush_tlb_mm(current->mm); |
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 26f15c458574..abab90c3803f 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -18,8 +18,9 @@ | |||
18 | #include "asm/current.h" | 18 | #include "asm/current.h" |
19 | #include "asm/irq.h" | 19 | #include "asm/irq.h" |
20 | #include "sysdep/sigcontext.h" | 20 | #include "sysdep/sigcontext.h" |
21 | #include "user_util.h" | ||
22 | #include "kern_util.h" | 21 | #include "kern_util.h" |
22 | #include "as-layout.h" | ||
23 | #include "arch.h" | ||
23 | #include "kern.h" | 24 | #include "kern.h" |
24 | #include "chan_kern.h" | 25 | #include "chan_kern.h" |
25 | #include "mconsole_kern.h" | 26 | #include "mconsole_kern.h" |
@@ -71,8 +72,8 @@ good_area: | |||
71 | goto out; | 72 | goto out; |
72 | 73 | ||
73 | /* Don't require VM_READ|VM_EXEC for write faults! */ | 74 | /* Don't require VM_READ|VM_EXEC for write faults! */ |
74 | if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) | 75 | if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) |
75 | goto out; | 76 | goto out; |
76 | 77 | ||
77 | do { | 78 | do { |
78 | survive: | 79 | survive: |
@@ -156,20 +157,23 @@ static void segv_handler(int sig, union uml_pt_regs *regs) | |||
156 | * the info in the regs. A pointer to the info then would | 157 | * the info in the regs. A pointer to the info then would |
157 | * give us bad data! | 158 | * give us bad data! |
158 | */ | 159 | */ |
159 | unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | 160 | unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, |
161 | union uml_pt_regs *regs) | ||
160 | { | 162 | { |
161 | struct siginfo si; | 163 | struct siginfo si; |
162 | void *catcher; | 164 | void *catcher; |
163 | int err; | 165 | int err; |
164 | int is_write = FAULT_WRITE(fi); | 166 | int is_write = FAULT_WRITE(fi); |
165 | unsigned long address = FAULT_ADDRESS(fi); | 167 | unsigned long address = FAULT_ADDRESS(fi); |
166 | 168 | ||
167 | if(!is_user && (address >= start_vm) && (address < end_vm)){ | 169 | if(!is_user && (address >= start_vm) && (address < end_vm)){ |
168 | flush_tlb_kernel_vm(); | 170 | flush_tlb_kernel_vm(); |
169 | return(0); | 171 | return 0; |
170 | } | 172 | } |
171 | else if(current->mm == NULL) | 173 | else if(current->mm == NULL) { |
172 | panic("Segfault with no mm"); | 174 | show_regs(container_of(regs, struct pt_regs, regs)); |
175 | panic("Segfault with no mm"); | ||
176 | } | ||
173 | 177 | ||
174 | if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) | 178 | if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) |
175 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | 179 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); |
@@ -182,26 +186,28 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |||
182 | 186 | ||
183 | catcher = current->thread.fault_catcher; | 187 | catcher = current->thread.fault_catcher; |
184 | if(!err) | 188 | if(!err) |
185 | return(0); | 189 | return 0; |
186 | else if(catcher != NULL){ | 190 | else if(catcher != NULL){ |
187 | current->thread.fault_addr = (void *) address; | 191 | current->thread.fault_addr = (void *) address; |
188 | do_longjmp(catcher, 1); | 192 | do_longjmp(catcher, 1); |
189 | } | 193 | } |
190 | else if(current->thread.fault_addr != NULL) | 194 | else if(current->thread.fault_addr != NULL) |
191 | panic("fault_addr set but no fault catcher"); | 195 | panic("fault_addr set but no fault catcher"); |
192 | else if(!is_user && arch_fixup(ip, sc)) | 196 | else if(!is_user && arch_fixup(ip, regs)) |
193 | return(0); | 197 | return 0; |
194 | 198 | ||
195 | if(!is_user) | 199 | if(!is_user) { |
200 | show_regs(container_of(regs, struct pt_regs, regs)); | ||
196 | panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", | 201 | panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", |
197 | address, ip); | 202 | address, ip); |
203 | } | ||
198 | 204 | ||
199 | if (err == -EACCES) { | 205 | if (err == -EACCES) { |
200 | si.si_signo = SIGBUS; | 206 | si.si_signo = SIGBUS; |
201 | si.si_errno = 0; | 207 | si.si_errno = 0; |
202 | si.si_code = BUS_ADRERR; | 208 | si.si_code = BUS_ADRERR; |
203 | si.si_addr = (void __user *)address; | 209 | si.si_addr = (void __user *)address; |
204 | current->thread.arch.faultinfo = fi; | 210 | current->thread.arch.faultinfo = fi; |
205 | force_sig_info(SIGBUS, &si, current); | 211 | force_sig_info(SIGBUS, &si, current); |
206 | } else if (err == -ENOMEM) { | 212 | } else if (err == -ENOMEM) { |
207 | printk("VM: killing process %s\n", current->comm); | 213 | printk("VM: killing process %s\n", current->comm); |
@@ -210,10 +216,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |||
210 | BUG_ON(err != -EFAULT); | 216 | BUG_ON(err != -EFAULT); |
211 | si.si_signo = SIGSEGV; | 217 | si.si_signo = SIGSEGV; |
212 | si.si_addr = (void __user *) address; | 218 | si.si_addr = (void __user *) address; |
213 | current->thread.arch.faultinfo = fi; | 219 | current->thread.arch.faultinfo = fi; |
214 | force_sig_info(SIGSEGV, &si, current); | 220 | force_sig_info(SIGSEGV, &si, current); |
215 | } | 221 | } |
216 | return(0); | 222 | return 0; |
217 | } | 223 | } |
218 | 224 | ||
219 | void relay_signal(int sig, union uml_pt_regs *regs) | 225 | void relay_signal(int sig, union uml_pt_regs *regs) |
@@ -223,12 +229,12 @@ void relay_signal(int sig, union uml_pt_regs *regs) | |||
223 | 229 | ||
224 | if(!UPT_IS_USER(regs)){ | 230 | if(!UPT_IS_USER(regs)){ |
225 | if(sig == SIGBUS) | 231 | if(sig == SIGBUS) |
226 | printk("Bus error - the /dev/shm or /tmp mount likely " | 232 | printk("Bus error - the host /dev/shm or /tmp mount " |
227 | "just ran out of space\n"); | 233 | "likely just ran out of space\n"); |
228 | panic("Kernel mode signal %d", sig); | 234 | panic("Kernel mode signal %d", sig); |
229 | } | 235 | } |
230 | 236 | ||
231 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); | 237 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); |
232 | force_sig(sig, current); | 238 | force_sig(sig, current); |
233 | } | 239 | } |
234 | 240 | ||
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c index ad66df17d9d7..98e21743e604 100644 --- a/arch/um/kernel/tt/exec_kern.c +++ b/arch/um/kernel/tt/exec_kern.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "asm/uaccess.h" | 10 | #include "asm/uaccess.h" |
11 | #include "asm/pgalloc.h" | 11 | #include "asm/pgalloc.h" |
12 | #include "asm/tlbflush.h" | 12 | #include "asm/tlbflush.h" |
13 | #include "user_util.h" | ||
14 | #include "kern_util.h" | 13 | #include "kern_util.h" |
15 | #include "irq_user.h" | 14 | #include "irq_user.h" |
16 | #include "mem_user.h" | 15 | #include "mem_user.h" |
diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c index a92c02ff2ce3..7b5f2181cf51 100644 --- a/arch/um/kernel/tt/exec_user.c +++ b/arch/um/kernel/tt/exec_user.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <errno.h> | 10 | #include <errno.h> |
11 | #include <sys/wait.h> | 11 | #include <sys/wait.h> |
12 | #include <signal.h> | 12 | #include <signal.h> |
13 | #include "user_util.h" | ||
14 | #include "kern_util.h" | 13 | #include "kern_util.h" |
15 | #include "user.h" | 14 | #include "user.h" |
16 | #include "ptrace_user.h" | 15 | #include "ptrace_user.h" |
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c index 8eba8f7dca68..030e4658f36b 100644 --- a/arch/um/kernel/tt/gdb.c +++ b/arch/um/kernel/tt/gdb.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include "user.h" | 17 | #include "user.h" |
18 | #include "debug.h" | 18 | #include "debug.h" |
19 | #include "kern_util.h" | 19 | #include "kern_util.h" |
20 | #include "user_util.h" | ||
21 | #include "tt.h" | 20 | #include "tt.h" |
22 | #include "sysdep/thread.h" | 21 | #include "sysdep/thread.h" |
23 | #include "os.h" | 22 | #include "os.h" |
@@ -115,6 +114,8 @@ struct gdb_data { | |||
115 | int err; | 114 | int err; |
116 | }; | 115 | }; |
117 | 116 | ||
117 | extern char *linux_prog; | ||
118 | |||
118 | static void config_gdb_cb(void *arg) | 119 | static void config_gdb_cb(void *arg) |
119 | { | 120 | { |
120 | struct gdb_data *data = arg; | 121 | struct gdb_data *data = arg; |
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h deleted file mode 100644 index 2a35b15c5fef..000000000000 --- a/arch/um/kernel/tt/include/mode_kern-tt.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __TT_MODE_KERN_H__ | ||
7 | #define __TT_MODE_KERN_H__ | ||
8 | |||
9 | #include "linux/sched.h" | ||
10 | #include "asm/page.h" | ||
11 | #include "asm/ptrace.h" | ||
12 | #include "asm/uaccess.h" | ||
13 | |||
14 | extern void switch_to_tt(void *prev, void *next); | ||
15 | extern void flush_thread_tt(void); | ||
16 | extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, | ||
17 | unsigned long esp); | ||
18 | extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, | ||
19 | unsigned long stack_top, struct task_struct *p, | ||
20 | struct pt_regs *regs); | ||
21 | extern void release_thread_tt(struct task_struct *task); | ||
22 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); | ||
23 | extern void init_idle_tt(void); | ||
24 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); | ||
25 | extern void flush_tlb_kernel_vm_tt(void); | ||
26 | extern void __flush_tlb_one_tt(unsigned long addr); | ||
27 | extern void flush_tlb_range_tt(struct vm_area_struct *vma, | ||
28 | unsigned long start, unsigned long end); | ||
29 | extern void flush_tlb_mm_tt(struct mm_struct *mm); | ||
30 | extern void force_flush_all_tt(void); | ||
31 | extern long execute_syscall_tt(void *r); | ||
32 | extern void before_mem_tt(unsigned long brk_start); | ||
33 | extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, | ||
34 | unsigned long *task_size_out); | ||
35 | extern int start_uml_tt(void); | ||
36 | extern int external_pid_tt(struct task_struct *task); | ||
37 | extern int thread_pid_tt(struct task_struct *task); | ||
38 | |||
39 | #define kmem_end_tt (host_task_size - ABOVE_KMEM) | ||
40 | |||
41 | #endif | ||
42 | |||
43 | /* | ||
44 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
45 | * Emacs will notice this stuff at the end of the file and automatically | ||
46 | * adjust the settings for this buffer only. This must remain at the end | ||
47 | * of the file. | ||
48 | * --------------------------------------------------------------------------- | ||
49 | * Local variables: | ||
50 | * c-file-style: "linux" | ||
51 | * End: | ||
52 | */ | ||
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c index 4d1929dfa285..d0c3c4975f28 100644 --- a/arch/um/kernel/tt/mem.c +++ b/arch/um/kernel/tt/mem.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include "asm/uaccess.h" | 8 | #include "asm/uaccess.h" |
9 | #include "mem_user.h" | 9 | #include "mem_user.h" |
10 | #include "kern_util.h" | 10 | #include "kern_util.h" |
11 | #include "user_util.h" | ||
12 | #include "kern.h" | 11 | #include "kern.h" |
13 | #include "tt.h" | 12 | #include "tt.h" |
14 | 13 | ||
diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c index 03e589895388..9774f6360c32 100644 --- a/arch/um/kernel/tt/mem_user.c +++ b/arch/um/kernel/tt/mem_user.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <sys/mman.h> | 11 | #include <sys/mman.h> |
12 | #include "tt.h" | 12 | #include "tt.h" |
13 | #include "mem_user.h" | 13 | #include "mem_user.h" |
14 | #include "user_util.h" | ||
15 | #include "os.h" | 14 | #include "os.h" |
16 | 15 | ||
17 | void remap_data(void *segment_start, void *segment_end, int w) | 16 | void remap_data(void *segment_start, void *segment_end, int w) |
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 1e86f0bfef72..c631303cb800 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include "asm/tlbflush.h" | 14 | #include "asm/tlbflush.h" |
15 | #include "irq_user.h" | 15 | #include "irq_user.h" |
16 | #include "kern_util.h" | 16 | #include "kern_util.h" |
17 | #include "user_util.h" | ||
18 | #include "os.h" | 17 | #include "os.h" |
19 | #include "kern.h" | 18 | #include "kern.h" |
20 | #include "sigcontext.h" | 19 | #include "sigcontext.h" |
@@ -65,7 +64,8 @@ void switch_to_tt(void *prev, void *next) | |||
65 | if(from->thread.mode.tt.switch_pipe[0] == -1) | 64 | if(from->thread.mode.tt.switch_pipe[0] == -1) |
66 | os_kill_process(os_getpid(), 0); | 65 | os_kill_process(os_getpid(), 0); |
67 | 66 | ||
68 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); | 67 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, |
68 | sizeof(c)); | ||
69 | if(err != sizeof(c)) | 69 | if(err != sizeof(c)) |
70 | panic("read of switch_pipe failed, errno = %d", -err); | 70 | panic("read of switch_pipe failed, errno = %d", -err); |
71 | 71 | ||
diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c index 58800c50b10e..420c23f311f3 100644 --- a/arch/um/kernel/tt/ptproxy/proxy.c +++ b/arch/um/kernel/tt/ptproxy/proxy.c | |||
@@ -26,7 +26,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml | |||
26 | #include "sysdep.h" | 26 | #include "sysdep.h" |
27 | #include "wait.h" | 27 | #include "wait.h" |
28 | 28 | ||
29 | #include "user_util.h" | ||
30 | #include "user.h" | 29 | #include "user.h" |
31 | #include "os.h" | 30 | #include "os.h" |
32 | #include "tempfile.h" | 31 | #include "tempfile.h" |
@@ -339,11 +338,12 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out) | |||
339 | "err = %d\n", -fd); | 338 | "err = %d\n", -fd); |
340 | exit(1); | 339 | exit(1); |
341 | } | 340 | } |
342 | os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1); | 341 | os_write_file(fd, gdb_init_string, |
342 | sizeof(gdb_init_string) - 1); | ||
343 | if(startup){ | 343 | if(startup){ |
344 | if(stop){ | 344 | if(stop){ |
345 | os_write_file(fd, "b start_kernel\n", | 345 | os_write_file(fd, "b start_kernel\n", |
346 | strlen("b start_kernel\n")); | 346 | strlen("b start_kernel\n")); |
347 | } | 347 | } |
348 | os_write_file(fd, "c\n", strlen("c\n")); | 348 | os_write_file(fd, "c\n", strlen("c\n")); |
349 | } | 349 | } |
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c index 03774427d468..4b4f6179b212 100644 --- a/arch/um/kernel/tt/ptproxy/ptrace.c +++ b/arch/um/kernel/tt/ptproxy/ptrace.c | |||
@@ -16,7 +16,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml | |||
16 | 16 | ||
17 | #include "ptproxy.h" | 17 | #include "ptproxy.h" |
18 | #include "debug.h" | 18 | #include "debug.h" |
19 | #include "user_util.h" | ||
20 | #include "kern_util.h" | 19 | #include "kern_util.h" |
21 | #include "ptrace_user.h" | 20 | #include "ptrace_user.h" |
22 | #include "tt.h" | 21 | #include "tt.h" |
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c index 99f178319d03..e0e1ab0588ad 100644 --- a/arch/um/kernel/tt/ptproxy/sysdep.c +++ b/arch/um/kernel/tt/ptproxy/sysdep.c | |||
@@ -13,7 +13,6 @@ terms and conditions. | |||
13 | #include <sys/types.h> | 13 | #include <sys/types.h> |
14 | #include <linux/unistd.h> | 14 | #include <linux/unistd.h> |
15 | #include "ptrace_user.h" | 15 | #include "ptrace_user.h" |
16 | #include "user_util.h" | ||
17 | #include "user.h" | 16 | #include "user.h" |
18 | #include "os.h" | 17 | #include "os.h" |
19 | 18 | ||
diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c index 12f6319d8d76..bdd4af4b65fc 100644 --- a/arch/um/kernel/tt/ptproxy/wait.c +++ b/arch/um/kernel/tt/ptproxy/wait.c | |||
@@ -13,7 +13,6 @@ terms and conditions. | |||
13 | #include "ptproxy.h" | 13 | #include "ptproxy.h" |
14 | #include "sysdep.h" | 14 | #include "sysdep.h" |
15 | #include "wait.h" | 15 | #include "wait.h" |
16 | #include "user_util.h" | ||
17 | #include "ptrace_user.h" | 16 | #include "ptrace_user.h" |
18 | #include "sysdep/ptrace.h" | 17 | #include "sysdep/ptrace.h" |
19 | #include "sysdep/sigcontext.h" | 18 | #include "sysdep/sigcontext.h" |
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c index 902987bf379b..f52b47aff1d2 100644 --- a/arch/um/kernel/tt/syscall_user.c +++ b/arch/um/kernel/tt/syscall_user.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include "sigcontext.h" | 11 | #include "sigcontext.h" |
12 | #include "ptrace_user.h" | 12 | #include "ptrace_user.h" |
13 | #include "task.h" | 13 | #include "task.h" |
14 | #include "user_util.h" | ||
15 | #include "kern_util.h" | 14 | #include "kern_util.h" |
16 | #include "syscall.h" | 15 | #include "syscall.h" |
17 | #include "tt.h" | 16 | #include "tt.h" |
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c index ae6217c86135..7caa24fe05df 100644 --- a/arch/um/kernel/tt/tlb.c +++ b/arch/um/kernel/tt/tlb.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include "asm/pgtable.h" | 12 | #include "asm/pgtable.h" |
13 | #include "asm/uaccess.h" | 13 | #include "asm/uaccess.h" |
14 | #include "asm/tlbflush.h" | 14 | #include "asm/tlbflush.h" |
15 | #include "user_util.h" | ||
16 | #include "mem_user.h" | 15 | #include "mem_user.h" |
17 | #include "os.h" | 16 | #include "os.h" |
18 | #include "tlb.h" | 17 | #include "tlb.h" |
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index b9195355075a..c23588393f6e 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include "sigcontext.h" | 19 | #include "sigcontext.h" |
20 | #include "sysdep/sigcontext.h" | 20 | #include "sysdep/sigcontext.h" |
21 | #include "os.h" | 21 | #include "os.h" |
22 | #include "user_util.h" | ||
23 | #include "mem_user.h" | 22 | #include "mem_user.h" |
24 | #include "process.h" | 23 | #include "process.h" |
25 | #include "kern_util.h" | 24 | #include "kern_util.h" |
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index b5d9d64d91e4..3032eb5e2467 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <signal.h> | 8 | #include <signal.h> |
9 | #include "sysdep/ptrace.h" | 9 | #include "sysdep/ptrace.h" |
10 | #include "sysdep/sigcontext.h" | 10 | #include "sysdep/sigcontext.h" |
11 | #include "user_util.h" | ||
12 | #include "kern_util.h" | 11 | #include "kern_util.h" |
13 | #include "task.h" | 12 | #include "task.h" |
14 | #include "tt.h" | 13 | #include "tt.h" |
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c index ed1abcf4d057..0e5c82c5e5b7 100644 --- a/arch/um/kernel/tt/uaccess_user.c +++ b/arch/um/kernel/tt/uaccess_user.c | |||
@@ -5,7 +5,6 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <string.h> | 7 | #include <string.h> |
8 | #include "user_util.h" | ||
9 | #include "uml_uaccess.h" | 8 | #include "uml_uaccess.h" |
10 | #include "task.h" | 9 | #include "task.h" |
11 | #include "kern_util.h" | 10 | #include "kern_util.h" |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 89c6dba731f8..1cf954a47fd7 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "linux/seq_file.h" | 17 | #include "linux/seq_file.h" |
18 | #include "linux/delay.h" | 18 | #include "linux/delay.h" |
19 | #include "linux/module.h" | 19 | #include "linux/module.h" |
20 | #include "linux/utsname.h" | ||
20 | #include "asm/page.h" | 21 | #include "asm/page.h" |
21 | #include "asm/pgtable.h" | 22 | #include "asm/pgtable.h" |
22 | #include "asm/ptrace.h" | 23 | #include "asm/ptrace.h" |
@@ -25,8 +26,9 @@ | |||
25 | #include "asm/setup.h" | 26 | #include "asm/setup.h" |
26 | #include "ubd_user.h" | 27 | #include "ubd_user.h" |
27 | #include "asm/current.h" | 28 | #include "asm/current.h" |
28 | #include "user_util.h" | ||
29 | #include "kern_util.h" | 29 | #include "kern_util.h" |
30 | #include "as-layout.h" | ||
31 | #include "arch.h" | ||
30 | #include "kern.h" | 32 | #include "kern.h" |
31 | #include "mem_user.h" | 33 | #include "mem_user.h" |
32 | #include "mem.h" | 34 | #include "mem.h" |
@@ -42,7 +44,7 @@ | |||
42 | 44 | ||
43 | #define DEFAULT_COMMAND_LINE "root=98:0" | 45 | #define DEFAULT_COMMAND_LINE "root=98:0" |
44 | 46 | ||
45 | /* Changed in linux_main and setup_arch, which run before SMP is started */ | 47 | /* Changed in add_arg and setup_arch, which run before SMP is started */ |
46 | static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; | 48 | static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; |
47 | 49 | ||
48 | static void __init add_arg(char *arg) | 50 | static void __init add_arg(char *arg) |
@@ -56,17 +58,25 @@ static void __init add_arg(char *arg) | |||
56 | strcat(command_line, arg); | 58 | strcat(command_line, arg); |
57 | } | 59 | } |
58 | 60 | ||
59 | struct cpuinfo_um boot_cpu_data = { | 61 | /* |
62 | * These fields are initialized at boot time and not changed. | ||
63 | * XXX This structure is used only in the non-SMP case. Maybe this | ||
64 | * should be moved to smp.c. | ||
65 | */ | ||
66 | struct cpuinfo_um boot_cpu_data = { | ||
60 | .loops_per_jiffy = 0, | 67 | .loops_per_jiffy = 0, |
61 | .ipi_pipe = { -1, -1 } | 68 | .ipi_pipe = { -1, -1 } |
62 | }; | 69 | }; |
63 | 70 | ||
64 | unsigned long thread_saved_pc(struct task_struct *task) | 71 | unsigned long thread_saved_pc(struct task_struct *task) |
65 | { | 72 | { |
66 | return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, | 73 | return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, |
67 | task))); | 74 | task)); |
68 | } | 75 | } |
69 | 76 | ||
77 | /* Changed in setup_arch, which is called in early boot */ | ||
78 | static char host_info[(__NEW_UTS_LEN + 1) * 5]; | ||
79 | |||
70 | static int show_cpuinfo(struct seq_file *m, void *v) | 80 | static int show_cpuinfo(struct seq_file *m, void *v) |
71 | { | 81 | { |
72 | int index = 0; | 82 | int index = 0; |
@@ -86,7 +96,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
86 | loops_per_jiffy/(500000/HZ), | 96 | loops_per_jiffy/(500000/HZ), |
87 | (loops_per_jiffy/(5000/HZ)) % 100); | 97 | (loops_per_jiffy/(5000/HZ)) % 100); |
88 | 98 | ||
89 | return(0); | 99 | return 0; |
90 | } | 100 | } |
91 | 101 | ||
92 | static void *c_start(struct seq_file *m, loff_t *pos) | 102 | static void *c_start(struct seq_file *m, loff_t *pos) |
@@ -114,14 +124,12 @@ const struct seq_operations cpuinfo_op = { | |||
114 | /* Set in linux_main */ | 124 | /* Set in linux_main */ |
115 | unsigned long host_task_size; | 125 | unsigned long host_task_size; |
116 | unsigned long task_size; | 126 | unsigned long task_size; |
117 | |||
118 | unsigned long uml_start; | ||
119 | |||
120 | /* Set in early boot */ | ||
121 | unsigned long uml_physmem; | 127 | unsigned long uml_physmem; |
122 | unsigned long uml_reserved; | 128 | unsigned long uml_reserved; /* Also modified in mem_init */ |
123 | unsigned long start_vm; | 129 | unsigned long start_vm; |
124 | unsigned long end_vm; | 130 | unsigned long end_vm; |
131 | |||
132 | /* Set in uml_ncpus_setup */ | ||
125 | int ncpus = 1; | 133 | int ncpus = 1; |
126 | 134 | ||
127 | #ifdef CONFIG_CMDLINE_ON_HOST | 135 | #ifdef CONFIG_CMDLINE_ON_HOST |
@@ -135,6 +143,8 @@ static char *argv1_end = NULL; | |||
135 | 143 | ||
136 | /* Set in early boot */ | 144 | /* Set in early boot */ |
137 | static int have_root __initdata = 0; | 145 | static int have_root __initdata = 0; |
146 | |||
147 | /* Set in uml_mem_setup and modified in linux_main */ | ||
138 | long long physmem_size = 32 * 1024 * 1024; | 148 | long long physmem_size = 32 * 1024 * 1024; |
139 | 149 | ||
140 | void set_cmdline(char *cmd) | 150 | void set_cmdline(char *cmd) |
@@ -212,12 +222,12 @@ __uml_setup("debug", no_skas_debug_setup, | |||
212 | #ifdef CONFIG_SMP | 222 | #ifdef CONFIG_SMP |
213 | static int __init uml_ncpus_setup(char *line, int *add) | 223 | static int __init uml_ncpus_setup(char *line, int *add) |
214 | { | 224 | { |
215 | if (!sscanf(line, "%d", &ncpus)) { | 225 | if (!sscanf(line, "%d", &ncpus)) { |
216 | printf("Couldn't parse [%s]\n", line); | 226 | printf("Couldn't parse [%s]\n", line); |
217 | return -1; | 227 | return -1; |
218 | } | 228 | } |
219 | 229 | ||
220 | return 0; | 230 | return 0; |
221 | } | 231 | } |
222 | 232 | ||
223 | __uml_setup("ncpus=", uml_ncpus_setup, | 233 | __uml_setup("ncpus=", uml_ncpus_setup, |
@@ -234,7 +244,7 @@ static int force_tt = 0; | |||
234 | static int __init mode_tt_setup(char *line, int *add) | 244 | static int __init mode_tt_setup(char *line, int *add) |
235 | { | 245 | { |
236 | force_tt = 1; | 246 | force_tt = 1; |
237 | return(0); | 247 | return 0; |
238 | } | 248 | } |
239 | 249 | ||
240 | #else | 250 | #else |
@@ -245,7 +255,7 @@ static int __init mode_tt_setup(char *line, int *add) | |||
245 | static int __init mode_tt_setup(char *line, int *add) | 255 | static int __init mode_tt_setup(char *line, int *add) |
246 | { | 256 | { |
247 | printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); | 257 | printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); |
248 | return(0); | 258 | return 0; |
249 | } | 259 | } |
250 | 260 | ||
251 | #else | 261 | #else |
@@ -256,7 +266,7 @@ static int __init mode_tt_setup(char *line, int *add) | |||
256 | static int __init mode_tt_setup(char *line, int *add) | 266 | static int __init mode_tt_setup(char *line, int *add) |
257 | { | 267 | { |
258 | printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); | 268 | printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); |
259 | return(0); | 269 | return 0; |
260 | } | 270 | } |
261 | 271 | ||
262 | #endif | 272 | #endif |
@@ -274,16 +284,15 @@ int mode_tt = DEFAULT_TT; | |||
274 | 284 | ||
275 | static int __init Usage(char *line, int *add) | 285 | static int __init Usage(char *line, int *add) |
276 | { | 286 | { |
277 | const char **p; | 287 | const char **p; |
278 | 288 | ||
279 | printf(usage_string, init_utsname()->release); | 289 | printf(usage_string, init_utsname()->release); |
280 | p = &__uml_help_start; | 290 | p = &__uml_help_start; |
281 | while (p < &__uml_help_end) { | 291 | while (p < &__uml_help_end) { |
282 | printf("%s", *p); | 292 | printf("%s", *p); |
283 | p++; | 293 | p++; |
284 | } | 294 | } |
285 | exit(0); | 295 | exit(0); |
286 | |||
287 | return 0; | 296 | return 0; |
288 | } | 297 | } |
289 | 298 | ||
@@ -374,13 +383,12 @@ int __init linux_main(int argc, char **argv) | |||
374 | 383 | ||
375 | printf("UML running in %s mode\n", mode); | 384 | printf("UML running in %s mode\n", mode); |
376 | 385 | ||
377 | uml_start = (unsigned long) &__binary_start; | ||
378 | host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, | 386 | host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, |
379 | set_task_sizes_skas, &task_size); | 387 | set_task_sizes_skas, &task_size); |
380 | 388 | ||
381 | /* | 389 | /* |
382 | * Setting up handlers to 'sig_info' struct | 390 | * Setting up handlers to 'sig_info' struct |
383 | */ | 391 | */ |
384 | os_fill_handlinfo(handlinfo_kern); | 392 | os_fill_handlinfo(handlinfo_kern); |
385 | 393 | ||
386 | brk_start = (unsigned long) sbrk(0); | 394 | brk_start = (unsigned long) sbrk(0); |
@@ -396,7 +404,7 @@ int __init linux_main(int argc, char **argv) | |||
396 | physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); | 404 | physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); |
397 | } | 405 | } |
398 | 406 | ||
399 | uml_physmem = uml_start & PAGE_MASK; | 407 | uml_physmem = (unsigned long) &__binary_start & PAGE_MASK; |
400 | 408 | ||
401 | /* Reserve up to 4M after the current brk */ | 409 | /* Reserve up to 4M after the current brk */ |
402 | uml_reserved = ROUND_4M(brk_start) + (1 << 22); | 410 | uml_reserved = ROUND_4M(brk_start) + (1 << 22); |
@@ -407,7 +415,7 @@ int __init linux_main(int argc, char **argv) | |||
407 | argv1_begin = argv[1]; | 415 | argv1_begin = argv[1]; |
408 | argv1_end = &argv[1][strlen(argv[1])]; | 416 | argv1_end = &argv[1][strlen(argv[1])]; |
409 | #endif | 417 | #endif |
410 | 418 | ||
411 | highmem = 0; | 419 | highmem = 0; |
412 | iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; | 420 | iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; |
413 | max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; | 421 | max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; |
@@ -449,12 +457,12 @@ int __init linux_main(int argc, char **argv) | |||
449 | printf("Kernel virtual memory size shrunk to %lu bytes\n", | 457 | printf("Kernel virtual memory size shrunk to %lu bytes\n", |
450 | virtmem_size); | 458 | virtmem_size); |
451 | 459 | ||
452 | uml_postsetup(); | 460 | uml_postsetup(); |
453 | 461 | ||
454 | task_protections((unsigned long) &init_thread_info); | 462 | task_protections((unsigned long) &init_thread_info); |
455 | os_flush_stdout(); | 463 | os_flush_stdout(); |
456 | 464 | ||
457 | return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); | 465 | return CHOOSE_MODE(start_uml_tt(), start_uml_skas()); |
458 | } | 466 | } |
459 | 467 | ||
460 | extern int uml_exitcode; | 468 | extern int uml_exitcode; |
@@ -466,8 +474,8 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1, | |||
466 | show_regs(&(current->thread.regs)); | 474 | show_regs(&(current->thread.regs)); |
467 | bust_spinlocks(0); | 475 | bust_spinlocks(0); |
468 | uml_exitcode = 1; | 476 | uml_exitcode = 1; |
469 | machine_halt(); | 477 | os_dump_core(); |
470 | return(0); | 478 | return 0; |
471 | } | 479 | } |
472 | 480 | ||
473 | static struct notifier_block panic_exit_notifier = { | 481 | static struct notifier_block panic_exit_notifier = { |
@@ -482,14 +490,14 @@ void __init setup_arch(char **cmdline_p) | |||
482 | &panic_exit_notifier); | 490 | &panic_exit_notifier); |
483 | paging_init(); | 491 | paging_init(); |
484 | strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | 492 | strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); |
485 | *cmdline_p = command_line; | 493 | *cmdline_p = command_line; |
486 | setup_hostinfo(); | 494 | setup_hostinfo(host_info, sizeof host_info); |
487 | } | 495 | } |
488 | 496 | ||
489 | void __init check_bugs(void) | 497 | void __init check_bugs(void) |
490 | { | 498 | { |
491 | arch_check_bugs(); | 499 | arch_check_bugs(); |
492 | os_check_bugs(); | 500 | os_check_bugs(); |
493 | } | 501 | } |
494 | 502 | ||
495 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) | 503 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) |