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