uml: formatting fixes
[deliverable/linux.git] / arch / um / kernel / um_arch.c
CommitLineData
ea2ba7dc 1/*
1da177e4
LT
2 * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
1da177e4
LT
6#include "linux/kernel.h"
7#include "linux/sched.h"
8#include "linux/notifier.h"
9#include "linux/mm.h"
10#include "linux/types.h"
11#include "linux/tty.h"
12#include "linux/init.h"
13#include "linux/bootmem.h"
14#include "linux/spinlock.h"
15#include "linux/utsname.h"
16#include "linux/sysrq.h"
17#include "linux/seq_file.h"
18#include "linux/delay.h"
19#include "linux/module.h"
20#include "asm/page.h"
21#include "asm/pgtable.h"
22#include "asm/ptrace.h"
23#include "asm/elf.h"
24#include "asm/user.h"
16c11163 25#include "asm/setup.h"
1da177e4
LT
26#include "ubd_user.h"
27#include "asm/current.h"
1da177e4
LT
28#include "user_util.h"
29#include "kern_util.h"
30#include "kern.h"
31#include "mem_user.h"
32#include "mem.h"
1da177e4
LT
33#include "initrd.h"
34#include "init.h"
35#include "os.h"
36#include "choose-mode.h"
37#include "mode_kern.h"
38#include "mode.h"
cb66504d
PBG
39#ifdef UML_CONFIG_MODE_SKAS
40#include "skas.h"
41#endif
1da177e4
LT
42
43#define DEFAULT_COMMAND_LINE "root=98:0"
44
45/* Changed in linux_main and setup_arch, which run before SMP is started */
7a3a06d0 46static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 };
1da177e4 47
7a3a06d0 48static void __init add_arg(char *arg)
1da177e4
LT
49{
50 if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
51 printf("add_arg: Too many command line arguments!\n");
52 exit(1);
53 }
54 if(strlen(command_line) > 0)
55 strcat(command_line, " ");
56 strcat(command_line, arg);
57}
58
59struct cpuinfo_um boot_cpu_data = {
60 .loops_per_jiffy = 0,
61 .ipi_pipe = { -1, -1 }
62};
63
64unsigned long thread_saved_pc(struct task_struct *task)
65{
a5ed1ffa
JD
66 return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
67 task));
1da177e4
LT
68}
69
70static int show_cpuinfo(struct seq_file *m, void *v)
71{
72 int index = 0;
73
74#ifdef CONFIG_SMP
75 index = (struct cpuinfo_um *) v - cpu_data;
76 if (!cpu_online(index))
77 return 0;
78#endif
79
80 seq_printf(m, "processor\t: %d\n", index);
81 seq_printf(m, "vendor_id\t: User Mode Linux\n");
82 seq_printf(m, "model name\t: UML\n");
83 seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
84 seq_printf(m, "host\t\t: %s\n", host_info);
85 seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
86 loops_per_jiffy/(500000/HZ),
87 (loops_per_jiffy/(5000/HZ)) % 100);
88
a5ed1ffa 89 return 0;
1da177e4
LT
90}
91
92static void *c_start(struct seq_file *m, loff_t *pos)
93{
94 return *pos < NR_CPUS ? cpu_data + *pos : NULL;
95}
96
97static void *c_next(struct seq_file *m, void *v, loff_t *pos)
98{
99 ++*pos;
100 return c_start(m, pos);
101}
102
103static void c_stop(struct seq_file *m, void *v)
104{
105}
106
5e7672ec 107const struct seq_operations cpuinfo_op = {
1da177e4
LT
108 .start = c_start,
109 .next = c_next,
110 .stop = c_stop,
111 .show = show_cpuinfo,
112};
113
1da177e4
LT
114/* Set in linux_main */
115unsigned long host_task_size;
116unsigned long task_size;
117
118unsigned long uml_start;
119
120/* Set in early boot */
121unsigned long uml_physmem;
122unsigned long uml_reserved;
123unsigned long start_vm;
124unsigned long end_vm;
125int ncpus = 1;
126
02215759 127#ifdef CONFIG_CMDLINE_ON_HOST
1da177e4
LT
128/* Pointer set in linux_main, the array itself is private to each thread,
129 * and changed at address space creation time so this poses no concurrency
130 * problems.
131 */
132static char *argv1_begin = NULL;
133static char *argv1_end = NULL;
134#endif
135
136/* Set in early boot */
137static int have_root __initdata = 0;
ae173816 138long long physmem_size = 32 * 1024 * 1024;
1da177e4
LT
139
140void set_cmdline(char *cmd)
141{
02215759 142#ifdef CONFIG_CMDLINE_ON_HOST
1da177e4
LT
143 char *umid, *ptr;
144
145 if(CHOOSE_MODE(honeypot, 0)) return;
146
7eebe8a9
JD
147 umid = get_umid();
148 if(*umid != '\0'){
1da177e4
LT
149 snprintf(argv1_begin,
150 (argv1_end - argv1_begin) * sizeof(*ptr),
151 "(%s) ", umid);
152 ptr = &argv1_begin[strlen(argv1_begin)];
153 }
154 else ptr = argv1_begin;
155
156 snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
157 memset(argv1_begin + strlen(argv1_begin), '\0',
158 argv1_end - argv1_begin - strlen(argv1_begin));
159#endif
160}
161
162static char *usage_string =
163"User Mode Linux v%s\n"
164" available at http://user-mode-linux.sourceforge.net/\n\n";
165
166static int __init uml_version_setup(char *line, int *add)
167{
96b644bd 168 printf("%s\n", init_utsname()->release);
1da177e4
LT
169 exit(0);
170
171 return 0;
172}
173
174__uml_setup("--version", uml_version_setup,
175"--version\n"
176" Prints the version number of the kernel.\n\n"
177);
178
179static int __init uml_root_setup(char *line, int *add)
180{
181 have_root = 1;
182 return 0;
183}
184
185__uml_setup("root=", uml_root_setup,
186"root=<file containing the root fs>\n"
187" This is actually used by the generic kernel in exactly the same\n"
188" way as in any other kernel. If you configure a number of block\n"
189" devices and want to boot off something other than ubd0, you \n"
190" would use something like:\n"
191" root=/dev/ubd5\n\n"
192);
193
fbd55779
JD
194#ifndef CONFIG_MODE_TT
195
196static int __init no_skas_debug_setup(char *line, int *add)
197{
198 printf("'debug' is not necessary to gdb UML in skas mode - run \n");
199 printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n");
200 printf("doesn't work as expected\n");
201
202 return 0;
203}
204
205__uml_setup("debug", no_skas_debug_setup,
206"debug\n"
207" this flag is not needed to run gdb on UML in skas mode\n\n"
208);
209
210#endif
211
1da177e4
LT
212#ifdef CONFIG_SMP
213static int __init uml_ncpus_setup(char *line, int *add)
214{
a5ed1ffa
JD
215 if (!sscanf(line, "%d", &ncpus)) {
216 printf("Couldn't parse [%s]\n", line);
217 return -1;
218 }
1da177e4 219
a5ed1ffa 220 return 0;
1da177e4
LT
221}
222
223__uml_setup("ncpus=", uml_ncpus_setup,
224"ncpus=<# of desired CPUs>\n"
225" This tells an SMP kernel how many virtual processors to start.\n\n"
226);
227#endif
228
229static int force_tt = 0;
230
231#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
232#define DEFAULT_TT 0
233
234static int __init mode_tt_setup(char *line, int *add)
235{
236 force_tt = 1;
a5ed1ffa 237 return 0;
1da177e4
LT
238}
239
240#else
241#ifdef CONFIG_MODE_SKAS
242
243#define DEFAULT_TT 0
244
245static int __init mode_tt_setup(char *line, int *add)
246{
247 printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
a5ed1ffa 248 return 0;
1da177e4
LT
249}
250
251#else
252#ifdef CONFIG_MODE_TT
253
254#define DEFAULT_TT 1
255
256static int __init mode_tt_setup(char *line, int *add)
257{
258 printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
a5ed1ffa 259 return 0;
1da177e4
LT
260}
261
1da177e4
LT
262#endif
263#endif
264#endif
265
266__uml_setup("mode=tt", mode_tt_setup,
267"mode=tt\n"
268" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
269" forces UML to run in tt (tracing thread) mode. It is not the default\n"
270" because it's slower and less secure than skas mode.\n\n"
271);
272
273int mode_tt = DEFAULT_TT;
274
275static int __init Usage(char *line, int *add)
276{
a5ed1ffa 277 const char **p;
1da177e4 278
96b644bd 279 printf(usage_string, init_utsname()->release);
a5ed1ffa
JD
280 p = &__uml_help_start;
281 while (p < &__uml_help_end) {
282 printf("%s", *p);
283 p++;
284 }
1da177e4 285 exit(0);
1da177e4
LT
286 return 0;
287}
288
289__uml_setup("--help", Usage,
290"--help\n"
291" Prints this message.\n\n"
292);
293
294static int __init uml_checksetup(char *line, int *add)
295{
296 struct uml_param *p;
297
298 p = &__uml_setup_start;
299 while(p < &__uml_setup_end) {
300 int n;
301
302 n = strlen(p->str);
303 if(!strncmp(line, p->str, n)){
304 if (p->setup_func(line + n, add)) return 1;
305 }
306 p++;
307 }
308 return 0;
309}
310
311static void __init uml_postsetup(void)
312{
313 initcall_t *p;
314
315 p = &__uml_postsetup_start;
316 while(p < &__uml_postsetup_end){
317 (*p)();
318 p++;
319 }
320 return;
321}
322
323/* Set during early boot */
324unsigned long brk_start;
325unsigned long end_iomem;
326EXPORT_SYMBOL(end_iomem);
327
328#define MIN_VMALLOC (32 * 1024 * 1024)
329
23bbd586
JD
330extern char __binary_start;
331
7a3a06d0 332int __init linux_main(int argc, char **argv)
1da177e4
LT
333{
334 unsigned long avail, diff;
335 unsigned long virtmem_size, max_physmem;
336 unsigned int i, add;
cb66504d 337 char * mode;
1da177e4
LT
338
339 for (i = 1; i < argc; i++){
340 if((i == 1) && (argv[i][0] == ' ')) continue;
341 add = 1;
342 uml_checksetup(argv[i], &add);
343 if (add)
344 add_arg(argv[i]);
345 }
346 if(have_root == 0)
347 add_arg(DEFAULT_COMMAND_LINE);
348
60d339f6 349 os_early_checks();
8923648c
PBG
350 if (force_tt)
351 clear_can_do_skas();
1da177e4
LT
352 mode_tt = force_tt ? 1 : !can_do_skas();
353#ifndef CONFIG_MODE_TT
354 if (mode_tt) {
355 /*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So,
356 * can_do_skas() returned 0, and the message is correct. */
357 printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n");
358 exit(1);
359 }
360#endif
cb66504d
PBG
361
362#ifndef CONFIG_MODE_SKAS
363 mode = "TT";
364#else
365 /* Show to the user the result of selection */
366 if (mode_tt)
367 mode = "TT";
368 else if (proc_mm && ptrace_faultinfo)
369 mode = "SKAS3";
370 else
371 mode = "SKAS0";
372#endif
373
374 printf("UML running in %s mode\n", mode);
375
23bbd586
JD
376 uml_start = (unsigned long) &__binary_start;
377 host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt,
378 set_task_sizes_skas, &task_size);
1da177e4 379
ea2ba7dc 380 /*
a5ed1ffa
JD
381 * Setting up handlers to 'sig_info' struct
382 */
ea2ba7dc
GS
383 os_fill_handlinfo(handlinfo_kern);
384
1da177e4
LT
385 brk_start = (unsigned long) sbrk(0);
386 CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
387 /* Increase physical memory size for exec-shield users
388 so they actually get what they asked for. This should
389 add zero for non-exec shield users */
390
391 diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
392 if(diff > 1024 * 1024){
393 printf("Adding %ld bytes to physical memory to account for "
394 "exec-shield gap\n", diff);
395 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
396 }
397
23bbd586 398 uml_physmem = uml_start & PAGE_MASK;
1da177e4
LT
399
400 /* Reserve up to 4M after the current brk */
401 uml_reserved = ROUND_4M(brk_start) + (1 << 22);
402
96b644bd 403 setup_machinename(init_utsname()->machine);
1da177e4 404
02215759 405#ifdef CONFIG_CMDLINE_ON_HOST
1da177e4
LT
406 argv1_begin = argv[1];
407 argv1_end = &argv[1][strlen(argv[1])];
408#endif
a5ed1ffa 409
1da177e4
LT
410 highmem = 0;
411 iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
412 max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
413
414 /* Zones have to begin on a 1 << MAX_ORDER page boundary,
415 * so this makes sure that's true for highmem
416 */
417 max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
418 if(physmem_size + iomem_size > max_physmem){
419 highmem = physmem_size + iomem_size - max_physmem;
420 physmem_size -= highmem;
421#ifndef CONFIG_HIGHMEM
422 highmem = 0;
423 printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
d9f8b62a 424 "to %Lu bytes\n", physmem_size);
1da177e4
LT
425#endif
426 }
427
428 high_physmem = uml_physmem + physmem_size;
429 end_iomem = high_physmem + iomem_size;
430 high_memory = (void *) end_iomem;
431
432 start_vm = VMALLOC_START;
433
434 setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
435 if(init_maps(physmem_size, iomem_size, highmem)){
d9f8b62a
JD
436 printf("Failed to allocate mem_map for %Lu bytes of physical "
437 "memory and %Lu bytes of highmem\n", physmem_size,
1da177e4
LT
438 highmem);
439 exit(1);
440 }
441
442 virtmem_size = physmem_size;
443 avail = get_kmem_end() - start_vm;
444 if(physmem_size > avail) virtmem_size = avail;
445 end_vm = start_vm + virtmem_size;
446
447 if(virtmem_size < physmem_size)
ae173816 448 printf("Kernel virtual memory size shrunk to %lu bytes\n",
1da177e4
LT
449 virtmem_size);
450
a5ed1ffa 451 uml_postsetup();
1da177e4
LT
452
453 task_protections((unsigned long) &init_thread_info);
454 os_flush_stdout();
455
a5ed1ffa 456 return CHOOSE_MODE(start_uml_tt(), start_uml_skas());
1da177e4
LT
457}
458
459extern int uml_exitcode;
460
461static int panic_exit(struct notifier_block *self, unsigned long unused1,
462 void *unused2)
463{
464 bust_spinlocks(1);
465 show_regs(&(current->thread.regs));
466 bust_spinlocks(0);
467 uml_exitcode = 1;
468 machine_halt();
a5ed1ffa 469 return 0;
1da177e4
LT
470}
471
472static struct notifier_block panic_exit_notifier = {
473 .notifier_call = panic_exit,
474 .next = NULL,
475 .priority = 0
476};
477
478void __init setup_arch(char **cmdline_p)
479{
e041c683
AS
480 atomic_notifier_chain_register(&panic_notifier_list,
481 &panic_exit_notifier);
1da177e4 482 paging_init();
19bf7e7a 483 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
a5ed1ffa 484 *cmdline_p = command_line;
1da177e4
LT
485 setup_hostinfo();
486}
487
488void __init check_bugs(void)
489{
490 arch_check_bugs();
a5ed1ffa 491 os_check_bugs();
1da177e4
LT
492}
493
9a0b5817
GH
494void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
495{
496}
497
c61a8416 498#ifdef CONFIG_SMP
9a0b5817
GH
499void alternatives_smp_module_add(struct module *mod, char *name,
500 void *locks, void *locks_end,
501 void *text, void *text_end)
502{
503}
504
505void alternatives_smp_module_del(struct module *mod)
1da177e4
LT
506{
507}
c61a8416 508#endif
This page took 0.344598 seconds and 5 git commands to generate.