diff options
Diffstat (limited to 'arch/um/kernel/um_arch.c')
-rw-r--r-- | arch/um/kernel/um_arch.c | 84 |
1 files changed, 46 insertions, 38 deletions
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) |