X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fkernel%2Fum_arch.c;h=66f43c906821b46de035417fdb1ca042b47eecad;hb=refs%2Fheads%2Fvserver;hp=e8f0cacc1f4162b243c956b30664330c02450576;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index e8f0cacc1..66f43c906 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -1,9 +1,8 @@ -/* +/* * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ -#include "linux/config.h" #include "linux/kernel.h" #include "linux/sched.h" #include "linux/notifier.h" @@ -17,17 +16,18 @@ #include "linux/sysrq.h" #include "linux/seq_file.h" #include "linux/delay.h" +#include "linux/module.h" #include "asm/page.h" #include "asm/pgtable.h" #include "asm/ptrace.h" #include "asm/elf.h" #include "asm/user.h" +#include "asm/setup.h" #include "ubd_user.h" #include "asm/current.h" #include "user_util.h" #include "kern_util.h" #include "kern.h" -#include "mprot.h" #include "mem_user.h" #include "mem.h" #include "umid.h" @@ -37,8 +37,25 @@ #include "choose-mode.h" #include "mode_kern.h" #include "mode.h" +#ifdef UML_CONFIG_MODE_SKAS +#include "skas.h" +#endif + +#define DEFAULT_COMMAND_LINE "root=98:0" -#define DEFAULT_COMMAND_LINE "root=6200" +/* Changed in linux_main and setup_arch, which run before SMP is started */ +static char command_line[COMMAND_LINE_SIZE] = { 0 }; + +static void add_arg(char *arg) +{ + if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { + printf("add_arg: Too many command line arguments!\n"); + exit(1); + } + if(strlen(command_line) > 0) + strcat(command_line, " "); + strcat(command_line, arg); +} struct cpuinfo_um boot_cpu_data = { .loops_per_jiffy = 0, @@ -53,18 +70,22 @@ unsigned long thread_saved_pc(struct task_struct *task) static int show_cpuinfo(struct seq_file *m, void *v) { - int index; + int index = 0; - index = (struct cpuinfo_um *)v - cpu_data; #ifdef CONFIG_SMP + index = (struct cpuinfo_um *) v - cpu_data; if (!cpu_online(index)) return 0; #endif - seq_printf(m, "bogomips\t: %lu.%02lu\n", + seq_printf(m, "processor\t: %d\n", index); + seq_printf(m, "vendor_id\t: User Mode Linux\n"); + seq_printf(m, "model name\t: UML\n"); + seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas")); + seq_printf(m, "host\t\t: %s\n", host_info); + seq_printf(m, "bogomips\t: %lu.%02lu\n\n", loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100); - seq_printf(m, "host\t\t: %s\n", host_info); return(0); } @@ -84,19 +105,13 @@ static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, .show = show_cpuinfo, }; -pte_t * __bad_pagetable(void) -{ - panic("Someone should implement __bad_pagetable"); - return(NULL); -} - /* Set in linux_main */ unsigned long host_task_size; unsigned long task_size; @@ -110,7 +125,7 @@ unsigned long start_vm; unsigned long end_vm; int ncpus = 1; -#ifdef CONFIG_MODE_TT +#ifdef CONFIG_CMDLINE_ON_HOST /* Pointer set in linux_main, the array itself is private to each thread, * and changed at address space creation time so this poses no concurrency * problems. @@ -121,25 +136,25 @@ static char *argv1_end = NULL; /* Set in early boot */ static int have_root __initdata = 0; -long physmem_size = 32 * 1024 * 1024; +long long physmem_size = 32 * 1024 * 1024; void set_cmdline(char *cmd) { -#ifdef CONFIG_MODE_TT +#ifdef CONFIG_CMDLINE_ON_HOST char *umid, *ptr; if(CHOOSE_MODE(honeypot, 0)) return; - umid = get_umid(1); - if(umid != NULL){ + umid = get_umid(); + if(*umid != '\0'){ snprintf(argv1_begin, (argv1_end - argv1_begin) * sizeof(*ptr), - "(%s)", umid); + "(%s) ", umid); ptr = &argv1_begin[strlen(argv1_begin)]; } else ptr = argv1_begin; - snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd); + snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd); memset(argv1_begin + strlen(argv1_begin), '\0', argv1_end - argv1_begin - strlen(argv1_begin)); #endif @@ -151,8 +166,10 @@ static char *usage_string = static int __init uml_version_setup(char *line, int *add) { - printf("%s\n", system_utsname.release); + printf("%s\n", init_utsname()->release); exit(0); + + return 0; } __uml_setup("--version", uml_version_setup, @@ -175,11 +192,29 @@ __uml_setup("root=", uml_root_setup, " root=/dev/ubd5\n\n" ); +#ifndef CONFIG_MODE_TT + +static int __init no_skas_debug_setup(char *line, int *add) +{ + printf("'debug' is not necessary to gdb UML in skas mode - run \n"); + printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n"); + printf("doesn't work as expected\n"); + + return 0; +} + +__uml_setup("debug", no_skas_debug_setup, +"debug\n" +" this flag is not needed to run gdb on UML in skas mode\n\n" +); + +#endif + #ifdef CONFIG_SMP static int __init uml_ncpus_setup(char *line, int *add) { if (!sscanf(line, "%d", &ncpus)) { - printk("Couldn't parse [%s]\n", line); + printf("Couldn't parse [%s]\n", line); return -1; } @@ -192,7 +227,7 @@ __uml_setup("ncpus=", uml_ncpus_setup, ); #endif -int force_tt = 0; +static int force_tt = 0; #if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS) #define DEFAULT_TT 0 @@ -210,7 +245,7 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { - printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); return(0); } @@ -221,14 +256,10 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { - printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); return(0); } -#else - -#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled - #endif #endif #endif @@ -246,13 +277,15 @@ static int __init Usage(char *line, int *add) { const char **p; - printf(usage_string, system_utsname.release); + printf(usage_string, init_utsname()->release); p = &__uml_help_start; while (p < &__uml_help_end) { printf("%s", *p); p++; } exit(0); + + return 0; } __uml_setup("--help", Usage, @@ -291,94 +324,149 @@ static void __init uml_postsetup(void) /* Set during early boot */ unsigned long brk_start; -static struct vm_reserved kernel_vm_reserved; +unsigned long end_iomem; +EXPORT_SYMBOL(end_iomem); #define MIN_VMALLOC (32 * 1024 * 1024) +extern char __binary_start; + int linux_main(int argc, char **argv) { - unsigned long avail; + unsigned long avail, diff; unsigned long virtmem_size, max_physmem; - unsigned int i, add, err; + unsigned int i, add; + char * mode; for (i = 1; i < argc; i++){ if((i == 1) && (argv[i][0] == ' ')) continue; add = 1; uml_checksetup(argv[i], &add); - if(add) add_arg(saved_command_line, argv[i]); + if (add) + add_arg(argv[i]); } - if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE); + if(have_root == 0) + add_arg(DEFAULT_COMMAND_LINE); + os_early_checks(); + if (force_tt) + clear_can_do_skas(); mode_tt = force_tt ? 1 : !can_do_skas(); - uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, - &host_task_size, &task_size); +#ifndef CONFIG_MODE_TT + if (mode_tt) { + /*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So, + * can_do_skas() returned 0, and the message is correct. */ + printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n"); + exit(1); + } +#endif + +#ifndef CONFIG_MODE_SKAS + mode = "TT"; +#else + /* Show to the user the result of selection */ + if (mode_tt) + mode = "TT"; + else if (proc_mm && ptrace_faultinfo) + mode = "SKAS3"; + else + mode = "SKAS0"; +#endif + + printf("UML running in %s mode\n", mode); + + uml_start = (unsigned long) &__binary_start; + host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, + set_task_sizes_skas, &task_size); + + /* + * Setting up handlers to 'sig_info' struct + */ + os_fill_handlinfo(handlinfo_kern); brk_start = (unsigned long) sbrk(0); CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); + /* Increase physical memory size for exec-shield users + so they actually get what they asked for. This should + add zero for non-exec shield users */ + + diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); + if(diff > 1024 * 1024){ + printf("Adding %ld bytes to physical memory to account for " + "exec-shield gap\n", diff); + physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); + } - uml_physmem = uml_start; + uml_physmem = uml_start & PAGE_MASK; /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); - setup_machinename(system_utsname.machine); + setup_machinename(init_utsname()->machine); -#ifdef CONFIG_MODE_TT +#ifdef CONFIG_CMDLINE_ON_HOST argv1_begin = argv[1]; argv1_end = &argv[1][strlen(argv[1])]; #endif - set_usable_vm(uml_physmem, get_kmem_end()); - highmem = 0; - max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC; - if(physmem_size > max_physmem){ - highmem = physmem_size - max_physmem; + iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; + max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; + + /* Zones have to begin on a 1 << MAX_ORDER page boundary, + * so this makes sure that's true for highmem + */ + max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); + if(physmem_size + iomem_size > max_physmem){ + highmem = physmem_size + iomem_size - max_physmem; physmem_size -= highmem; #ifndef CONFIG_HIGHMEM highmem = 0; printf("CONFIG_HIGHMEM not enabled - physical memory shrunk " - "to %ld bytes\n", physmem_size); + "to %Lu bytes\n", physmem_size); #endif } high_physmem = uml_physmem + physmem_size; - high_memory = (void *) high_physmem; + end_iomem = high_physmem + iomem_size; + high_memory = (void *) end_iomem; start_vm = VMALLOC_START; - setup_physmem(uml_physmem, uml_reserved, physmem_size); + setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); + if(init_maps(physmem_size, iomem_size, highmem)){ + printf("Failed to allocate mem_map for %Lu bytes of physical " + "memory and %Lu bytes of highmem\n", physmem_size, + highmem); + exit(1); + } + virtmem_size = physmem_size; avail = get_kmem_end() - start_vm; if(physmem_size > avail) virtmem_size = avail; end_vm = start_vm + virtmem_size; if(virtmem_size < physmem_size) - printf("Kernel virtual memory size shrunk to %ld bytes\n", + printf("Kernel virtual memory size shrunk to %lu bytes\n", virtmem_size); - err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved); - if(err){ - printf("Failed to reserve VM area for kernel VM\n"); - exit(1); - } - uml_postsetup(); - init_task.thread.kernel_stack = (unsigned long) &init_thread_info + - 2 * PAGE_SIZE; - task_protections((unsigned long) &init_thread_info); + os_flush_stdout(); return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); } +extern int uml_exitcode; + static int panic_exit(struct notifier_block *self, unsigned long unused1, void *unused2) { -#ifdef CONFIG_MAGIC_SYSRQ - handle_sysrq('p', ¤t->thread.regs, NULL, NULL); -#endif + bust_spinlocks(1); + show_regs(&(current->thread.regs)); + bust_spinlocks(0); + uml_exitcode = 1; machine_halt(); return(0); } @@ -391,9 +479,10 @@ static struct notifier_block panic_exit_notifier = { void __init setup_arch(char **cmdline_p) { - notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); + atomic_notifier_chain_register(&panic_notifier_list, + &panic_exit_notifier); paging_init(); - strcpy(command_line, saved_command_line); + strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; setup_hostinfo(); } @@ -401,17 +490,21 @@ void __init setup_arch(char **cmdline_p) void __init check_bugs(void) { arch_check_bugs(); - check_ptrace(); - check_sigio(); + os_check_bugs(); } -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ +void apply_alternatives(struct alt_instr *start, struct alt_instr *end) +{ +} + +#ifdef CONFIG_SMP +void alternatives_smp_module_add(struct module *mod, char *name, + void *locks, void *locks_end, + void *text, void *text_end) +{ +} + +void alternatives_smp_module_del(struct module *mod) +{ +} +#endif