From 0949be35095b53dbaa72db700cb5074c5c249629 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Wed, 2 May 2007 19:27:05 +0200 Subject: [PATCH] i386: Add an option for the VIA C7 which sets appropriate L1 cache The VIA C7 is a 686 (with TSC) that supports MMX, SSE and SSE2, it also has a cache line length of 64 according to http://www.digit-life.com/articles2/cpu/rmma-via-c7.html. This patch sets gcc to -march=686 and select s the correct cache shift. Signed-off-by: Simon Arlott Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Dave Jones Cc: Alan Cox Signed-off-by: Andrew Morton --- arch/um/defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/um') diff --git a/arch/um/defconfig b/arch/um/defconfig index 780cc0a4a12..f938fa82214 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -41,6 +41,7 @@ CONFIG_M686=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set # CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y -- cgit v1.2.3 From 11100b1dfb6e9444d54d38e822753f59ee42a7e6 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:50:57 -0700 Subject: uml: delete unused code Get rid of a bunch of unused stuff - cpu_feature had no users linux_prog is little-used, so its declaration is moved to the user for easy deletion when the whole file goes away a long-unused debugging aid in helper.c is gone Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/kern_util.h | 1 - arch/um/include/user_util.h | 1 - arch/um/kernel/tt/gdb.c | 2 ++ arch/um/os-Linux/helper.c | 11 ----------- arch/um/os-Linux/main.c | 8 +------- arch/um/sys-i386/bugs.c | 23 ----------------------- arch/um/sys-x86_64/bugs.c | 23 ----------------------- 7 files changed, 3 insertions(+), 66 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 173af029d12..be850b9ec94 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -23,7 +23,6 @@ struct kern_handlers { extern const struct kern_handlers handlinfo_kern; extern int ncpus; -extern char *linux_prog; extern char *gdb_init; extern int kmalloc_ok; extern int jail; diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 023575f6734..99492d5c82d 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -60,7 +60,6 @@ extern void kill_child_dead(int pid); extern int cont(int pid); extern void check_sigio(void); extern void arch_check_bugs(void); -extern int cpu_feature(char *what, char *buf, int len); extern int arch_handle_signal(int sig, union uml_pt_regs *regs); extern int arch_fixup(unsigned long address, void *sc_ptr); extern void arch_init_thread(void); diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c index 8eba8f7dca6..d284f69f04e 100644 --- a/arch/um/kernel/tt/gdb.c +++ b/arch/um/kernel/tt/gdb.c @@ -115,6 +115,8 @@ struct gdb_data { int err; }; +extern char *linux_prog; + static void config_gdb_cb(void *arg) { struct gdb_data *data = arg; diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index c7ad6306e22..a375cc138c2 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -25,23 +25,12 @@ struct helper_data { char *buf; }; -/* Debugging aid, changed only from gdb */ -int helper_pause = 0; - -static void helper_hup(int sig) -{ -} - static int helper_child(void *arg) { struct helper_data *data = arg; char **argv = data->argv; int errval; - if (helper_pause){ - signal(SIGHUP, helper_hup); - pause(); - } if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); errval = execvp_noalloc(data->buf, argv[0], argv); diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 685feaab65d..7aa4c2a7a59 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -25,12 +25,7 @@ #include "os.h" #include "um_malloc.h" -/* Set in set_stklim, which is called from main and __wrap_malloc. - * __wrap_malloc only calls it if main hasn't started. - */ -unsigned long stacksizelim; - -/* Set in main */ +/* Set in main, unchanged thereafter */ char *linux_prog; #define PGD_BOUND (4 * 1024 * 1024) @@ -52,7 +47,6 @@ static void set_stklim(void) exit(1); } } - stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1); } static __init void do_uml_initcalls(void) diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index f1bcd399ac9..e524a087679 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -79,29 +79,6 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return(0); } -int cpu_feature(char *what, char *buf, int len) -{ - int fd, ret = 0; - - fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); - return(0); - } - - if(!find_cpuinfo_line(fd, what, buf, len)){ - printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); - goto out_close; - } - - token(fd, buf, len, '\n'); - ret = 1; - - out_close: - os_close_file(fd); - return(ret); -} - static int check_cpu_flag(char *feature, int *have_it) { char buf[MAXTOKEN], c; diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c index fdce7ea98ca..73ca62312fd 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/um/sys-x86_64/bugs.c @@ -88,29 +88,6 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return(0); } -int cpu_feature(char *what, char *buf, int len) -{ - int fd, ret = 0; - - fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); - return(0); - } - - if(!find_cpuinfo_line(fd, what, buf, len)){ - printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); - goto out_close; - } - - token(fd, buf, len, '\n'); - ret = 1; - - out_close: - os_close_file(fd); - return(ret); -} - /* 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 -- cgit v1.2.3 From a5ed1ffa6c2480cdcf3f0aa945f0b8622fe4e90b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:50:58 -0700 Subject: uml: formatting fixes Formatting fixes - style violations whitespace breakage emacs formatting comment removal Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/um_arch.c | 51 ++++++++++++++++++++++---------------------- arch/um/os-Linux/main.c | 11 +++++----- arch/um/sys-i386/bugs.c | 54 +++++++++++++++++++++-------------------------- arch/um/sys-x86_64/bugs.c | 34 +++++++++++------------------ 4 files changed, 67 insertions(+), 83 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 89c6dba731f..299d75a41a7 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -63,8 +63,8 @@ struct cpuinfo_um boot_cpu_data = { unsigned long thread_saved_pc(struct task_struct *task) { - return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, - task))); + return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, + task)); } static int show_cpuinfo(struct seq_file *m, void *v) @@ -86,7 +86,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100); - return(0); + return 0; } static void *c_start(struct seq_file *m, loff_t *pos) @@ -212,12 +212,12 @@ __uml_setup("debug", no_skas_debug_setup, #ifdef CONFIG_SMP static int __init uml_ncpus_setup(char *line, int *add) { - if (!sscanf(line, "%d", &ncpus)) { - printf("Couldn't parse [%s]\n", line); - return -1; - } + if (!sscanf(line, "%d", &ncpus)) { + printf("Couldn't parse [%s]\n", line); + return -1; + } - return 0; + return 0; } __uml_setup("ncpus=", uml_ncpus_setup, @@ -234,7 +234,7 @@ static int force_tt = 0; static int __init mode_tt_setup(char *line, int *add) { force_tt = 1; - return(0); + return 0; } #else @@ -245,7 +245,7 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); - return(0); + return 0; } #else @@ -256,7 +256,7 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); - return(0); + return 0; } #endif @@ -274,16 +274,15 @@ int mode_tt = DEFAULT_TT; static int __init Usage(char *line, int *add) { - const char **p; + const char **p; printf(usage_string, init_utsname()->release); - p = &__uml_help_start; - while (p < &__uml_help_end) { - printf("%s", *p); - p++; - } + p = &__uml_help_start; + while (p < &__uml_help_end) { + printf("%s", *p); + p++; + } exit(0); - return 0; } @@ -379,8 +378,8 @@ int __init linux_main(int argc, char **argv) set_task_sizes_skas, &task_size); /* - * Setting up handlers to 'sig_info' struct - */ + * Setting up handlers to 'sig_info' struct + */ os_fill_handlinfo(handlinfo_kern); brk_start = (unsigned long) sbrk(0); @@ -407,7 +406,7 @@ int __init linux_main(int argc, char **argv) argv1_begin = argv[1]; argv1_end = &argv[1][strlen(argv[1])]; #endif - + highmem = 0; iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; @@ -449,12 +448,12 @@ int __init linux_main(int argc, char **argv) printf("Kernel virtual memory size shrunk to %lu bytes\n", virtmem_size); - uml_postsetup(); + uml_postsetup(); task_protections((unsigned long) &init_thread_info); os_flush_stdout(); - return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); + return CHOOSE_MODE(start_uml_tt(), start_uml_skas()); } extern int uml_exitcode; @@ -467,7 +466,7 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1, bust_spinlocks(0); uml_exitcode = 1; machine_halt(); - return(0); + return 0; } static struct notifier_block panic_exit_notifier = { @@ -482,14 +481,14 @@ void __init setup_arch(char **cmdline_p) &panic_exit_notifier); paging_init(); strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; + *cmdline_p = command_line; setup_hostinfo(); } void __init check_bugs(void) { arch_check_bugs(); - os_check_bugs(); + os_check_bugs(); } void apply_alternatives(struct alt_instr *start, struct alt_instr *end) diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 7aa4c2a7a59..2c089c2c63b 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -218,7 +218,7 @@ int main(int argc, char **argv, char **envp) ret = 1; } printf("\n"); - return(uml_exitcode); + return uml_exitcode; } #define CAN_KMALLOC() \ @@ -231,7 +231,7 @@ void *__wrap_malloc(int size) void *ret; if(!CAN_KMALLOC()) - return(__real_malloc(size)); + return __real_malloc(size); else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/ ret = um_kmalloc(size); else ret = um_vmalloc(size); @@ -242,16 +242,17 @@ void *__wrap_malloc(int size) if(ret == NULL) errno = ENOMEM; - return(ret); + return ret; } void *__wrap_calloc(int n, int size) { void *ptr = __wrap_malloc(n * size); - if(ptr == NULL) return(NULL); + if(ptr == NULL) + return NULL; memset(ptr, 0, n * size); - return(ptr); + return ptr; } extern void __real_free(void *); diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index e524a087679..cae0af14903 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -32,21 +32,21 @@ static char token(int fd, char *buf, int len, char stop) n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ - if(n == 0) return(0); + if(n == 0) + return 0; printk("Reading /proc/cpuinfo failed, err = %d\n", -n); if(n < 0) - return(n); - else - return(-EIO); + return n; + else return -EIO; } } while((c != '\n') && (c != stop) && (ptr < end)); if(ptr == end){ printk("Failed to find '%c' in /proc/cpuinfo\n", stop); - return(-1); + return -1; } *(ptr - 1) = '\0'; - return(c); + return c; } static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) @@ -58,25 +58,25 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) while(1){ c = token(fd, scratch, len - 1, ':'); if(c <= 0) - return(0); + return 0; else if(c != ':'){ printk("Failed to find ':' in /proc/cpuinfo\n"); - return(0); + return 0; } if(!strncmp(scratch, key, strlen(key))) - return(1); + return 1; do { n = os_read_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); - return(0); + return 0; } } while(c != '\n'); } - return(0); + return 0; } static int check_cpu_flag(char *feature, int *have_it) @@ -96,7 +96,8 @@ static int check_cpu_flag(char *feature, int *have_it) goto out; c = token(fd, buf, len - 1, ' '); - if(c < 0) goto out; + if(c < 0) + goto out; else if(c != ' '){ printk("Failed to find ' ' in /proc/cpuinfo\n"); goto out; @@ -104,7 +105,8 @@ static int check_cpu_flag(char *feature, int *have_it) while(1){ c = token(fd, buf, len - 1, ' '); - if(c < 0) goto out; + if(c < 0) + goto out; else if(c == '\n') break; if(!strcmp(buf, feature)){ @@ -113,8 +115,10 @@ static int check_cpu_flag(char *feature, int *have_it) } } out: - if(*have_it == 0) printk("No\n"); - else if(*have_it == 1) printk("Yes\n"); + if(*have_it == 0) + printk("No\n"); + else if(*have_it == 1) + printk("Yes\n"); os_close_file(fd); return 1; } @@ -166,12 +170,13 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) /* This is testing for a cmov (0x0f 0x4x) instruction causing a * SIGILL in init. */ - if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0); + if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) + return 0; if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) panic("SIGILL in init, could not read instructions!\n"); if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) - return(0); + return 0; if(host_has_cmov == 0) panic("SIGILL caused by cmov, which this processor doesn't " @@ -185,16 +190,5 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) "implements it, boot a filesystem compiled for older " "processors"); else panic("Bad value for host_has_cmov (%d)", host_has_cmov); - return(0); + return 0; } - -/* - * 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: - */ diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c index 73ca62312fd..9fa5392e312 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/um/sys-x86_64/bugs.c @@ -21,7 +21,7 @@ void arch_check_bugs(void) int arch_handle_signal(int sig, union uml_pt_regs *regs) { - return(0); + return 0; } #define MAXTOKEN 64 @@ -41,21 +41,21 @@ static char token(int fd, char *buf, int len, char stop) n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ - if(n == 0) return(0); + if(n == 0) + return 0; printk("Reading /proc/cpuinfo failed, err = %d\n", -n); if(n < 0) - return(n); - else - return(-EIO); + return n; + else return -EIO; } } while((c != '\n') && (c != stop) && (ptr < end)); if(ptr == end){ printk("Failed to find '%c' in /proc/cpuinfo\n", stop); - return(-1); + return -1; } *(ptr - 1) = '\0'; - return(c); + return c; } static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) @@ -67,33 +67,23 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) while(1){ c = token(fd, scratch, len - 1, ':'); if(c <= 0) - return(0); + return 0; else if(c != ':'){ printk("Failed to find ':' in /proc/cpuinfo\n"); - return(0); + return 0; } if(!strncmp(scratch, key, strlen(key))) - return(1); + return 1; do { n = os_read_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); - return(0); + return 0; } } while(c != '\n'); } - return(0); + return 0; } - -/* 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: - */ -- cgit v1.2.3 From b4ffb6ad8d8477b561377ca150bbbfc0db02da54 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:50:59 -0700 Subject: uml: host_info tidying Move the host_info string from util.c to um_arch.c, where it is actually initialized and used. Also document its lack of locking. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 2 +- arch/um/include/user_util.h | 2 -- arch/um/kernel/um_arch.c | 6 +++++- arch/um/os-Linux/util.c | 8 +++----- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 5c74da41045..22666b4a8be 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -273,7 +273,7 @@ extern void stack_protections(unsigned long address); extern void task_protections(unsigned long address); extern int raw(int fd); extern void setup_machinename(char *machine_out); -extern void setup_hostinfo(void); +extern void setup_hostinfo(char *buf, int len); extern int setjmp_wrapper(void (*proc)(void *, void *), ...); /* time.c */ diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 99492d5c82d..73ffea1829f 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -36,8 +36,6 @@ extern unsigned long end_vm; extern unsigned long start_vm; extern unsigned long long highmem; -extern char host_info[]; - extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; extern unsigned long _unprotected_end; extern unsigned long brk_start; diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 299d75a41a7..613fb082bbd 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -17,6 +17,7 @@ #include "linux/seq_file.h" #include "linux/delay.h" #include "linux/module.h" +#include "linux/utsname.h" #include "asm/page.h" #include "asm/pgtable.h" #include "asm/ptrace.h" @@ -67,6 +68,9 @@ unsigned long thread_saved_pc(struct task_struct *task) task)); } +/* Changed in setup_arch, which is called in early boot */ +static char host_info[(__NEW_UTS_LEN + 1) * 5]; + static int show_cpuinfo(struct seq_file *m, void *v) { int index = 0; @@ -482,7 +486,7 @@ void __init setup_arch(char **cmdline_p) paging_init(); strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; - setup_hostinfo(); + setup_hostinfo(host_info, sizeof host_info); } void __init check_bugs(void) diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 56b8a50e8bc..125854a2aa2 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -96,15 +96,13 @@ void setup_machinename(char *machine_out) strcpy(machine_out, host.machine); } -char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1]; - -void setup_hostinfo(void) +void setup_hostinfo(char *buf, int len) { struct utsname host; uname(&host); - sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename, - host.release, host.version, host.machine); + snprintf(buf, len, "%s %s %s %s %s", host.sysname, host.nodename, + host.release, host.version, host.machine); } int setjmp_wrapper(void (*proc)(void *, void *), ...) -- cgit v1.2.3 From 48b201846901c1780fbc7ea779dcc8aa8ab8e16b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:00 -0700 Subject: uml: mark tt-mode code for future removal Mark some tt-mode-only code as such. Also cleaned up some formatting. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/ptrace_user.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 01212c88fcc..95dd309ff69 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -45,7 +45,8 @@ int ptrace_setfpregs(long pid, unsigned long *regs) return 0; } -/* All the below stuff is of interest for TT mode only */ +#ifdef UML_CONFIG_MODE_TT + static void write_debugregs(int pid, unsigned long *regs) { struct user *dummy; @@ -128,13 +129,4 @@ void update_debugregs(int seq) } #endif -/* - * 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: - */ +#endif -- cgit v1.2.3 From 1d94cda04eb82feb87c932ac3d4aef1e9dc78a43 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:00 -0700 Subject: uml: print coredump limits Print out core dump limits at boot time. This is to allow core dumps to be collected if something goes very wrong and to tell if a core dump isn't going to happen because of a resource limit. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/start_up.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'arch/um') diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 5178eba9afa..1244179e6c8 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -329,8 +330,32 @@ static void __init check_ptrace(void) extern void check_tmpexec(void); +static void check_coredump_limit(void) +{ + struct rlimit lim; + int err = getrlimit(RLIMIT_CORE, &lim); + + if(err){ + perror("Getting core dump limit"); + return; + } + + printf("Core dump limits :\n\tsoft - "); + if(lim.rlim_cur == RLIM_INFINITY) + printf("NONE\n"); + else printf("%lu\n", lim.rlim_cur); + + printf("\thard - "); + if(lim.rlim_max == RLIM_INFINITY) + printf("NONE\n"); + else printf("%lu\n", lim.rlim_max); +} + void os_early_checks(void) { + /* Print out the core dump limits early */ + check_coredump_limit(); + check_ptrace(); /* Need to check this early because mmapping happens before the -- cgit v1.2.3 From b47d2debf229469c78af4145ee7ad35a0f21b67f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:01 -0700 Subject: uml: handle block device hotplug errors If a disk fails to open, i.e. its host file doesn't exist, it won't be removable because the hot-unplug code checks the existence of its gendisk. This won't exist because it is only allocated for successfully opened disks. Thus, a typo on the command line can result in a unusable and unfixable disk. This is fixed by freeing the gendisk if it's there, but not letting that affect the removal. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 8bd9204ac1a..53c36d1770c 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -788,14 +788,12 @@ static int ubd_id(char **str, int *start_out, int *end_out) static int ubd_remove(int n, char **error_out) { + struct gendisk *disk; struct ubd *ubd_dev; int err = -ENODEV; mutex_lock(&ubd_lock); - if(ubd_gendisk[n] == NULL) - goto out; - ubd_dev = &ubd_devs[n]; if(ubd_dev->file == NULL) @@ -806,9 +804,12 @@ static int ubd_remove(int n, char **error_out) if(ubd_dev->count > 0) goto out; - del_gendisk(ubd_gendisk[n]); - put_disk(ubd_gendisk[n]); - ubd_gendisk[n] = NULL; + disk = ubd_gendisk[n]; + ubd_gendisk[n] = NULL; + if(disk != NULL){ + del_gendisk(disk); + put_disk(disk); + } if(fake_gendisk[n] != NULL){ del_gendisk(fake_gendisk[n]); -- cgit v1.2.3 From 56bd194bb200ef0c49517de67a7d7f4b043b11b1 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:02 -0700 Subject: uml: driver formatting fixes Fix a bunch of formatting violations in the drivers: return(n) -> return n whitespace fixes emacs formatting comment removal breaking if(foo) return(n) into two lines There are also a couple of errno use bugs: using errno in a printk when the failure put errno into a local variable saving errno after a printk, which can change it Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 2 +- arch/um/drivers/daemon_user.c | 25 ++++++-------------- arch/um/drivers/mcast_user.c | 12 +++++----- arch/um/drivers/pcap_user.c | 33 +++++++++----------------- arch/um/drivers/ubd_user.c | 15 ++---------- arch/um/os-Linux/drivers/ethertap_user.c | 36 +++++++++++----------------- arch/um/os-Linux/drivers/tuntap_user.c | 40 +++++++++++++------------------- 7 files changed, 57 insertions(+), 106 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 0cad3546cb8..77d3fdb0c21 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -158,7 +158,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) */ err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); if(err < 0){ - printk("fork of winch_thread failed - errno = %d\n", errno); + printk("fork of winch_thread failed - errno = %d\n", err); goto out_close; } diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 021b82c7a75..09d1de90297 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -39,11 +39,11 @@ static struct sockaddr_un *new_addr(void *name, int len) sun = um_kmalloc(sizeof(struct sockaddr_un)); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); - return(NULL); + return NULL; } sun->sun_family = AF_UNIX; memcpy(sun->sun_path, name, len); - return(sun); + return sun; } static int connect_to_switch(struct daemon_data *pri) @@ -112,7 +112,7 @@ static int connect_to_switch(struct daemon_data *pri) } pri->data_addr = sun; - return(fd); + return fd; out_free: kfree(sun); @@ -120,7 +120,7 @@ static int connect_to_switch(struct daemon_data *pri) os_close_file(fd); out: os_close_file(pri->control); - return(err); + return err; } static void daemon_user_init(void *data, void *dev) @@ -152,7 +152,7 @@ static void daemon_user_init(void *data, void *dev) static int daemon_open(void *data) { struct daemon_data *pri = data; - return(pri->fd); + return pri->fd; } static void daemon_remove(void *data) @@ -176,12 +176,12 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) { struct sockaddr_un *data_addr = pri->data_addr; - return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); + return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); } static int daemon_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } const struct net_user_info daemon_user_info = { @@ -194,14 +194,3 @@ const struct net_user_info daemon_user_info = { .delete_address = NULL, .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; - -/* - * 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: - */ diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index b827e82884c..cfaa2cc4313 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -34,12 +34,12 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) sin = um_kmalloc(sizeof(struct sockaddr_in)); if(sin == NULL){ printk("new_addr: allocation of sockaddr_in failed\n"); - return(NULL); + return NULL; } sin->sin_family = AF_INET; sin->sin_addr.s_addr = in_aton(addr); sin->sin_port = htons(port); - return(sin); + return sin; } static void mcast_user_init(void *data, void *dev) @@ -107,8 +107,8 @@ static int mcast_open(void *data) err = -errno; printk("mcast_open : data bind failed, errno = %d\n", errno); goto out_close; - } - + } + /* subscribe to the multicast group */ mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; mreq.imr_interface.s_addr = 0; @@ -153,12 +153,12 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) { struct sockaddr_in *data_addr = pri->mcast_addr; - return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); + return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); } static int mcast_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } const struct net_user_info mcast_user_info = { diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index 11921a7baa7..a1747dc0ff6 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -42,39 +42,39 @@ static int pcap_open(void *data) int err; if(pri->pcap == NULL) - return(-ENODEV); + return -ENODEV; if(pri->filter != NULL){ err = dev_netmask(pri->dev, &netmask); if(err < 0){ printk("pcap_open : dev_netmask failed\n"); - return(-EIO); + return -EIO; } pri->compiled = um_kmalloc(sizeof(struct bpf_program)); if(pri->compiled == NULL){ printk("pcap_open : kmalloc failed\n"); - return(-ENOMEM); + return -ENOMEM; } - + err = pcap_compile(pri->pcap, (struct bpf_program *) pri->compiled, pri->filter, pri->optimize, netmask); if(err < 0){ printk("pcap_open : pcap_compile failed - '%s'\n", pcap_geterr(pri->pcap)); - return(-EIO); + return -EIO; } err = pcap_setfilter(pri->pcap, pri->compiled); if(err < 0){ printk("pcap_open : pcap_setfilter failed - '%s'\n", pcap_geterr(pri->pcap)); - return(-EIO); + return -EIO; } } - - return(PCAP_FD(pri->pcap)); + + return PCAP_FD(pri->pcap); } static void pcap_remove(void *data) @@ -114,11 +114,11 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); if(n < 0){ printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap)); - return(-EIO); + return -EIO; } else if(n == 0) - return(0); - return(hdata.len); + return 0; + return hdata.len; } const struct net_user_info pcap_user_info = { @@ -131,14 +131,3 @@ const struct net_user_info pcap_user_info = { .delete_address = NULL, .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; - -/* - * 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: - */ diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index b94d2bc4fe0..039572cbedf 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -47,8 +47,8 @@ int start_io_thread(unsigned long sp, int *fd_out) pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD, NULL); if(pid < 0){ - printk("start_io_thread - clone failed : errno = %d\n", errno); err = -errno; + printk("start_io_thread - clone failed : errno = %d\n", errno); goto out_close; } @@ -60,16 +60,5 @@ int start_io_thread(unsigned long sp, int *fd_out) kernel_fd = -1; *fd_out = -1; out: - return(err); + return err; } - -/* - * 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: - */ diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 863981ba146..f3ad0dac7cd 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -121,7 +121,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, n = os_read_file(control_me, &c, sizeof(c)); if(n != sizeof(c)){ printk("etap_tramp : read of status failed, err = %d\n", -n); - return(-EINVAL); + return -EINVAL; } if(c != 1){ printk("etap_tramp : uml_net failed\n"); @@ -132,7 +132,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) printk("uml_net didn't exit with status 1\n"); } - return(err); + return err; } static int etap_open(void *data) @@ -142,20 +142,21 @@ static int etap_open(void *data) int data_fds[2], control_fds[2], err, output_len; err = tap_open_common(pri->dev, pri->gate_addr); - if(err) return(err); + if(err) + return err; err = os_pipe(data_fds, 0, 0); if(err < 0){ printk("data os_pipe failed - err = %d\n", -err); - return(err); + return err; } err = os_pipe(control_fds, 1, 0); if(err < 0){ printk("control os_pipe failed - err = %d\n", -err); - return(err); + return err; } - + err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); output_len = page_size(); @@ -171,13 +172,13 @@ static int etap_open(void *data) if(err < 0){ printk("etap_tramp failed - err = %d\n", -err); - return(err); + return err; } pri->data_fd = data_fds[0]; pri->control_fd = control_fds[0]; iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); - return(data_fds[0]); + return data_fds[0]; } static void etap_close(int fd, void *data) @@ -195,7 +196,7 @@ static void etap_close(int fd, void *data) static int etap_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } static void etap_add_addr(unsigned char *addr, unsigned char *netmask, @@ -204,7 +205,8 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask, struct ethertap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if(pri->control_fd == -1) return; + if(pri->control_fd == -1) + return; etap_open_addr(addr, netmask, &pri->control_fd); } @@ -213,7 +215,8 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask, { struct ethertap_data *pri = data; - if(pri->control_fd == -1) return; + if(pri->control_fd == -1) + return; etap_close_addr(addr, netmask, &pri->control_fd); } @@ -227,14 +230,3 @@ const struct net_user_info ethertap_user_info = { .delete_address = etap_del_addr, .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP }; - -/* - * 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: - */ diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index e846b23f755..ab63fb6f999 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -37,7 +37,8 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, struct tuntap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if((pri->fd == -1) || pri->fixed_config) return; + if((pri->fd == -1) || pri->fixed_config) + return; open_addr(addr, netmask, pri->dev_name); } @@ -46,7 +47,8 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask, { struct tuntap_data *pri = data; - if((pri->fd == -1) || pri->fixed_config) return; + if((pri->fd == -1) || pri->fixed_config) + return; close_addr(addr, netmask, pri->dev_name); } @@ -58,7 +60,7 @@ struct tuntap_pre_exec_data { static void tuntap_pre_exec(void *arg) { struct tuntap_pre_exec_data *data = arg; - + dup2(data->stdout, 1); os_close_file(data->close_me); } @@ -83,7 +85,8 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, pid = run_helper(tuntap_pre_exec, &data, argv, NULL); - if(pid < 0) return(-pid); + if(pid < 0) + return -pid; os_close_file(remote); @@ -114,16 +117,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, cmsg = CMSG_FIRSTHDR(&msg); if(cmsg == NULL){ printk("tuntap_open_tramp : didn't receive a message\n"); - return(-EINVAL); + return -EINVAL; } if((cmsg->cmsg_level != SOL_SOCKET) || (cmsg->cmsg_type != SCM_RIGHTS)){ printk("tuntap_open_tramp : didn't receive a descriptor\n"); - return(-EINVAL); + return -EINVAL; } *fd_out = ((int *) CMSG_DATA(cmsg))[0]; os_set_exec_close(*fd_out, 1); - return(0); + return 0; } static int tuntap_open(void *data) @@ -135,7 +138,7 @@ static int tuntap_open(void *data) err = tap_open_common(pri->dev, pri->gate_addr); if(err < 0) - return(err); + return err; if(pri->fixed_config){ pri->fd = os_open_file("/dev/net/tun", @@ -143,7 +146,7 @@ static int tuntap_open(void *data) if(pri->fd < 0){ printk("Failed to open /dev/net/tun, err = %d\n", -pri->fd); - return(pri->fd); + return pri->fd; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; @@ -160,7 +163,7 @@ static int tuntap_open(void *data) if(err < 0){ printk("tuntap_open : os_pipe failed - err = %d\n", -err); - return(err); + return err; } buffer = get_output_buffer(&len); @@ -175,7 +178,7 @@ static int tuntap_open(void *data) printk("%s", output); free_output_buffer(buffer); printk("tuntap_open_tramp failed - err = %d\n", -err); - return(err); + return err; } pri->dev_name = uml_strdup(buffer); @@ -187,7 +190,7 @@ static int tuntap_open(void *data) iter_addresses(pri->dev, open_addr, pri->dev_name); } - return(pri->fd); + return pri->fd; } static void tuntap_close(int fd, void *data) @@ -202,7 +205,7 @@ static void tuntap_close(int fd, void *data) static int tuntap_set_mtu(int mtu, void *data) { - return(mtu); + return mtu; } const struct net_user_info tuntap_user_info = { @@ -215,14 +218,3 @@ const struct net_user_info tuntap_user_info = { .delete_address = tuntap_del_addr, .max_packet = MAX_PACKET }; - -/* - * 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: - */ -- cgit v1.2.3 From b16895b63c504698b0c3ab26ca3c41a4fa162a42 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 6 May 2007 14:51:03 -0700 Subject: uml-driver-formatting-fixes-fix Cc: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 77d3fdb0c21..ed24eab647d 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -158,7 +158,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) */ err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); if(err < 0){ - printk("fork of winch_thread failed - errno = %d\n", err); + printk("fork of winch_thread failed - errno = %d\n", -err); goto out_close; } -- cgit v1.2.3 From f34d9d2dcb7f17b64124841345b23adc0843e7a5 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:04 -0700 Subject: uml: network interface hotplug error handling This fixes a number of problems associated with network interface hotplug. The userspace initialization function can fail in some cases, but the failure was never passed back to eth_configure, which proceeded with the configuration. This results in a zombie device that is present, but can't work. This is fixed by allowing the initialization routines to return an error, which is checked, and the configuration aborted on failure. eth_configure failed to check for many failures. Even when it did check, it didn't undo whatever initializations has already happened, so a present, but partially initialized and non-working device could result. It now checks everything that can fail, and bails out, undoing whatever had been done. The return value of eth_configure was always ignored, so it is now just void. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/daemon_user.c | 5 +- arch/um/drivers/mcast_user.c | 3 +- arch/um/drivers/net_kern.c | 81 ++++++++++++++++++-------------- arch/um/drivers/pcap_user.c | 5 +- arch/um/drivers/slip_user.c | 3 +- arch/um/drivers/slirp_user.c | 3 +- arch/um/include/net_user.h | 2 +- arch/um/os-Linux/drivers/ethertap_user.c | 3 +- arch/um/os-Linux/drivers/tuntap_user.c | 3 +- 9 files changed, 64 insertions(+), 44 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 09d1de90297..d0b656a517d 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -123,7 +123,7 @@ static int connect_to_switch(struct daemon_data *pri) return err; } -static void daemon_user_init(void *data, void *dev) +static int daemon_user_init(void *data, void *dev) { struct daemon_data *pri = data; struct timeval tv; @@ -146,7 +146,10 @@ static void daemon_user_init(void *data, void *dev) if(pri->fd < 0){ kfree(pri->local_addr); pri->local_addr = NULL; + return pri->fd; } + + return 0; } static int daemon_open(void *data) diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index cfaa2cc4313..0f64d946728 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -42,12 +42,13 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) return sin; } -static void mcast_user_init(void *data, void *dev) +static int mcast_user_init(void *data, void *dev) { struct mcast_data *pri = data; pri->mcast_addr = new_addr(pri->addr, pri->port); pri->dev = dev; + return 0; } static void mcast_remove(void *data) diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 859303730b2..ac746fb5d10 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -325,8 +325,8 @@ static struct platform_driver uml_net_driver = { }; static int driver_registered; -static int eth_configure(int n, void *init, char *mac, - struct transport *transport) +static void eth_configure(int n, void *init, char *mac, + struct transport *transport) { struct uml_net *device; struct net_device *dev; @@ -339,16 +339,12 @@ static int eth_configure(int n, void *init, char *mac, device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); - return(1); + return; } INIT_LIST_HEAD(&device->list); device->index = n; - spin_lock(&devices_lock); - list_add(&device->list, &devices); - spin_unlock(&devices_lock); - setup_etheraddr(mac, device->mac); printk(KERN_INFO "Netdevice %d ", n); @@ -360,7 +356,7 @@ static int eth_configure(int n, void *init, char *mac, dev = alloc_etherdev(size); if (dev == NULL) { printk(KERN_ERR "eth_configure: failed to allocate device\n"); - return 1; + goto out_free_device; } lp = dev->priv; @@ -376,7 +372,8 @@ static int eth_configure(int n, void *init, char *mac, } device->pdev.id = n; device->pdev.name = DRIVER_NAME; - platform_device_register(&device->pdev); + if(platform_device_register(&device->pdev)) + goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); /* If this name ends up conflicting with an existing registered @@ -386,31 +383,12 @@ static int eth_configure(int n, void *init, char *mac, snprintf(dev->name, sizeof(dev->name), "eth%d", n); device->dev = dev; + /* + * These just fill in a data structure, so there's no failure + * to be worried about. + */ (*transport->kern->init)(dev, init); - dev->mtu = transport->user->max_packet; - dev->open = uml_net_open; - dev->hard_start_xmit = uml_net_start_xmit; - dev->stop = uml_net_close; - dev->get_stats = uml_net_get_stats; - dev->set_multicast_list = uml_net_set_multicast_list; - dev->tx_timeout = uml_net_tx_timeout; - dev->set_mac_address = uml_net_set_mac; - dev->change_mtu = uml_net_change_mtu; - dev->ethtool_ops = ¨_net_ethtool_ops; - dev->watchdog_timeo = (HZ >> 1); - dev->irq = UM_ETH_IRQ; - - rtnl_lock(); - err = register_netdevice(dev); - rtnl_unlock(); - if (err) { - device->dev = NULL; - /* XXX: should we call ->remove() here? */ - free_netdev(dev); - return 1; - } - /* lp.user is the first four bytes of the transport data, which * has already been initialized. This structure assignment will * overwrite that, so we make sure that .user gets overwritten with @@ -438,12 +416,45 @@ static int eth_configure(int n, void *init, char *mac, lp->tl.function = uml_net_user_timer_expire; memcpy(lp->mac, device->mac, sizeof(lp->mac)); - if (transport->user->init) - (*transport->user->init)(&lp->user, dev); + if ((transport->user->init != NULL) && + ((*transport->user->init)(&lp->user, dev) != 0)) + goto out_unregister; set_ether_mac(dev, device->mac); + dev->mtu = transport->user->max_packet; + dev->open = uml_net_open; + dev->hard_start_xmit = uml_net_start_xmit; + dev->stop = uml_net_close; + dev->get_stats = uml_net_get_stats; + dev->set_multicast_list = uml_net_set_multicast_list; + dev->tx_timeout = uml_net_tx_timeout; + dev->set_mac_address = uml_net_set_mac; + dev->change_mtu = uml_net_change_mtu; + dev->ethtool_ops = ¨_net_ethtool_ops; + dev->watchdog_timeo = (HZ >> 1); + dev->irq = UM_ETH_IRQ; - return 0; + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) + goto out_undo_user_init; + + spin_lock(&devices_lock); + list_add(&device->list, &devices); + spin_unlock(&devices_lock); + + return; + +out_undo_user_init: + if (transport->user->init != NULL) + (*transport->user->remove)(&lp->user); +out_unregister: + platform_device_unregister(&device->pdev); +out_free_netdev: + free_netdev(dev); +out_free_device: ; + kfree(device); } static struct uml_net *find_device(int n) diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index a1747dc0ff6..dc0a903ef9a 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -18,7 +18,7 @@ #define PCAP_FD(p) (*(int *)(p)) -static void pcap_user_init(void *data, void *dev) +static int pcap_user_init(void *data, void *dev) { struct pcap_data *pri = data; pcap_t *p; @@ -28,11 +28,12 @@ static void pcap_user_init(void *data, void *dev) if(p == NULL){ printk("pcap_user_init : pcap_open_live failed - '%s'\n", errors); - return; + return -EINVAL; } pri->dev = dev; pri->pcap = p; + return 0; } static int pcap_open(void *data) diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 7eddacc53b6..329c072d17d 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -17,11 +17,12 @@ #include "os.h" #include "um_malloc.h" -void slip_user_init(void *data, void *dev) +static int slip_user_init(void *data, void *dev) { struct slip_data *pri = data; pri->dev = dev; + return 0; } static int set_up_tty(int fd) diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index ce5e85d1de3..f0a40abc8ab 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -15,11 +15,12 @@ #include "slip_common.h" #include "os.h" -void slirp_user_init(void *data, void *dev) +static int slirp_user_init(void *data, void *dev) { struct slirp_data *pri = data; pri->dev = dev; + return 0; } struct slirp_pre_exec_data { diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index 19f207cd70f..cfe7c50634b 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h @@ -14,7 +14,7 @@ #define UML_NET_VERSION (4) struct net_user_info { - void (*init)(void *, void *); + int (*init)(void *, void *); int (*open)(void *); void (*close)(int, void *); void (*remove)(void *); diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index f3ad0dac7cd..2cc2d3ea2e6 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -24,11 +24,12 @@ #define MAX_PACKET ETH_MAX_PACKET -void etap_user_init(void *data, void *dev) +static int etap_user_init(void *data, void *dev) { struct ethertap_data *pri = data; pri->dev = dev; + return 0; } struct addr_change { diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index ab63fb6f999..506ef09d83a 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -24,11 +24,12 @@ #define MAX_PACKET ETH_MAX_PACKET -void tuntap_user_init(void *data, void *dev) +static int tuntap_user_init(void *data, void *dev) { struct tuntap_data *pri = data; pri->dev = dev; + return 0; } static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, -- cgit v1.2.3 From c5e631cf65f4d6875efcd571275436f2964a8b48 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 6 May 2007 14:51:05 -0700 Subject: ARRAY_SIZE: check for type We can use a gcc extension to ensure that ARRAY_SIZE() is handed an array, not a pointer. This is especially important when code is changed from a fixed array to a pointer. I assume the Intel compiler doesn't support __builtin_types_compatible_p. [jdike@addtoit.com: uml: update UML definition of ARRAY_SIZE] Signed-off-by: Rusty Russell Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user_util.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 73ffea1829f..b52bc408483 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -8,8 +8,19 @@ #include "sysdep/ptrace.h" -/* Copied from kernel.h */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/* Copied from kernel.h and compiler-gcc.h */ + +/* Force a compilation error if condition is true, but also produce a + result (of value 0 and type size_t), so the expression can be used + e.g. in a structure initializer (or where-ever else comma expressions + aren't permitted). */ +#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) + +/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array(a) \ + BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) -- cgit v1.2.3 From c65badbdf5dc117e45873e760f807063ad59a854 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:06 -0700 Subject: uml: move SIGIO testing to sigio.c This patch narrows the sigio interface. The boot-time SIGIO testing used to be in start_up.c, which meant that pty_output_sigio and pty_close_sigio needed to be global. By moving that code here, those can become static and the declarations moved from user_util.h. os_check_bugs is also here because it only does the SIGIO checking. If it does more, it'll probably move back to start_up.c. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user_util.h | 3 - arch/um/os-Linux/sigio.c | 145 ++++++++++++++++++++++++++++++++++++++++++++ arch/um/os-Linux/start_up.c | 145 -------------------------------------------- 3 files changed, 145 insertions(+), 148 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index b52bc408483..df4869aa940 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -51,9 +51,6 @@ extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; extern unsigned long _unprotected_end; extern unsigned long brk_start; -extern int pty_output_sigio; -extern int pty_close_sigio; - extern void *add_signal_handler(int sig, void (*handler)(int)); extern int linux_main(int argc, char **argv); extern void set_cmdline(char *cmd); diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 3fc43b33db6..c61d01bf46e 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include "sigio.h" #include "os.h" #include "um_malloc.h" +#include "init.h" /* Protected by sigio_lock(), also used by sigio_cleanup, which is an * exitcall. @@ -320,6 +322,10 @@ out_close1: close(l_write_sigio_fds[1]); } +/* Changed during early boot */ +static int pty_output_sigio = 0; +static int pty_close_sigio = 0; + void maybe_sigio_broken(int fd, int read) { int err; @@ -357,3 +363,142 @@ static void sigio_cleanup(void) } __uml_exitcall(sigio_cleanup); + +/* Used as a flag during SIGIO testing early in boot */ +static volatile int got_sigio = 0; + +static void __init handler(int sig) +{ + got_sigio = 1; +} + +struct openpty_arg { + int master; + int slave; + int err; +}; + +static void openpty_cb(void *arg) +{ + struct openpty_arg *info = arg; + + info->err = 0; + if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) + info->err = -errno; +} + +static int async_pty(int master, int slave) +{ + int flags; + + flags = fcntl(master, F_GETFL); + if(flags < 0) + return -errno; + + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || + (fcntl(master, F_SETOWN, os_getpid()) < 0)) + return -errno; + + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) + return -errno; + + return(0); +} + +static void __init check_one_sigio(void (*proc)(int, int)) +{ + struct sigaction old, new; + struct openpty_arg pty = { .master = -1, .slave = -1 }; + int master, slave, err; + + initial_thread_cb(openpty_cb, &pty); + if(pty.err){ + printk("openpty failed, errno = %d\n", -pty.err); + return; + } + + master = pty.master; + slave = pty.slave; + + if((master == -1) || (slave == -1)){ + printk("openpty failed to allocate a pty\n"); + return; + } + + /* Not now, but complain so we now where we failed. */ + err = raw(master); + if (err < 0) + panic("check_sigio : __raw failed, errno = %d\n", -err); + + err = async_pty(master, slave); + if(err < 0) + panic("tty_fds : sigio_async failed, err = %d\n", -err); + + if(sigaction(SIGIO, NULL, &old) < 0) + panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); + new = old; + new.sa_handler = handler; + if(sigaction(SIGIO, &new, NULL) < 0) + panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); + + got_sigio = 0; + (*proc)(master, slave); + + close(master); + close(slave); + + if(sigaction(SIGIO, &old, NULL) < 0) + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); +} + +static void tty_output(int master, int slave) +{ + int n; + char buf[512]; + + printk("Checking that host ptys support output SIGIO..."); + + memset(buf, 0, sizeof(buf)); + + while(os_write_file(master, buf, sizeof(buf)) > 0) ; + if(errno != EAGAIN) + panic("check_sigio : write failed, errno = %d\n", errno); + while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; + + if(got_sigio){ + printk("Yes\n"); + pty_output_sigio = 1; + } + else if(n == -EAGAIN) printk("No, enabling workaround\n"); + else panic("check_sigio : read failed, err = %d\n", n); +} + +static void tty_close(int master, int slave) +{ + printk("Checking that host ptys support SIGIO on close..."); + + close(slave); + if(got_sigio){ + printk("Yes\n"); + pty_close_sigio = 1; + } + else printk("No, enabling workaround\n"); +} + +void __init check_sigio(void) +{ + if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && + (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ + printk("No pseudo-terminals available - skipping pty SIGIO " + "check\n"); + return; + } + check_one_sigio(tty_output); + check_one_sigio(tty_close); +} + +/* Here because it only does the SIGIO testing for now */ +void __init os_check_bugs(void) +{ + check_sigio(); +} diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 1244179e6c8..1540f21d699 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -553,148 +553,3 @@ int __init parse_iomem(char *str, int *add) out: return 1; } - - -/* Changed during early boot */ -int pty_output_sigio = 0; -int pty_close_sigio = 0; - -/* Used as a flag during SIGIO testing early in boot */ -static volatile int got_sigio = 0; - -static void __init handler(int sig) -{ - got_sigio = 1; -} - -struct openpty_arg { - int master; - int slave; - int err; -}; - -static void openpty_cb(void *arg) -{ - struct openpty_arg *info = arg; - - info->err = 0; - if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) - info->err = -errno; -} - -static int async_pty(int master, int slave) -{ - int flags; - - flags = fcntl(master, F_GETFL); - if(flags < 0) - return -errno; - - if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || - (fcntl(master, F_SETOWN, os_getpid()) < 0)) - return -errno; - - if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) - return -errno; - - return(0); -} - -static void __init check_one_sigio(void (*proc)(int, int)) -{ - struct sigaction old, new; - struct openpty_arg pty = { .master = -1, .slave = -1 }; - int master, slave, err; - - initial_thread_cb(openpty_cb, &pty); - if(pty.err){ - printk("openpty failed, errno = %d\n", -pty.err); - return; - } - - master = pty.master; - slave = pty.slave; - - if((master == -1) || (slave == -1)){ - printk("openpty failed to allocate a pty\n"); - return; - } - - /* Not now, but complain so we now where we failed. */ - err = raw(master); - if (err < 0) - panic("check_sigio : __raw failed, errno = %d\n", -err); - - err = async_pty(master, slave); - if(err < 0) - panic("tty_fds : sigio_async failed, err = %d\n", -err); - - if(sigaction(SIGIO, NULL, &old) < 0) - panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); - new = old; - new.sa_handler = handler; - if(sigaction(SIGIO, &new, NULL) < 0) - panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); - - got_sigio = 0; - (*proc)(master, slave); - - close(master); - close(slave); - - if(sigaction(SIGIO, &old, NULL) < 0) - panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); -} - -static void tty_output(int master, int slave) -{ - int n; - char buf[512]; - - printk("Checking that host ptys support output SIGIO..."); - - memset(buf, 0, sizeof(buf)); - - while(os_write_file(master, buf, sizeof(buf)) > 0) ; - if(errno != EAGAIN) - panic("check_sigio : write failed, errno = %d\n", errno); - while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; - - if(got_sigio){ - printk("Yes\n"); - pty_output_sigio = 1; - } - else if(n == -EAGAIN) printk("No, enabling workaround\n"); - else panic("check_sigio : read failed, err = %d\n", n); -} - -static void tty_close(int master, int slave) -{ - printk("Checking that host ptys support SIGIO on close..."); - - close(slave); - if(got_sigio){ - printk("Yes\n"); - pty_close_sigio = 1; - } - else printk("No, enabling workaround\n"); -} - -void __init check_sigio(void) -{ - if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && - (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ - printk("No pseudo-terminals available - skipping pty SIGIO " - "check\n"); - return; - } - check_one_sigio(tty_output); - check_one_sigio(tty_close); -} - -void os_check_bugs(void) -{ - check_ptrace(); - check_sigio(); -} - -- cgit v1.2.3 From eb8307595baa729a12db0fec9a80910b13bd6fc8 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:07 -0700 Subject: uml: create arch.h This patch moves the declarations of the architecture hooks from user_util.h to a new header, arch.c, and adds the necessary includes to files which need those declarations. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/arch.h | 15 +++++++++++++++ arch/um/include/user_util.h | 4 ---- arch/um/kernel/trap.c | 1 + arch/um/kernel/um_arch.c | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 arch/um/include/arch.h (limited to 'arch/um') diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h new file mode 100644 index 00000000000..8e11dd7c1ad --- /dev/null +++ b/arch/um/include/arch.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __ARCH_H__ +#define __ARCH_H__ + +#include "sysdep/ptrace.h" + +extern void arch_check_bugs(void); +extern int arch_fixup(unsigned long address, void *sc_ptr); +extern int arch_handle_signal(int sig, union uml_pt_regs *regs); + +#endif diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index df4869aa940..fabad2372af 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -65,10 +65,6 @@ extern int attach(int pid); extern void kill_child_dead(int pid); extern int cont(int pid); extern void check_sigio(void); -extern void arch_check_bugs(void); -extern int arch_handle_signal(int sig, union uml_pt_regs *regs); -extern int arch_fixup(unsigned long address, void *sc_ptr); -extern void arch_init_thread(void); extern int raw(int fd); #endif diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 26f15c45857..e27b898412f 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -20,6 +20,7 @@ #include "sysdep/sigcontext.h" #include "user_util.h" #include "kern_util.h" +#include "arch.h" #include "kern.h" #include "chan_kern.h" #include "mconsole_kern.h" diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 613fb082bbd..8eefb5202c5 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -28,6 +28,7 @@ #include "asm/current.h" #include "user_util.h" #include "kern_util.h" +#include "arch.h" #include "kern.h" #include "mem_user.h" #include "mem.h" -- cgit v1.2.3 From 4ff83ce1114827f707b7f1f4f2e5f69de9df94ac Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:08 -0700 Subject: uml: create as-layout.h This patch moves all the the symbols defined in um_arch.c, which are mostly boundaries between different parts of the UML kernel address space, to a new header, as-layout.h. There are also a few things here which aren't really related to address space layout, but which don't really have a better place to go. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/as-layout.h | 35 +++++++++++++++++++++++++++++++++++ arch/um/include/user_util.h | 23 ----------------------- arch/um/kernel/exec.c | 1 + arch/um/kernel/ksyms.c | 1 + arch/um/kernel/mem.c | 1 + arch/um/kernel/physmem.c | 1 + arch/um/kernel/process.c | 1 + arch/um/kernel/skas/process.c | 1 + arch/um/kernel/tlb.c | 1 + arch/um/kernel/trap.c | 1 + arch/um/kernel/um_arch.c | 1 + arch/um/os-Linux/main.c | 1 + arch/um/os-Linux/skas/trap.c | 1 + 13 files changed, 46 insertions(+), 23 deletions(-) create mode 100644 arch/um/include/as-layout.h (limited to 'arch/um') diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h new file mode 100644 index 00000000000..fccf187bf4e --- /dev/null +++ b/arch/um/include/as-layout.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __START_H__ +#define __START_H__ + +#include "sysdep/ptrace.h" + +struct cpu_task { + int pid; + void *task; +}; + +extern struct cpu_task cpu_tasks[]; + +extern unsigned long low_physmem; +extern unsigned long high_physmem; +extern unsigned long uml_physmem; +extern unsigned long uml_reserved; +extern unsigned long end_vm; +extern unsigned long start_vm; +extern unsigned long long highmem; + +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; +extern unsigned long _unprotected_end; +extern unsigned long brk_start; + +extern int linux_main(int argc, char **argv); +extern void set_cmdline(char *cmd); + +extern void (*sig_info[])(int, union uml_pt_regs *); + +#endif diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index fabad2372af..f04776e2436 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -30,30 +30,7 @@ extern int grantpt(int __fd); extern int unlockpt(int __fd); extern char *ptsname(int __fd); -struct cpu_task { - int pid; - void *task; -}; - -extern struct cpu_task cpu_tasks[]; - -extern void (*sig_info[])(int, union uml_pt_regs *); - -extern unsigned long low_physmem; -extern unsigned long high_physmem; -extern unsigned long uml_physmem; -extern unsigned long uml_reserved; -extern unsigned long end_vm; -extern unsigned long start_vm; -extern unsigned long long highmem; - -extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; -extern unsigned long _unprotected_end; -extern unsigned long brk_start; - extern void *add_signal_handler(int sig, void (*handler)(int)); -extern int linux_main(int argc, char **argv); -extern void set_cmdline(char *cmd); extern void input_cb(void (*proc)(void *), void *arg, int arg_len); extern int get_pty(void); extern int switcheroo(int fd, int prot, void *from, void *to, int size); diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 121166400e2..1ada13ea84e 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -12,6 +12,7 @@ #include "asm/uaccess.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "mem_user.h" #include "kern.h" #include "irq_user.h" diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 0e00cf93f90..288b4ee2041 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -16,6 +16,7 @@ #include "asm/page.h" #include "asm/tlbflush.h" #include "kern_util.h" +#include "as-layout.h" #include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index df7d662b98c..3a13d41c28d 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -15,6 +15,7 @@ #include "asm/pgalloc.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "kern.h" #include "mem_user.h" #include "uml_uaccess.h" diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 638f3b5f609..f92f06c35db 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -13,6 +13,7 @@ #include "asm/types.h" #include "asm/pgtable.h" #include "kern_util.h" +#include "as-layout.h" #include "user_util.h" #include "mode_kern.h" #include "mem.h" diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 348b272bb76..e4208386e7a 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -34,6 +34,7 @@ #include "asm/user.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "kern.h" #include "signal_kern.h" #include "init.h" diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index ae4fa71d3b8..9c2a7d8c56f 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -13,6 +13,7 @@ #include "asm/uaccess.h" #include "asm/atomic.h" #include "kern_util.h" +#include "as-layout.h" #include "skas.h" #include "os.h" #include "user_util.h" diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 54a5ff25645..b8b3cff0668 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -9,6 +9,7 @@ #include "asm/tlbflush.h" #include "choose-mode.h" #include "mode_kern.h" +#include "as-layout.h" #include "user_util.h" #include "tlb.h" #include "mem.h" diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index e27b898412f..552bcfc7c08 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -20,6 +20,7 @@ #include "sysdep/sigcontext.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "arch.h" #include "kern.h" #include "chan_kern.h" diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 8eefb5202c5..20684c04d5d 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -28,6 +28,7 @@ #include "asm/current.h" #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "arch.h" #include "kern.h" #include "mem_user.h" diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 2c089c2c63b..25261d6c7bf 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -15,6 +15,7 @@ #include #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "mem_user.h" #include "irq_user.h" #include "user.h" diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 9ad5fbec459..19ff04bdec9 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -7,6 +7,7 @@ #include #include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "task.h" #include "sigcontext.h" #include "skas.h" -- cgit v1.2.3 From 24fa6c0832f4513ac897082d7d803970a40cc1b0 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:09 -0700 Subject: uml: move remaining useful contents of user_util.h Rescue the useful contents of the soon-to-be-gone user-util.h. pty.c now gets ptsname from stdlib.h like it should have always done. CATCH_EINTR is now in os.h, although perhaps all usage should be under os-Linux at some point. get_pty is also in os.h. This patch restores the old definition of ARRAY_SIZE in user.h. This file is included only in userspace files, so there will be no conflict with the kernel's new ARRAY_SIZE. The copy of the kernel's ARRAY_SIZE and associated infrastructure is now gone. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/pty.c | 1 + arch/um/include/os.h | 6 ++++++ arch/um/include/user.h | 19 ++++++++----------- arch/um/include/user_util.h | 18 ------------------ arch/um/os-Linux/sys-i386/tls.c | 1 + 5 files changed, 16 insertions(+), 29 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 829a5eca8c0..aa311afa966 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 22666b4a8be..394adcded0b 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -16,6 +16,8 @@ #include "sysdep/tls.h" #include "sysdep/archsetjmp.h" +#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) + #define OS_TYPE_FILE 1 #define OS_TYPE_DIR 2 #define OS_TYPE_SYMLINK 3 @@ -341,6 +343,10 @@ extern void maybe_sigio_broken(int fd, int read); extern void sig_handler_common_skas(int sig, void *sc_ptr); extern void user_signal(int sig, union uml_pt_regs *regs, int pid); +/* sys-x86_64/prctl.c */ extern int os_arch_prctl(int pid, int code, unsigned long *addr); +/* tty.c */ +int get_pty(void); + #endif diff --git a/arch/um/include/user.h b/arch/um/include/user.h index acadce3f271..a6da6260825 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h @@ -6,6 +6,14 @@ #ifndef __USER_H__ #define __USER_H__ +/* + * The usual definition - copied here because the kernel provides its own, + * fancier, type-safe, definition. Using that one would require + * copying too much infrastructure for my taste, so userspace files + * get less checking than kernel files. + */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + extern void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern int printk(const char *fmt, ...) @@ -18,14 +26,3 @@ extern unsigned long strlcpy(char *, const char *, unsigned long); extern unsigned long strlcat(char *, const char *, unsigned long); #endif - -/* - * 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: - */ diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index f04776e2436..7fa5c68f062 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -8,31 +8,13 @@ #include "sysdep/ptrace.h" -/* Copied from kernel.h and compiler-gcc.h */ - -/* Force a compilation error if condition is true, but also produce a - result (of value 0 and type size_t), so the expression can be used - e.g. in a structure initializer (or where-ever else comma expressions - aren't permitted). */ -#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) - -/* &a[0] degrades to a pointer: a different type from an array */ -#define __must_be_array(a) \ - BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) - -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) - -#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) - extern int mode_tt; extern int grantpt(int __fd); extern int unlockpt(int __fd); -extern char *ptsname(int __fd); extern void *add_signal_handler(int sig, void (*handler)(int)); extern void input_cb(void (*proc)(void *), void *arg, int arg_len); -extern int get_pty(void); extern int switcheroo(int fd, int prot, void *from, void *to, int size); extern void do_exec(int old_pid, int new_pid); extern void tracer_panic(char *msg, ...) diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index 256532034c6..8ba13248297 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -5,6 +5,7 @@ #include #include "sysdep/tls.h" +#include "user.h" #include "user_util.h" /* Checks whether host supports TLS, and sets *tls_min according to the value -- cgit v1.2.3 From 9218b1714949095bff9d9739d80f431d58e561d6 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:10 -0700 Subject: uml: remove user_util.h user_util.h isn't needed any more, so delete it and remove all includes of it. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 1 - arch/um/drivers/chan_user.c | 1 - arch/um/drivers/cow_sys.h | 1 - arch/um/drivers/daemon_user.c | 1 - arch/um/drivers/fd.c | 1 - arch/um/drivers/harddog_user.c | 1 - arch/um/drivers/line.c | 1 - arch/um/drivers/mcast_user.c | 1 - arch/um/drivers/mconsole_kern.c | 1 - arch/um/drivers/mconsole_user.c | 1 - arch/um/drivers/mmapper_kern.c | 1 - arch/um/drivers/net_kern.c | 1 - arch/um/drivers/net_user.c | 1 - arch/um/drivers/port_user.c | 1 - arch/um/drivers/pty.c | 1 - arch/um/drivers/slip_user.c | 1 - arch/um/drivers/slirp_user.c | 1 - arch/um/drivers/ssl.c | 1 - arch/um/drivers/stdio_console.c | 1 - arch/um/drivers/tty.c | 1 - arch/um/drivers/ubd_kern.c | 1 - arch/um/drivers/ubd_user.c | 1 - arch/um/drivers/xterm.c | 1 - arch/um/include/user_util.h | 29 ----------------------------- arch/um/kernel/exec.c | 1 - arch/um/kernel/init_task.c | 1 - arch/um/kernel/initrd.c | 1 - arch/um/kernel/irq.c | 1 - arch/um/kernel/ksyms.c | 1 - arch/um/kernel/mem.c | 1 - arch/um/kernel/physmem.c | 1 - arch/um/kernel/process.c | 1 - arch/um/kernel/reboot.c | 1 - arch/um/kernel/signal.c | 1 - arch/um/kernel/skas/process.c | 1 - arch/um/kernel/skas/tlb.c | 1 - arch/um/kernel/smp.c | 1 - arch/um/kernel/syscall.c | 1 - arch/um/kernel/sysrq.c | 1 - arch/um/kernel/time.c | 1 - arch/um/kernel/tlb.c | 1 - arch/um/kernel/trap.c | 1 - arch/um/kernel/tt/exec_kern.c | 1 - arch/um/kernel/tt/exec_user.c | 1 - arch/um/kernel/tt/gdb.c | 1 - arch/um/kernel/tt/mem.c | 1 - arch/um/kernel/tt/mem_user.c | 1 - arch/um/kernel/tt/process_kern.c | 1 - arch/um/kernel/tt/ptproxy/proxy.c | 1 - arch/um/kernel/tt/ptproxy/ptrace.c | 1 - arch/um/kernel/tt/ptproxy/sysdep.c | 1 - arch/um/kernel/tt/ptproxy/wait.c | 1 - arch/um/kernel/tt/syscall_user.c | 1 - arch/um/kernel/tt/tlb.c | 1 - arch/um/kernel/tt/tracer.c | 1 - arch/um/kernel/tt/trap_user.c | 1 - arch/um/kernel/tt/uaccess_user.c | 1 - arch/um/kernel/um_arch.c | 1 - arch/um/os-Linux/drivers/ethertap_user.c | 1 - arch/um/os-Linux/drivers/tuntap_user.c | 1 - arch/um/os-Linux/file.c | 1 - arch/um/os-Linux/helper.c | 1 - arch/um/os-Linux/irq.c | 1 - arch/um/os-Linux/main.c | 1 - arch/um/os-Linux/mem.c | 1 - arch/um/os-Linux/process.c | 1 - arch/um/os-Linux/sigio.c | 1 - arch/um/os-Linux/signal.c | 1 - arch/um/os-Linux/skas/mem.c | 1 - arch/um/os-Linux/skas/process.c | 1 - arch/um/os-Linux/skas/trap.c | 1 - arch/um/os-Linux/start_up.c | 1 - arch/um/os-Linux/sys-i386/tls.c | 1 - arch/um/os-Linux/time.c | 1 - arch/um/os-Linux/trap.c | 1 - arch/um/os-Linux/tt.c | 1 - arch/um/os-Linux/util.c | 1 - arch/um/sys-i386/bugs.c | 1 - arch/um/sys-i386/ptrace_user.c | 1 - arch/um/sys-ppc/sigcontext.c | 1 - 80 files changed, 108 deletions(-) delete mode 100644 arch/um/include/user_util.h (limited to 'arch/um') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 9fdfad64953..3aa35161176 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -12,7 +12,6 @@ #include #include #include "chan_kern.h" -#include "user_util.h" #include "kern.h" #include "irq_user.h" #include "sigio.h" diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index ed24eab647d..ee53cf882f4 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -14,7 +14,6 @@ #include #include #include "kern_util.h" -#include "user_util.h" #include "chan_user.h" #include "user.h" #include "os.h" diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index c6a308464ac..c702943769c 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -2,7 +2,6 @@ #define __COW_SYS_H__ #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "user.h" #include "um_malloc.h" diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index d0b656a517d..b869e389968 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -14,7 +14,6 @@ #include "net_user.h" #include "daemon.h" #include "kern_util.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 218aa0e9b79..7f083ec47a4 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -9,7 +9,6 @@ #include #include #include "user.h" -#include "user_util.h" #include "chan_user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index c495ecf263b..5eeecf8917c 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -6,7 +6,6 @@ #include #include #include -#include "user_util.h" #include "user.h" #include "mconsole.h" #include "os.h" diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index f75d7b05c48..ced99106f79 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -13,7 +13,6 @@ #include "irq_user.h" #include "line.h" #include "kern.h" -#include "user_util.h" #include "kern_util.h" #include "os.h" #include "irq_kern.h" diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 0f64d946728..d319db16d4e 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -20,7 +20,6 @@ #include "net_user.h" #include "mcast.h" #include "kern_util.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 65ad2932672..542c9ef858f 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -25,7 +25,6 @@ #include "linux/console.h" #include "asm/irq.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "mconsole.h" diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index f02634fbf32..62e5ad63181 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -17,7 +17,6 @@ #include "sysdep/ptrace.h" #include "mconsole.h" #include "os.h" -#include "user_util.h" static struct mconsole_command commands[] = { /* With uts namespaces, uts information becomes process-specific, so diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index df3516e47d4..e41a08f0469 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -15,7 +15,6 @@ #include #include #include "mem_user.h" -#include "user_util.h" /* These are set in mmapper_init, which is called at boot time */ static unsigned long mmapper_size; diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index ac746fb5d10..20963f106c3 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -21,7 +21,6 @@ #include "linux/ethtool.h" #include "linux/platform_device.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "net_kern.h" #include "net_user.h" diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 0ffd7ac295d..b63a8604637 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -14,7 +14,6 @@ #include #include #include "user.h" -#include "user_util.h" #include "kern_util.h" #include "net_user.h" #include "os.h" diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index 80508023054..3f6357d24be 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -13,7 +13,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "chan_user.h" diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index aa311afa966..df4976c9eef 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -11,7 +11,6 @@ #include #include "chan_user.h" #include "user.h" -#include "user_util.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 329c072d17d..9f41cece091 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -8,7 +8,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "net_user.h" diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index f0a40abc8ab..39f889fe994 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -7,7 +7,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "net_user.h" diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 4b382a6e710..94faadc5ea1 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -15,7 +15,6 @@ #include "line.h" #include "ssl.h" #include "chan_kern.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "init.h" diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 76d1f1c980e..90a2c5cc17d 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -22,7 +22,6 @@ #include "stdio_console.h" #include "line.h" #include "chan_kern.h" -#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "mconsole_kern.h" diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index d95d64309ea..c07d0d56278 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -8,7 +8,6 @@ #include #include #include "chan_user.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 53c36d1770c..962b8fb35f8 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -39,7 +39,6 @@ #include "asm/irq.h" #include "asm/types.h" #include "asm/tlbflush.h" -#include "user_util.h" #include "mem_user.h" #include "kern_util.h" #include "kern.h" diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index 039572cbedf..4707b3f14c2 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -16,7 +16,6 @@ #include #include #include "asm/types.h" -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "ubd_user.h" diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 850221d9b4c..571c2b3325d 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -14,7 +14,6 @@ #include #include "kern_util.h" #include "chan_user.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "xterm.h" diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h deleted file mode 100644 index 7fa5c68f062..00000000000 --- a/arch/um/include/user_util.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __USER_UTIL_H__ -#define __USER_UTIL_H__ - -#include "sysdep/ptrace.h" - -extern int mode_tt; - -extern int grantpt(int __fd); -extern int unlockpt(int __fd); - -extern void *add_signal_handler(int sig, void (*handler)(int)); -extern void input_cb(void (*proc)(void *), void *arg, int arg_len); -extern int switcheroo(int fd, int prot, void *from, void *to, int size); -extern void do_exec(int old_pid, int new_pid); -extern void tracer_panic(char *msg, ...) - __attribute__ ((format (printf, 1, 2))); -extern int detach(int pid, int sig); -extern int attach(int pid); -extern void kill_child_dead(int pid); -extern int cont(int pid); -extern void check_sigio(void); -extern int raw(int fd); - -#endif diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 1ada13ea84e..356e50f5aae 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -10,7 +10,6 @@ #include "asm/pgtable.h" #include "asm/tlbflush.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "mem_user.h" diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index 8cde431348c..cda91aa8e70 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c @@ -10,7 +10,6 @@ #include "linux/mqueue.h" #include "asm/uaccess.h" #include "asm/pgtable.h" -#include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index 82ecf904b09..6ab1539108e 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -7,7 +7,6 @@ #include "linux/bootmem.h" #include "linux/initrd.h" #include "asm/types.h" -#include "user_util.h" #include "kern_util.h" #include "initrd.h" #include "init.h" diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index dbf2f5bc842..a1e8c460b75 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -25,7 +25,6 @@ #include "asm/system.h" #include "asm/errno.h" #include "asm/uaccess.h" -#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "irq_kern.h" diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 288b4ee2041..7b3e53fb807 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -17,7 +17,6 @@ #include "asm/tlbflush.h" #include "kern_util.h" #include "as-layout.h" -#include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 3a13d41c28d..5e93bbf6e48 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -13,7 +13,6 @@ #include "asm/page.h" #include "asm/fixmap.h" #include "asm/pgalloc.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "kern.h" diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index f92f06c35db..df1ad3ba130 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -14,7 +14,6 @@ #include "asm/pgtable.h" #include "kern_util.h" #include "as-layout.h" -#include "user_util.h" #include "mode_kern.h" #include "mem.h" #include "mem_user.h" diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index e4208386e7a..90c9ffafc65 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,7 +32,6 @@ #include "asm/tlbflush.h" #include "asm/uaccess.h" #include "asm/user.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "kern.h" diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index f602623644a..7e4305a1fd3 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -6,7 +6,6 @@ #include "linux/module.h" #include "linux/sched.h" #include "asm/smp.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "os.h" diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index 3c798cdde55..c4020c3d785 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -17,7 +17,6 @@ #include "asm/signal.h" #include "asm/uaccess.h" #include "asm/unistd.h" -#include "user_util.h" #include "asm/ucontext.h" #include "kern_util.h" #include "signal_kern.h" diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 9c2a7d8c56f..ef36facd8fe 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -16,7 +16,6 @@ #include "as-layout.h" #include "skas.h" #include "os.h" -#include "user_util.h" #include "tlb.h" #include "kern.h" #include "mode.h" diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index 27eb29ce666..304a5b0695a 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -10,7 +10,6 @@ #include "asm/page.h" #include "asm/pgtable.h" #include "asm/mmu.h" -#include "user_util.h" #include "mem_user.h" #include "mem.h" #include "skas.h" diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 759b0705316..62dd093cbcd 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); #include "asm/smp.h" #include "asm/processor.h" #include "asm/spinlock.h" -#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "irq_user.h" diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 2828c528322..237c4eab7cf 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -18,7 +18,6 @@ #include "asm/mman.h" #include "asm/uaccess.h" #include "kern_util.h" -#include "user_util.h" #include "sysdep/syscalls.h" #include "mode_kern.h" #include "choose-mode.h" diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index f9e02b31a97..93263571d81 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c @@ -10,7 +10,6 @@ #include "asm/page.h" #include "asm/processor.h" #include "sysrq.h" -#include "user_util.h" /* Catch non-i386 SUBARCH's. */ #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index b1f8b075241..9fd80ee3eef 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -18,7 +18,6 @@ #include "asm/param.h" #include "asm/current.h" #include "kern_util.h" -#include "user_util.h" #include "mode.h" #include "os.h" diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index b8b3cff0668..e40f3352bd2 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -10,7 +10,6 @@ #include "choose-mode.h" #include "mode_kern.h" #include "as-layout.h" -#include "user_util.h" #include "tlb.h" #include "mem.h" #include "mem_user.h" diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 552bcfc7c08..2de81d4d9b5 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -18,7 +18,6 @@ #include "asm/current.h" #include "asm/irq.h" #include "sysdep/sigcontext.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "arch.h" diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c index ad66df17d9d..98e21743e60 100644 --- a/arch/um/kernel/tt/exec_kern.c +++ b/arch/um/kernel/tt/exec_kern.c @@ -10,7 +10,6 @@ #include "asm/uaccess.h" #include "asm/pgalloc.h" #include "asm/tlbflush.h" -#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "mem_user.h" diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c index a92c02ff2ce..7b5f2181cf5 100644 --- a/arch/um/kernel/tt/exec_user.c +++ b/arch/um/kernel/tt/exec_user.c @@ -10,7 +10,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "ptrace_user.h" diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c index d284f69f04e..030e4658f36 100644 --- a/arch/um/kernel/tt/gdb.c +++ b/arch/um/kernel/tt/gdb.c @@ -17,7 +17,6 @@ #include "user.h" #include "debug.h" #include "kern_util.h" -#include "user_util.h" #include "tt.h" #include "sysdep/thread.h" #include "os.h" diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c index 4d1929dfa28..d0c3c4975f2 100644 --- a/arch/um/kernel/tt/mem.c +++ b/arch/um/kernel/tt/mem.c @@ -8,7 +8,6 @@ #include "asm/uaccess.h" #include "mem_user.h" #include "kern_util.h" -#include "user_util.h" #include "kern.h" #include "tt.h" diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c index 03e58989538..9774f6360c3 100644 --- a/arch/um/kernel/tt/mem_user.c +++ b/arch/um/kernel/tt/mem_user.c @@ -11,7 +11,6 @@ #include #include "tt.h" #include "mem_user.h" -#include "user_util.h" #include "os.h" 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 1e86f0bfef7..8029f72afaa 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -14,7 +14,6 @@ #include "asm/tlbflush.h" #include "irq_user.h" #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "kern.h" #include "sigcontext.h" diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c index 58800c50b10..c88e7b5d8a7 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 #include "sysdep.h" #include "wait.h" -#include "user_util.h" #include "user.h" #include "os.h" #include "tempfile.h" diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c index 03774427d46..4b4f6179b21 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 #include "ptproxy.h" #include "debug.h" -#include "user_util.h" #include "kern_util.h" #include "ptrace_user.h" #include "tt.h" diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c index 99f178319d0..e0e1ab0588a 100644 --- a/arch/um/kernel/tt/ptproxy/sysdep.c +++ b/arch/um/kernel/tt/ptproxy/sysdep.c @@ -13,7 +13,6 @@ terms and conditions. #include #include #include "ptrace_user.h" -#include "user_util.h" #include "user.h" #include "os.h" diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c index 12f6319d8d7..bdd4af4b65f 100644 --- a/arch/um/kernel/tt/ptproxy/wait.c +++ b/arch/um/kernel/tt/ptproxy/wait.c @@ -13,7 +13,6 @@ terms and conditions. #include "ptproxy.h" #include "sysdep.h" #include "wait.h" -#include "user_util.h" #include "ptrace_user.h" #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c index 902987bf379..f52b47aff1d 100644 --- a/arch/um/kernel/tt/syscall_user.c +++ b/arch/um/kernel/tt/syscall_user.c @@ -11,7 +11,6 @@ #include "sigcontext.h" #include "ptrace_user.h" #include "task.h" -#include "user_util.h" #include "kern_util.h" #include "syscall.h" #include "tt.h" diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c index ae6217c8613..7caa24fe05d 100644 --- a/arch/um/kernel/tt/tlb.c +++ b/arch/um/kernel/tt/tlb.c @@ -12,7 +12,6 @@ #include "asm/pgtable.h" #include "asm/uaccess.h" #include "asm/tlbflush.h" -#include "user_util.h" #include "mem_user.h" #include "os.h" #include "tlb.h" diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index b9195355075..c23588393f6 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -19,7 +19,6 @@ #include "sigcontext.h" #include "sysdep/sigcontext.h" #include "os.h" -#include "user_util.h" #include "mem_user.h" #include "process.h" #include "kern_util.h" diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index b5d9d64d91e..3032eb5e246 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c @@ -8,7 +8,6 @@ #include #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" -#include "user_util.h" #include "kern_util.h" #include "task.h" #include "tt.h" diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c index ed1abcf4d05..0e5c82c5e5b 100644 --- a/arch/um/kernel/tt/uaccess_user.c +++ b/arch/um/kernel/tt/uaccess_user.c @@ -5,7 +5,6 @@ */ #include -#include "user_util.h" #include "uml_uaccess.h" #include "task.h" #include "kern_util.h" diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 20684c04d5d..cfa35763405 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -26,7 +26,6 @@ #include "asm/setup.h" #include "ubd_user.h" #include "asm/current.h" -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "arch.h" diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 2cc2d3ea2e6..4e38ccf3512 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -16,7 +16,6 @@ #include #include "user.h" #include "kern_util.h" -#include "user_util.h" #include "net_user.h" #include "etap.h" #include "os.h" diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 506ef09d83a..11a9779dc9f 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -18,7 +18,6 @@ #include "net_user.h" #include "tuntap.h" #include "kern_util.h" -#include "user_util.h" #include "user.h" #include "os.h" diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 371b4335f46..4a9510c6762 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -18,7 +18,6 @@ #include "os.h" #include "user.h" #include "kern_util.h" -#include "user_util.h" static void copy_stat(struct uml_stat *dst, struct stat64 *src) { diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index a375cc138c2..f35220c7204 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -13,7 +13,6 @@ #include #include "user.h" #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index d1b61d474e0..a633fa8e0a9 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -11,7 +11,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "process.h" diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 25261d6c7bf..4b6e122ff17 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -13,7 +13,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "mem_user.h" diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index f1ea169db85..dcaca0e190d 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -11,7 +11,6 @@ #include #include "kern_util.h" #include "user.h" -#include "user_util.h" #include "mem_user.h" #include "init.h" #include "os.h" diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 76bdd671241..697828220af 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -14,7 +14,6 @@ #include "ptrace_user.h" #include "os.h" #include "user.h" -#include "user_util.h" #include "process.h" #include "irq_user.h" #include "kern_util.h" diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index c61d01bf46e..f77ce3d6f7c 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -17,7 +17,6 @@ #include "init.h" #include "user.h" #include "kern_util.h" -#include "user_util.h" #include "sigio.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 266768629fe..48d49341530 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -11,7 +11,6 @@ #include #include #include -#include "user_util.h" #include "user.h" #include "signal_kern.h" #include "sysdep/sigcontext.h" diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 9383e8751ae..470ec531aa5 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -17,7 +17,6 @@ #include "os.h" #include "proc_mm.h" #include "ptrace_user.h" -#include "user_util.h" #include "kern_util.h" #include "task.h" #include "registers.h" diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 0564422c155..6554ff53012 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -18,7 +18,6 @@ #include #include "user.h" #include "sysdep/ptrace.h" -#include "user_util.h" #include "kern_util.h" #include "skas.h" #include "stub-data.h" diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 19ff04bdec9..f104427d2ca 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -5,7 +5,6 @@ #include #include -#include "user_util.h" #include "kern_util.h" #include "as-layout.h" #include "task.h" diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 1540f21d699..3380a13986e 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -21,7 +21,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "signal_kern.h" diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index 8ba13248297..32ed41ec1a3 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -6,7 +6,6 @@ #include "sysdep/tls.h" #include "user.h" -#include "user_util.h" /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 2115b8beb54..5de169b168f 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -10,7 +10,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "process.h" diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index d221214d2ed..295da657931 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c @@ -6,7 +6,6 @@ #include #include #include "kern_util.h" -#include "user_util.h" #include "os.h" #include "mode.h" #include "longjmp.h" diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c index 3dc3a02d626..00e14f446f1 100644 --- a/arch/um/os-Linux/tt.c +++ b/arch/um/os-Linux/tt.c @@ -18,7 +18,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "signal_kern.h" diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 125854a2aa2..0e771bb04dd 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -21,7 +21,6 @@ #include #include #include -#include "user_util.h" #include "kern_util.h" #include "user.h" #include "mem_user.h" diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index cae0af14903..0393e44813e 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -13,7 +13,6 @@ #include "sysdep/ptrace.h" #include "task.h" #include "os.h" -#include "user_util.h" #define MAXTOKEN 64 diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 95dd309ff69..40ff0c831bd 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c @@ -15,7 +15,6 @@ #include "user.h" #include "os.h" #include "uml-config.h" -#include "user_util.h" int ptrace_getregs(long pid, unsigned long *regs_out) { diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c index 5d430fc994a..4bdc15c89ed 100644 --- a/arch/um/sys-ppc/sigcontext.c +++ b/arch/um/sys-ppc/sigcontext.c @@ -1,7 +1,6 @@ #include "asm/ptrace.h" #include "asm/sigcontext.h" #include "sysdep/ptrace.h" -#include "user_util.h" /* * Overrides for Emacs so that we follow Linus's tabbing style. -- cgit v1.2.3 From 36e454630473caa178bcbc4982ed6a68cf002e95 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:11 -0700 Subject: uml: add missing __init declarations The build started finding calls from non-init to init functions. These are just cases of init functions not being properly marked, so this patch fixes that. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/mem.c | 2 +- arch/um/os-Linux/main.c | 2 +- arch/um/os-Linux/mem.c | 9 +++++---- arch/um/os-Linux/process.c | 5 +++-- arch/um/os-Linux/start_up.c | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 5e93bbf6e48..72ff85693a3 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -216,7 +216,7 @@ static void __init fixaddr_user_init( void) #endif } -void paging_init(void) +void __init paging_init(void) { unsigned long zones_size[MAX_NR_ZONES], vaddr; int i; diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 4b6e122ff17..ea9a23696f3 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -120,7 +120,7 @@ extern int uml_exitcode; extern void scan_elf_aux( char **envp); -int main(int argc, char **argv, char **envp) +int __init main(int argc, char **argv, char **envp) { char **new_argv; int ret, i, err; diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index dcaca0e190d..77d16023c28 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -164,7 +164,8 @@ found: * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). * So it isn't 'static' yet. */ -int make_tempfile(const char *template, char **out_tempname, int do_unlink) +int __init make_tempfile(const char *template, char **out_tempname, + int do_unlink) { char *tempname; int fd; @@ -205,7 +206,7 @@ out: * This proc is used in start_up.c * So it isn't 'static'. */ -int create_tmp_file(unsigned long long len) +int __init create_tmp_file(unsigned long long len) { int fd, err; char zero; @@ -241,7 +242,7 @@ int create_tmp_file(unsigned long long len) return fd; } -int create_mem_file(unsigned long long len) +int __init create_mem_file(unsigned long long len) { int err, fd; @@ -256,7 +257,7 @@ int create_mem_file(unsigned long long len) } -void check_tmpexec(void) +void __init check_tmpexec(void) { void *addr; int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 697828220af..2babea30345 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -21,6 +21,7 @@ #include "skas_ptrace.h" #include "kern_constants.h" #include "uml-config.h" +#include "init.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -192,7 +193,7 @@ int os_unmap_memory(void *addr, int len) #define MADV_REMOVE KERNEL_MADV_REMOVE #endif -int os_drop_memory(void *addr, int length) +int __init os_drop_memory(void *addr, int length) { int err; @@ -202,7 +203,7 @@ int os_drop_memory(void *addr, int length) return err; } -int can_drop_memory(void) +int __init can_drop_memory(void) { void *addr; int fd, ok = 0; diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 3380a13986e..79471f85eb8 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -329,7 +329,7 @@ static void __init check_ptrace(void) extern void check_tmpexec(void); -static void check_coredump_limit(void) +static void __init check_coredump_limit(void) { struct rlimit lim; int err = getrlimit(RLIMIT_CORE, &lim); @@ -350,7 +350,7 @@ static void check_coredump_limit(void) else printf("%lu\n", lim.rlim_max); } -void os_early_checks(void) +void __init os_early_checks(void) { /* Print out the core dump limits early */ check_coredump_limit(); -- cgit v1.2.3 From 85ee2ce8ae7d6716beffc84451dd65cd217dbf7a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 6 May 2007 14:51:12 -0700 Subject: remove unused header file: arch/um/kernel/tt/include/mode_kern-tt.h Signed-off-by: Robert P. J. Day Acked-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tt/include/mode_kern-tt.h | 52 -------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 arch/um/kernel/tt/include/mode_kern-tt.h (limited to 'arch/um') 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 2a35b15c5fe..00000000000 --- a/arch/um/kernel/tt/include/mode_kern-tt.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TT_MODE_KERN_H__ -#define __TT_MODE_KERN_H__ - -#include "linux/sched.h" -#include "asm/page.h" -#include "asm/ptrace.h" -#include "asm/uaccess.h" - -extern void switch_to_tt(void *prev, void *next); -extern void flush_thread_tt(void); -extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, - unsigned long esp); -extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct *p, - struct pt_regs *regs); -extern void release_thread_tt(struct task_struct *task); -extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); -extern void init_idle_tt(void); -extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); -extern void flush_tlb_kernel_vm_tt(void); -extern void __flush_tlb_one_tt(unsigned long addr); -extern void flush_tlb_range_tt(struct vm_area_struct *vma, - unsigned long start, unsigned long end); -extern void flush_tlb_mm_tt(struct mm_struct *mm); -extern void force_flush_all_tt(void); -extern long execute_syscall_tt(void *r); -extern void before_mem_tt(unsigned long brk_start); -extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, - unsigned long *task_size_out); -extern int start_uml_tt(void); -extern int external_pid_tt(struct task_struct *task); -extern int thread_pid_tt(struct task_struct *task); - -#define kmem_end_tt (host_task_size - ABOVE_KMEM) - -#endif - -/* - * 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: - */ -- cgit v1.2.3 From e024715f5f6250179a31716a898800a48cf23b39 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:13 -0700 Subject: uml: improve checking and diagnostics of ethernet MACs Improve checking and diagnostics for broadcast and multicast Ethernet MAC addresses, and distinguish between those cases in output; also make sure the device is assigned a MAC address valid only locally to avoid collisions. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 20963f106c3..cd466e30af6 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -283,7 +283,7 @@ void uml_net_user_timer_expire(unsigned long _conn) #endif } -static void setup_etheraddr(char *str, unsigned char *addr) +static void setup_etheraddr(char *str, unsigned char *addr, char *name) { char *end; int i; @@ -302,15 +302,32 @@ static void setup_etheraddr(char *str, unsigned char *addr) } str = end + 1; } - if(addr[0] & 1){ + if (is_multicast_ether_addr(addr)) { printk(KERN_ERR - "Attempt to assign a broadcast ethernet address to a " + "Attempt to assign a multicast ethernet address to a " "device disallowed\n"); goto random; } + if (!is_valid_ether_addr(addr)) { + printk(KERN_ERR + "Attempt to assign an invalid ethernet address to a " + "device disallowed\n"); + goto random; + } + if (!is_local_ether_addr(addr)) { + printk(KERN_WARNING + "Warning: attempt to assign a globally valid ethernet address to a " + "device\n"); + printk(KERN_WARNING "You should better enable the 2nd rightmost bit " + "in the first byte of the MAC, i.e. " + "%02x:%02x:%02x:%02x:%02x:%02x\n", + addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]); + } return; random: + printk(KERN_INFO + "Choosing a random ethernet address for device %s\n", name); random_ether_addr(addr); } @@ -331,6 +348,7 @@ static void eth_configure(int n, void *init, char *mac, struct net_device *dev; struct uml_net_private *lp; int save, err, size; + char name[sizeof(dev->name)]; size = transport->private_size + sizeof(struct uml_net_private) + sizeof(((struct uml_net_private *) 0)->user); @@ -344,7 +362,13 @@ static void eth_configure(int n, void *init, char *mac, INIT_LIST_HEAD(&device->list); device->index = n; - setup_etheraddr(mac, device->mac); + /* If this name ends up conflicting with an existing registered + * netdevice, that is OK, register_netdev{,ice}() will notice this + * and fail. + */ + snprintf(name, sizeof(name), "eth%d", n); + + setup_etheraddr(mac, device->mac, name); printk(KERN_INFO "Netdevice %d ", n); printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", @@ -375,11 +399,7 @@ static void eth_configure(int n, void *init, char *mac, goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); - /* If this name ends up conflicting with an existing registered - * netdevice, that is OK, register_netdev{,ice}() will notice this - * and fail. - */ - snprintf(dev->name, sizeof(dev->name), "eth%d", n); + strcpy(dev->name, name); device->dev = dev; /* -- cgit v1.2.3 From 8c8408358f19a386298744829bf67b90c129ff18 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:14 -0700 Subject: uml: Eliminate temporary buffer in eth_configure Avoid using the temporary buffer introduced by previous patch to hold the device name. Btw, avoid leaking device on an error path. Other error paths may need cleanup. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index cd466e30af6..3f5e8e63430 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -348,17 +348,24 @@ static void eth_configure(int n, void *init, char *mac, struct net_device *dev; struct uml_net_private *lp; int save, err, size; - char name[sizeof(dev->name)]; size = transport->private_size + sizeof(struct uml_net_private) + sizeof(((struct uml_net_private *) 0)->user); device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { - printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); + printk(KERN_ERR "eth_configure failed to allocate struct " + "uml_net\n"); return; } + dev = alloc_etherdev(size); + if (dev == NULL) { + printk(KERN_ERR "eth_configure: failed to allocate struct " + "net_device for eth%d\n", n); + goto out_free_device; + } + INIT_LIST_HEAD(&device->list); device->index = n; @@ -366,9 +373,9 @@ static void eth_configure(int n, void *init, char *mac, * netdevice, that is OK, register_netdev{,ice}() will notice this * and fail. */ - snprintf(name, sizeof(name), "eth%d", n); + snprintf(dev->name, sizeof(dev->name), "eth%d", n); - setup_etheraddr(mac, device->mac, name); + setup_etheraddr(mac, device->mac, dev->name); printk(KERN_INFO "Netdevice %d ", n); printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", @@ -376,11 +383,6 @@ static void eth_configure(int n, void *init, char *mac, device->mac[2], device->mac[3], device->mac[4], device->mac[5]); printk(": "); - dev = alloc_etherdev(size); - if (dev == NULL) { - printk(KERN_ERR "eth_configure: failed to allocate device\n"); - goto out_free_device; - } lp = dev->priv; /* This points to the transport private data. It's still clear, but we @@ -399,7 +401,6 @@ static void eth_configure(int n, void *init, char *mac, goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); - strcpy(dev->name, name); device->dev = dev; /* @@ -466,13 +467,13 @@ static void eth_configure(int n, void *init, char *mac, return; out_undo_user_init: - if (transport->user->init != NULL) + if (transport->user->remove != NULL) (*transport->user->remove)(&lp->user); out_unregister: platform_device_unregister(&device->pdev); out_free_netdev: free_netdev(dev); -out_free_device: ; +out_free_device: kfree(device); } -- cgit v1.2.3 From c74c69b442364125fd13259ecaa4cd2ee43b9172 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:15 -0700 Subject: uml: Replace one-element array with zero-element array To look at users I did: $ find arch/um/ include/asm-um -name '*.[ch]'|xargs grep -r 'net_kern\.h' +-l|xargs grep '\' Most users just cast user to the appropriate pointer, the remaining ones are fixed here. In net_kern.c, I'm almost sure that save trick is not needed anymore, but I've not verified it. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 14 +++----------- arch/um/include/net_kern.h | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 3f5e8e63430..b2c292a6621 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -347,10 +347,9 @@ static void eth_configure(int n, void *init, char *mac, struct uml_net *device; struct net_device *dev; struct uml_net_private *lp; - int save, err, size; + int err, size; - size = transport->private_size + sizeof(struct uml_net_private) + - sizeof(((struct uml_net_private *) 0)->user); + size = transport->private_size + sizeof(struct uml_net_private); device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { @@ -409,12 +408,6 @@ static void eth_configure(int n, void *init, char *mac, */ (*transport->kern->init)(dev, init); - /* lp.user is the first four bytes of the transport data, which - * has already been initialized. This structure assignment will - * overwrite that, so we make sure that .user gets overwritten with - * what it already has. - */ - save = lp->user[0]; *lp = ((struct uml_net_private) { .list = LIST_HEAD_INIT(lp->list), .dev = dev, @@ -428,8 +421,7 @@ static void eth_configure(int n, void *init, char *mac, .write = transport->kern->write, .add_address = transport->user->add_address, .delete_address = transport->user->delete_address, - .set_mtu = transport->user->set_mtu, - .user = { save } }); + .set_mtu = transport->user->set_mtu }); init_timer(&lp->tl); spin_lock_init(&lp->lock); diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h index 125ab42df18..9237056b910 100644 --- a/arch/um/include/net_kern.h +++ b/arch/um/include/net_kern.h @@ -40,7 +40,7 @@ struct uml_net_private { void (*add_address)(unsigned char *, unsigned char *, void *); void (*delete_address)(unsigned char *, unsigned char *, void *); int (*set_mtu)(int mtu, void *); - int user[1]; + char user[0]; }; struct net_kern_info { -- cgit v1.2.3 From 57ac895a7f22d235f637317f58a2d9ba6ec91a27 Mon Sep 17 00:00:00 2001 From: Davide Brini Date: Sun, 6 May 2007 14:51:16 -0700 Subject: uml: fix umid in xterm titles Calls lines_init() *after* xterm_title is modified to include umid. Signed-off-by: Davide Brini Signed-off-by: Jeff Dike Acked-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ssl.c | 4 ++-- arch/um/drivers/stdio_console.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 94faadc5ea1..fd09ad9e9c0 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -191,12 +191,12 @@ static int ssl_init(void) ssl_driver = register_lines(&driver, &ssl_ops, serial_lines, ARRAY_SIZE(serial_lines)); - lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts); - new_title = add_xterm_umid(opts.xterm_title); if (new_title != NULL) opts.xterm_title = new_title; + lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts); + ssl_init_done = 1; register_console(&ssl_cons); return 0; diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 90a2c5cc17d..2bb4193ac1a 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -166,12 +166,12 @@ int stdio_init(void) return -1; printk(KERN_INFO "Initialized stdio console driver\n"); - lines_init(vts, ARRAY_SIZE(vts), &opts); - new_title = add_xterm_umid(opts.xterm_title); if(new_title != NULL) opts.xterm_title = new_title; + lines_init(vts, ARRAY_SIZE(vts), &opts); + con_init_done = 1; register_console(&stdiocons); return 0; -- cgit v1.2.3 From a18ff1bde0c3da9ece3ba60e6eae2ef87f91a12e Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:19 -0700 Subject: uml: speed up exec flush_thread doesn't need to do a full page table walk in order to clear the address space. It knows what the end result needs to be, so it can call unmap directly. This results in a 10-20% speedup in an exec from bash. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/exec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c index 54b79595137..580eb646894 100644 --- a/arch/um/kernel/skas/exec.c +++ b/arch/um/kernel/skas/exec.c @@ -17,7 +17,17 @@ void flush_thread_skas(void) { - force_flush_all(); + void *data = NULL; + unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; + int ret; + + ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data); + if(ret){ + printk("flush_thread_skas - clearing address space failed, " + "err = %d\n", ret); + force_sig(SIGKILL, current); + } + switch_mm_skas(¤t->mm->context.skas.id); } -- cgit v1.2.3 From 65a58ab044308ae65ca06c50fb10be5e0e080989 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:20 -0700 Subject: uml: no locking needed in tls.c Comment the lack of locking on a couple of globals. Also fix the formatting of __setup_host_supports_tls. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/tls.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c index 643dab58572..fea8e5e15cc 100644 --- a/arch/um/sys-i386/tls.c +++ b/arch/um/sys-i386/tls.c @@ -23,9 +23,13 @@ #include "skas.h" #endif -/* If needed we can detect when it's uninitialized. */ +/* + * If needed we can detect when it's uninitialized. + * + * These are initialized in an initcall and unchanged thereafter. + */ static int host_supports_tls = -1; -int host_gdt_entry_tls_min = -1; +int host_gdt_entry_tls_min; #ifdef CONFIG_MODE_SKAS int do_set_thread_area_skas(struct user_desc *info) @@ -361,7 +365,8 @@ out: /* XXX: This part is probably common to i386 and x86-64. Don't create a common * file for now, do that when implementing x86-64 support.*/ -static int __init __setup_host_supports_tls(void) { +static int __init __setup_host_supports_tls(void) +{ check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); if (host_supports_tls) { printk(KERN_INFO "Host TLS support detected\n"); -- cgit v1.2.3 From 6e21aec3fcf6c8862b755d45c0af45acdefff976 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:21 -0700 Subject: uml: tidy process.c Clean up arch/um/kernel/process.c: - lots of return(x); -> return x; conversions - a number of the small functions are either unused, in which case they are gone, along any declarations in a header, or could be made static. - current_pid is ifdefed on CONFIG_MODE_TT and its declaration is ifdefed on both CONFIG_MODE_TT and UML_CONFIG_MODE_TT because we don't know whether it's being used in a userspace or kernel file. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/kern_util.h | 7 +-- arch/um/include/tt/uaccess-tt.h | 2 - arch/um/include/um_malloc.h | 1 - arch/um/kernel/process.c | 118 ++++++++++++---------------------------- 4 files changed, 38 insertions(+), 90 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index be850b9ec94..09810bc48e5 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -8,6 +8,7 @@ #include "sysdep/ptrace.h" #include "sysdep/faultinfo.h" +#include "uml-config.h" typedef void (*kern_hndl)(int, union uml_pt_regs *); @@ -33,7 +34,9 @@ extern int nsyscalls; UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); +#ifdef UML_CONFIG_MODE_TT extern unsigned long stack_sp(unsigned long page); +#endif extern int kernel_thread_proc(void *data); extern void syscall_segv(int sig); extern int current_pid(void); @@ -57,7 +60,6 @@ extern void add_input_request(int op, void (*proc)(int), void *arg); extern char *current_cmd(void); extern void timer_handler(int sig, union uml_pt_regs *regs); extern int set_signals(int enable); -extern void force_sigbus(void); extern int pid_to_processor_id(int pid); extern void deliver_signals(void *t); extern int next_trap_index(int max); @@ -69,7 +71,6 @@ extern void *syscall_sp(void *t); extern void syscall_trace(union uml_pt_regs *regs, int entryexit); extern int hz(void); extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); -extern int external_pid(void *t); extern void interrupt_end(void); extern void initial_thread_cb(void (*proc)(void *), void *arg); extern int debugger_signal(int status, int pid); @@ -80,7 +81,6 @@ extern int init_parent_proxy(int pid); extern int singlestepping(void *t); extern void check_stack_overflow(void *ptr); extern void relay_signal(int sig, union uml_pt_regs *regs); -extern void not_implemented(void); extern int user_context(unsigned long sp); extern void timer_irq(union uml_pt_regs *regs); extern void unprotect_stack(unsigned long stack); @@ -92,7 +92,6 @@ extern char *uml_strdup(char *string); extern void unprotect_kernel_mem(void); extern void protect_kernel_mem(void); extern void uml_cleanup(void); -extern void set_current(void *t); extern void lock_signalled_task(void *t); extern void IPI_handler(int cpu); extern int jail_setup(char *line, int *add); diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h index b19645f32f2..13a64f61fcf 100644 --- a/arch/um/include/tt/uaccess-tt.h +++ b/arch/um/include/tt/uaccess-tt.h @@ -27,8 +27,6 @@ extern unsigned long uml_physmem; #define access_ok_tt(type, addr, size) \ (is_stack(addr, size)) -extern unsigned long get_fault_addr(void); - extern int __do_copy_from_user(void *to, const void *from, int n, void **fault_addr, void **fault_catcher); extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h index 0363a9b53f8..e6d7c5aa3f4 100644 --- a/arch/um/include/um_malloc.h +++ b/arch/um/include/um_malloc.h @@ -11,7 +11,6 @@ extern void *um_kmalloc_atomic(int size); extern void kfree(const void *ptr); extern void *um_vmalloc(int size); -extern void *um_vmalloc_atomic(int size); extern void vfree(void *ptr); #endif /* __UM_MALLOC_H__ */ diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 90c9ffafc65..d6d3319b367 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -54,11 +54,9 @@ */ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; -int external_pid(void *t) +static inline int external_pid(struct task_struct *task) { - struct task_struct *task = t ? t : current; - - return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task)); + return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task); } int pid_to_processor_id(int pid) @@ -66,9 +64,10 @@ int pid_to_processor_id(int pid) int i; for(i = 0; i < ncpus; i++){ - if(cpu_tasks[i].pid == pid) return(i); + if(cpu_tasks[i].pid == pid) + return i; } - return(-1); + return -1; } void free_stack(unsigned long stack, int order) @@ -85,9 +84,9 @@ unsigned long alloc_stack(int order, int atomic) flags = GFP_ATOMIC; page = __get_free_pages(flags, order); if(page == 0) - return(0); + return 0; stack_protections(page); - return(page); + return page; } int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -100,13 +99,11 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ¤t->thread.regs, 0, NULL, NULL); if(pid < 0) panic("do_fork failed in kernel_thread, errno = %d", pid); - return(pid); + return pid; } -void set_current(void *t) +static inline void set_current(struct task_struct *task) { - struct task_struct *task = t; - cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) { external_pid(task), task }); } @@ -128,14 +125,16 @@ void *_switch_to(void *prev, void *next, void *last) prev= current; } while(current->thread.saved_task); - return(current->thread.prev_sched); + return current->thread.prev_sched; } void interrupt_end(void) { - if(need_resched()) schedule(); - if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal(); + if(need_resched()) + schedule(); + if(test_tsk_thread_flag(current, TIF_SIGPENDING)) + do_signal(); } void release_thread(struct task_struct *task) @@ -150,7 +149,7 @@ void exit_thread(void) void *get_current(void) { - return(current); + return current; } int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, @@ -188,15 +187,12 @@ void initial_thread_cb(void (*proc)(void *), void *arg) kmalloc_ok = save_kmalloc_ok; } +#ifdef CONFIG_MODE_TT unsigned long stack_sp(unsigned long page) { - return(page + PAGE_SIZE - sizeof(void *)); -} - -int current_pid(void) -{ - return(current->pid); + return page + PAGE_SIZE - sizeof(void *); } +#endif void default_idle(void) { @@ -223,7 +219,7 @@ void cpu_idle(void) int page_size(void) { - return(PAGE_SIZE); + return PAGE_SIZE; } void *um_virt_to_phys(struct task_struct *task, unsigned long addr, @@ -236,68 +232,43 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t ptent; if(task->mm == NULL) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pgd = pgd_offset(task->mm, addr); if(!pgd_present(*pgd)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pud = pud_offset(pgd, addr); if(!pud_present(*pud)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pmd = pmd_offset(pud, addr); if(!pmd_present(*pmd)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); pte = pte_offset_kernel(pmd, addr); ptent = *pte; if(!pte_present(ptent)) - return(ERR_PTR(-EINVAL)); + return ERR_PTR(-EINVAL); if(pte_out != NULL) *pte_out = ptent; - return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK)); + return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); } char *current_cmd(void) { #if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM) - return("(Unknown)"); + return "(Unknown)"; #else void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL); return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr); #endif } -void force_sigbus(void) -{ - printk(KERN_ERR "Killing pid %d because of a lack of memory\n", - current->pid); - lock_kernel(); - sigaddset(¤t->pending.signal, SIGBUS); - recalc_sigpending(); - current->flags |= PF_SIGNALED; - do_exit(SIGBUS | 0x80); -} - void dump_thread(struct pt_regs *regs, struct user *u) { } -void enable_hlt(void) -{ - panic("enable_hlt"); -} - -EXPORT_SYMBOL(enable_hlt); - -void disable_hlt(void) -{ - panic("disable_hlt"); -} - -EXPORT_SYMBOL(disable_hlt); - void *um_kmalloc(int size) { return kmalloc(size, GFP_KERNEL); @@ -313,36 +284,17 @@ void *um_vmalloc(int size) return vmalloc(size); } -void *um_vmalloc_atomic(int size) -{ - return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL); -} - int __cant_sleep(void) { return in_atomic() || irqs_disabled() || in_interrupt(); /* Is in_interrupt() really needed? */ } -unsigned long get_fault_addr(void) -{ - return((unsigned long) current->thread.fault_addr); -} - -EXPORT_SYMBOL(get_fault_addr); - -void not_implemented(void) -{ - printk(KERN_DEBUG "Something isn't implemented in here\n"); -} - -EXPORT_SYMBOL(not_implemented); - int user_context(unsigned long sp) { unsigned long stack; stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); - return(stack != (unsigned long) current_thread); + return stack != (unsigned long) current_thread; } extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; @@ -363,22 +315,22 @@ char *uml_strdup(char *string) int copy_to_user_proc(void __user *to, void *from, int size) { - return(copy_to_user(to, from, size)); + return copy_to_user(to, from, size); } int copy_from_user_proc(void *to, void __user *from, int size) { - return(copy_from_user(to, from, size)); + return copy_from_user(to, from, size); } int clear_user_proc(void __user *buf, int size) { - return(clear_user(buf, size)); + return clear_user(buf, size); } int strlen_user_proc(char __user *str) { - return(strlen_user(str)); + return strlen_user(str); } int smp_sigio_handler(void) @@ -387,14 +339,14 @@ int smp_sigio_handler(void) int cpu = current_thread->cpu; IPI_handler(cpu); if(cpu != 0) - return(1); + return 1; #endif - return(0); + return 0; } int cpu(void) { - return(current_thread->cpu); + return current_thread->cpu; } static atomic_t using_sysemu = ATOMIC_INIT(0); @@ -443,7 +395,7 @@ int __init make_proc_sysemu(void) if (ent == NULL) { printk(KERN_WARNING "Failed to register /proc/sysemu\n"); - return(0); + return 0; } ent->read_proc = proc_read_sysemu; -- cgit v1.2.3 From 1ffb9164f51094b7105ce9f81600b222ddf5b82c Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:22 -0700 Subject: uml: remove page_size() userspace code used to have to call the kernelspace function page_size() in order to determine the value of the kernel's PAGE_SIZE. Since this is now available directly from kern_constants.h as UM_KERN_PAGE_SIZE, page_size() can be deleted and calls changed to use the constant. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_user.c | 3 ++- arch/um/drivers/slip_user.c | 3 ++- arch/um/include/kern_util.h | 1 - arch/um/kernel/process.c | 5 ----- arch/um/os-Linux/drivers/ethertap_user.c | 7 ++++--- arch/um/os-Linux/helper.c | 5 +++-- arch/um/os-Linux/process.c | 2 +- arch/um/os-Linux/skas/process.c | 9 +++++---- arch/um/os-Linux/tt.c | 3 ++- arch/um/os-Linux/util.c | 11 ++++++----- 10 files changed, 25 insertions(+), 24 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index b63a8604637..3503cff867c 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -18,6 +18,7 @@ #include "net_user.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" int tap_open_common(void *dev, char *gate_addr) { @@ -215,7 +216,7 @@ static void change(char *dev, char *what, unsigned char *addr, sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]); - output_len = page_size(); + output_len = UM_KERN_PAGE_SIZE; output = um_kmalloc(output_len); if(output == NULL) printk("change : failed to allocate output buffer\n"); diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 9f41cece091..78f0e515da8 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -15,6 +15,7 @@ #include "slip_common.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" static int slip_user_init(void *data, void *dev) { @@ -89,7 +90,7 @@ static int slip_tramp(char **argv, int fd) goto out_close; pid = err; - output_len = page_size(); + output_len = UM_KERN_PAGE_SIZE; output = um_kmalloc(output_len); if(output == NULL){ printk("slip_tramp : failed to allocate output buffer\n"); diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 09810bc48e5..ae434a9b400 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -52,7 +52,6 @@ extern void set_tracing(void *t, int tracing); extern int is_tracing(void *task); extern int segv_syscall(void); extern void kern_finish_exec(void *task, int new_pid, unsigned long stack); -extern int page_size(void); extern unsigned long page_mask(void); extern int need_finish_fork(void); extern void free_stack(unsigned long stack, int order); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index d6d3319b367..9ac9944aa2c 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -217,11 +217,6 @@ void cpu_idle(void) CHOOSE_MODE(init_idle_tt(), init_idle_skas()); } -int page_size(void) -{ - return PAGE_SIZE; -} - void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t *pte_out) { diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 4e38ccf3512..96e12ea8172 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -20,6 +20,7 @@ #include "etap.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" #define MAX_PACKET ETH_MAX_PACKET @@ -50,10 +51,10 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, n = os_write_file(fd, &change, sizeof(change)); if(n != sizeof(change)) printk("etap_change - request failed, err = %d\n", -n); - output = um_kmalloc(page_size()); + output = um_kmalloc(UM_KERN_PAGE_SIZE); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); - read_output(fd, output, page_size()); + read_output(fd, output, UM_KERN_PAGE_SIZE); if(output != NULL){ printk("%s", output); kfree(output); @@ -159,7 +160,7 @@ static int etap_open(void *data) err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); - output_len = page_size(); + output_len = UM_KERN_PAGE_SIZE; output = um_kmalloc(output_len); read_output(control_fds[0], output, output_len); diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index f35220c7204..2184ddb9cb3 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -15,6 +15,7 @@ #include "kern_util.h" #include "os.h" #include "um_malloc.h" +#include "kern_constants.h" struct helper_data { void (*pre_exec)(void*); @@ -69,7 +70,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, goto out_close; } - sp = stack + page_size() - sizeof(void *); + sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *); data.pre_exec = pre_exec; data.pre_data = pre_data; data.argv = argv; @@ -123,7 +124,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, if (stack == 0) return -ENOMEM; - sp = stack + (page_size() << stack_order) - sizeof(void *); + sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *); pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); if (pid < 0) { err = -errno; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 2babea30345..37933d3f92b 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -244,7 +244,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) if(sig_stack != NULL){ pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER); - set_sigstack(sig_stack, pages * page_size()); + set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE); flags = SA_ONSTACK; } if(usr1_handler){ diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 6554ff53012..29fd079c30b 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -33,6 +33,7 @@ #include "uml-config.h" #include "process.h" #include "longjmp.h" +#include "kern_constants.h" int is_skas_winch(int pid, int fd, void *data) { @@ -171,7 +172,7 @@ static int userspace_tramp(void *stack) int fd; __u64 offset; fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); - addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(), + addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE, PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); if(addr == MAP_FAILED){ printk("mapping mmap stub failed, errno = %d\n", @@ -181,8 +182,8 @@ static int userspace_tramp(void *stack) if(stack != NULL){ fd = phys_mapping(to_phys(stack), &offset); - addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(), - PROT_READ | PROT_WRITE, + addr = mmap((void *) UML_CONFIG_STUB_DATA, + UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, offset); if(addr == MAP_FAILED){ printk("mapping segfault stack failed, " @@ -198,7 +199,7 @@ static int userspace_tramp(void *stack) (unsigned long) stub_segv_handler - (unsigned long) &__syscall_stub_start; - set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); + set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE); sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGWINCH); diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c index 00e14f446f1..bcf9359c4e9 100644 --- a/arch/um/os-Linux/tt.c +++ b/arch/um/os-Linux/tt.c @@ -31,6 +31,7 @@ #include "choose-mode.h" #include "mode.h" #include "tempfile.h" +#include "kern_constants.h" int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, int must_succeed) @@ -142,7 +143,7 @@ int outer_tramp(void *arg) int sig = sigkill; t = arg; - t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, + t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2, t->flags, t->tramp_data); if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); kill(os_getpid(), sig); diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 0e771bb04dd..48bc4927b99 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -29,28 +29,29 @@ #include "uml-config.h" #include "os.h" #include "longjmp.h" +#include "kern_constants.h" void stack_protections(unsigned long address) { int prot = PROT_READ | PROT_WRITE | PROT_EXEC; - if(mprotect((void *) address, page_size(), prot) < 0) + if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0) panic("protecting stack failed, errno = %d", errno); } void task_protections(unsigned long address) { - unsigned long guard = address + page_size(); - unsigned long stack = guard + page_size(); + unsigned long guard = address + UM_KERN_PAGE_SIZE; + unsigned long stack = guard + UM_KERN_PAGE_SIZE; int prot = 0, pages; #ifdef notdef - if(mprotect((void *) stack, page_size(), prot) < 0) + if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0) panic("protecting guard page failed, errno = %d", errno); #endif pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; prot = PROT_READ | PROT_WRITE | PROT_EXEC; - if(mprotect((void *) stack, pages * page_size(), prot) < 0) + if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0) panic("protecting stack failed, errno = %d", errno); } -- cgit v1.2.3 From ccdddb57874522e6b267204f9c5e94ba7d9d66b0 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:23 -0700 Subject: uml: kernel_thread shouldn't panic kernel_thread() should just return an error value on do_fork failure, not panic. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 9ac9944aa2c..8d2c5496532 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -97,8 +97,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) current->thread.request.u.thread.arg = arg; pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, ¤t->thread.regs, 0, NULL, NULL); - if(pid < 0) - panic("do_fork failed in kernel_thread, errno = %d", pid); return pid; } -- cgit v1.2.3 From 5d86456d3852cb95a38d2b23fe01cede54984ba5 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:24 -0700 Subject: uml: tidy fault code Tidying in preparation for the segfault register dumping patch which follows. void * pointers are changed to union uml_pt_regs *. This makes the types match reality, except in arch_fixup, which is changed to operate on a union uml_pt_regs. This fixes a bug in the call from segv_handler, which passes a union uml_pt_regs, to segv, which expects to pass a struct sigcontext to arch_fixup. Whitespace and other style fixes. There's also a errno printk fix. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/arch.h | 2 +- arch/um/include/kern_util.h | 2 +- arch/um/kernel/trap.c | 35 ++++++++++++++++++----------------- arch/um/os-Linux/skas/trap.c | 17 ++++++++--------- arch/um/sys-i386/fault.c | 18 ++---------------- arch/um/sys-i386/signal.c | 41 +++++++++++++++-------------------------- arch/um/sys-x86_64/fault.c | 30 +++++++++++++++++------------- arch/um/sys-x86_64/signal.c | 2 +- 8 files changed, 63 insertions(+), 84 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h index 8e11dd7c1ad..10ad52daa8c 100644 --- a/arch/um/include/arch.h +++ b/arch/um/include/arch.h @@ -9,7 +9,7 @@ #include "sysdep/ptrace.h" extern void arch_check_bugs(void); -extern int arch_fixup(unsigned long address, void *sc_ptr); +extern int arch_fixup(unsigned long address, union uml_pt_regs *regs); extern int arch_handle_signal(int sig, union uml_pt_regs *regs); #endif diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index ae434a9b400..092a2841556 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -44,7 +44,7 @@ extern unsigned long alloc_stack(int order, int atomic); extern int do_signal(void); extern int is_stack_fault(unsigned long sp); extern unsigned long segv(struct faultinfo fi, unsigned long ip, - int is_user, void *sc); + int is_user, union uml_pt_regs *regs); extern int handle_page_fault(unsigned long address, unsigned long ip, int is_write, int is_user, int *code_out); extern void syscall_ready(void); diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 2de81d4d9b5..c3e62e634c0 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -72,8 +72,8 @@ good_area: goto out; /* Don't require VM_READ|VM_EXEC for write faults! */ - if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) - goto out; + if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) + goto out; do { survive: @@ -157,18 +157,19 @@ static void segv_handler(int sig, union uml_pt_regs *regs) * the info in the regs. A pointer to the info then would * give us bad data! */ -unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) +unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, + union uml_pt_regs *regs) { struct siginfo si; void *catcher; int err; - int is_write = FAULT_WRITE(fi); - unsigned long address = FAULT_ADDRESS(fi); + int is_write = FAULT_WRITE(fi); + unsigned long address = FAULT_ADDRESS(fi); - if(!is_user && (address >= start_vm) && (address < end_vm)){ - flush_tlb_kernel_vm(); - return(0); - } + if(!is_user && (address >= start_vm) && (address < end_vm)){ + flush_tlb_kernel_vm(); + return 0; + } else if(current->mm == NULL) panic("Segfault with no mm"); @@ -183,17 +184,17 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) catcher = current->thread.fault_catcher; if(!err) - return(0); + return 0; else if(catcher != NULL){ current->thread.fault_addr = (void *) address; do_longjmp(catcher, 1); } else if(current->thread.fault_addr != NULL) panic("fault_addr set but no fault catcher"); - else if(!is_user && arch_fixup(ip, sc)) - return(0); + else if(!is_user && arch_fixup(ip, regs)) + return 0; - if(!is_user) + if(!is_user) panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", address, ip); @@ -202,7 +203,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) si.si_errno = 0; si.si_code = BUS_ADRERR; si.si_addr = (void __user *)address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi; force_sig_info(SIGBUS, &si, current); } else if (err == -ENOMEM) { printk("VM: killing process %s\n", current->comm); @@ -211,10 +212,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) BUG_ON(err != -EFAULT); si.si_signo = SIGSEGV; si.si_addr = (void __user *) address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi; force_sig_info(SIGSEGV, &si, current); } - return(0); + return 0; } void relay_signal(int sig, union uml_pt_regs *regs) @@ -229,7 +230,7 @@ void relay_signal(int sig, union uml_pt_regs *regs) panic("Kernel mode signal %d", sig); } - current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); + current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); force_sig(sig, current); } diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index f104427d2ca..6a20d08caf9 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -18,10 +18,9 @@ void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; - struct skas_regs *r; + union uml_pt_regs *r; void (*handler)(int, union uml_pt_regs *); - int save_errno = errno; - int save_user; + int save_user, save_errno = errno; /* This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, @@ -31,13 +30,13 @@ void sig_handler_common_skas(int sig, void *sc_ptr) if(sig == SIGSEGV) change_sig(SIGSEGV, 1); - r = &TASK_REGS(get_current())->skas; - save_user = r->is_user; - r->is_user = 0; + r = TASK_REGS(get_current()); + save_user = r->skas.is_user; + r->skas.is_user = 0; if ( sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGTRAP ) { - GET_FAULTINFO_FROM_SC(r->faultinfo, sc); + GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc); } change_sig(SIGUSR1, 1); @@ -49,10 +48,10 @@ void sig_handler_common_skas(int sig, void *sc_ptr) sig != SIGVTALRM && sig != SIGALRM) unblock_signals(); - handler(sig, (union uml_pt_regs *) r); + handler(sig, r); errno = save_errno; - r->is_user = save_user; + r->skas.is_user = save_user; } extern int ptrace_faultinfo; diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c index d0bbcdfdb53..745b4fd49e9 100644 --- a/arch/um/sys-i386/fault.c +++ b/arch/um/sys-i386/fault.c @@ -3,9 +3,7 @@ * Licensed under the GPL */ -#include #include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" /* These two are from asm-um/uaccess.h and linux/module.h, check them. */ struct exception_table_entry @@ -17,26 +15,14 @@ struct exception_table_entry const struct exception_table_entry *search_exception_tables(unsigned long add); /* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup(unsigned long address, void *sc_ptr) +int arch_fixup(unsigned long address, union uml_pt_regs *regs) { - struct sigcontext *sc = sc_ptr; const struct exception_table_entry *fixup; fixup = search_exception_tables(address); if(fixup != 0){ - sc->eip = fixup->fixup; + UPT_IP(regs) = fixup->fixup; return(1); } return(0); } - -/* - * 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: - */ diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 3f6acd66771..42ecf8e8ad0 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -28,7 +28,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, err = copy_from_user(&sc, from, sizeof(sc)); err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); if(err) - return(err); + return err; REGS_GS(regs->regs.skas.regs) = sc.gs; REGS_FS(regs->regs.skas.regs) = sc.fs; @@ -50,11 +50,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, err = restore_fp_registers(userspace_pid[0], fpregs); if(err < 0){ printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " - "errno = %d\n", err); - return(1); + "errno = %d\n", -err); + return err; } - return(0); + return 0; } int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, @@ -90,16 +90,16 @@ int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *t if(err < 0){ printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, " "errno = %d\n", err); - return(1); + return 1; } to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); sc.fpstate = to_fp; if(err) - return(err); + return err; - return(copy_to_user(to, &sc, sizeof(sc)) || - copy_to_user(to_fp, fpregs, sizeof(fpregs))); + return copy_to_user(to, &sc, sizeof(sc)) || + copy_to_user(to_fp, fpregs, sizeof(fpregs)); } #endif @@ -129,7 +129,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, to->fpstate = to_fp; if(to_fp != NULL) err |= copy_from_user(to_fp, from_fp, fpsize); - return(err); + return err; } int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, @@ -164,15 +164,15 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, sizeof(struct _fpstate)), copy_sc_from_user_skas(to, from)); - return(ret); + return ret; } static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, struct pt_regs *from, unsigned long sp) { - return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), + return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), sizeof(*fp), sp), - copy_sc_to_user_skas(to, fp, from, sp))); + copy_sc_to_user_skas(to, fp, from, sp)); } static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, @@ -185,7 +185,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __u err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); - return(err); + return err; } struct sigframe @@ -359,7 +359,7 @@ long sys_sigreturn(struct pt_regs regs) /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); + return PT_REGS_SYSCALL_RET(¤t->thread.regs); segfault: force_sig(SIGSEGV, current); @@ -389,20 +389,9 @@ long sys_rt_sigreturn(struct pt_regs regs) /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); + return PT_REGS_SYSCALL_RET(¤t->thread.regs); segfault: force_sig(SIGSEGV, current); return 0; } - -/* - * 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: - */ diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c index cee1513c5c3..4636b1465b6 100644 --- a/arch/um/sys-x86_64/fault.c +++ b/arch/um/sys-x86_64/fault.c @@ -4,20 +4,24 @@ * Licensed under the GPL */ -#include "user.h" +#include "sysdep/ptrace.h" -int arch_fixup(unsigned long address, void *sc_ptr) +/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ +struct exception_table_entry { - /* XXX search_exception_tables() */ + unsigned long insn; + unsigned long fixup; +}; + +const struct exception_table_entry *search_exception_tables(unsigned long add); +int arch_fixup(unsigned long address, union uml_pt_regs *regs) +{ + const struct exception_table_entry *fixup; + + fixup = search_exception_tables(address); + if(fixup != 0){ + UPT_IP(regs) = fixup->fixup; + return(1); + } return(0); } - -/* 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: - */ diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index af2f017617b..06800621359 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -51,7 +51,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, #undef GETREG - return(err); + return err; } int copy_sc_to_user_skas(struct sigcontext __user *to, -- cgit v1.2.3 From 377fad3acbb7e94ab9942a74e0d9ede8eeb2f039 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:25 -0700 Subject: uml: kernel segfaults should dump proper registers If there's a segfault inside the kernel, we want a dump of the registers at the point of the segfault, not the registers at the point of calling panic or the last userspace registers. sig_handler_common_skas now uses a static register set in the case of a SIGSEGV to avoid messing up the process registers if the segfault turns out to be non-fatal. The architecture sigcontext-to-pt_regs copying code was repurposed to copy data out of the SEGV stack frame. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/common-offsets.h | 2 ++ arch/um/include/kern_util.h | 2 ++ arch/um/kernel/trap.c | 10 +++++++--- arch/um/os-Linux/skas/trap.c | 15 +++++++++++++-- arch/um/sys-i386/signal.c | 41 +++++++++++++++++++++++----------------- arch/um/sys-x86_64/signal.c | 30 +++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 22 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h index 461175f8b1d..5593a802708 100644 --- a/arch/um/include/common-offsets.h +++ b/arch/um/include/common-offsets.h @@ -24,5 +24,7 @@ DEFINE(UM_ELF_CLASS, ELF_CLASS); DEFINE(UM_ELFCLASS32, ELFCLASS32); DEFINE(UM_ELFCLASS64, ELFCLASS64); +DEFINE(UM_NR_CPUS, NR_CPUS); + /* For crypto assembler code. */ DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 092a2841556..50a49691e0e 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -115,4 +115,6 @@ extern void time_init_kern(void); extern int __cant_sleep(void); extern void sigio_handler(int sig, union uml_pt_regs *regs); +extern void copy_sc(union uml_pt_regs *regs, void *from); + #endif diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index c3e62e634c0..0c467fa0887 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -170,8 +170,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, flush_tlb_kernel_vm(); return 0; } - else if(current->mm == NULL) - panic("Segfault with no mm"); + else if(current->mm == NULL) { + show_regs(container_of(regs, struct pt_regs, regs)); + panic("Segfault with no mm"); + } if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); @@ -194,9 +196,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, else if(!is_user && arch_fixup(ip, regs)) return 0; - if(!is_user) + if(!is_user) { + show_regs(container_of(regs, struct pt_regs, regs)); panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", address, ip); + } if (err == -EACCES) { si.si_signo = SIGBUS; diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 6a20d08caf9..5110eff51b9 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -15,6 +15,8 @@ #include "sysdep/ptrace_user.h" #include "os.h" +static union uml_pt_regs ksig_regs[UM_NR_CPUS]; + void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; @@ -27,10 +29,19 @@ void sig_handler_common_skas(int sig, void *sc_ptr) * the process will die. * XXX Figure out why this is better than SA_NODEFER */ - if(sig == SIGSEGV) + if(sig == SIGSEGV) { change_sig(SIGSEGV, 1); + /* For segfaults, we want the data from the + * sigcontext. In this case, we don't want to mangle + * the process registers, so use a static set of + * registers. For other signals, the process + * registers are OK. + */ + r = &ksig_regs[cpu()]; + copy_sc(r, sc_ptr); + } + else r = TASK_REGS(get_current()); - r = TASK_REGS(get_current()); save_user = r->skas.is_user; r->skas.is_user = 0; if ( sig == SIGFPE || sig == SIGSEGV || diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 42ecf8e8ad0..1cbf95f6858 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -18,6 +18,28 @@ #include "skas.h" +void copy_sc(union uml_pt_regs *regs, void *from) +{ + struct sigcontext *sc = from; + + REGS_GS(regs->skas.regs) = sc->gs; + REGS_FS(regs->skas.regs) = sc->fs; + REGS_ES(regs->skas.regs) = sc->es; + REGS_DS(regs->skas.regs) = sc->ds; + REGS_EDI(regs->skas.regs) = sc->edi; + REGS_ESI(regs->skas.regs) = sc->esi; + REGS_EBP(regs->skas.regs) = sc->ebp; + REGS_SP(regs->skas.regs) = sc->esp; + REGS_EBX(regs->skas.regs) = sc->ebx; + REGS_EDX(regs->skas.regs) = sc->edx; + REGS_ECX(regs->skas.regs) = sc->ecx; + REGS_EAX(regs->skas.regs) = sc->eax; + REGS_IP(regs->skas.regs) = sc->eip; + REGS_CS(regs->skas.regs) = sc->cs; + REGS_EFLAGS(regs->skas.regs) = sc->eflags; + REGS_SS(regs->skas.regs) = sc->ss; +} + static int copy_sc_from_user_skas(struct pt_regs *regs, struct sigcontext __user *from) { @@ -30,25 +52,10 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, if(err) return err; - REGS_GS(regs->regs.skas.regs) = sc.gs; - REGS_FS(regs->regs.skas.regs) = sc.fs; - REGS_ES(regs->regs.skas.regs) = sc.es; - REGS_DS(regs->regs.skas.regs) = sc.ds; - REGS_EDI(regs->regs.skas.regs) = sc.edi; - REGS_ESI(regs->regs.skas.regs) = sc.esi; - REGS_EBP(regs->regs.skas.regs) = sc.ebp; - REGS_SP(regs->regs.skas.regs) = sc.esp; - REGS_EBX(regs->regs.skas.regs) = sc.ebx; - REGS_EDX(regs->regs.skas.regs) = sc.edx; - REGS_ECX(regs->regs.skas.regs) = sc.ecx; - REGS_EAX(regs->regs.skas.regs) = sc.eax; - REGS_IP(regs->regs.skas.regs) = sc.eip; - REGS_CS(regs->regs.skas.regs) = sc.cs; - REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; - REGS_SS(regs->regs.skas.regs) = sc.ss; + copy_sc(®s->regs, &sc); err = restore_fp_registers(userspace_pid[0], fpregs); - if(err < 0){ + if(err < 0) { printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " "errno = %d\n", -err); return err; diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 06800621359..fe8ec04d35b 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -20,6 +20,36 @@ #include "skas.h" +void copy_sc(union uml_pt_regs *regs, void *from) +{ + struct sigcontext *sc = from; + +#define GETREG(regs, regno, sc, regname) \ + (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname + + GETREG(regs, R8, sc, r8); + GETREG(regs, R9, sc, r9); + GETREG(regs, R10, sc, r10); + GETREG(regs, R11, sc, r11); + GETREG(regs, R12, sc, r12); + GETREG(regs, R13, sc, r13); + GETREG(regs, R14, sc, r14); + GETREG(regs, R15, sc, r15); + GETREG(regs, RDI, sc, rdi); + GETREG(regs, RSI, sc, rsi); + GETREG(regs, RBP, sc, rbp); + GETREG(regs, RBX, sc, rbx); + GETREG(regs, RDX, sc, rdx); + GETREG(regs, RAX, sc, rax); + GETREG(regs, RCX, sc, rcx); + GETREG(regs, RSP, sc, rsp); + GETREG(regs, RIP, sc, rip); + GETREG(regs, EFLAGS, sc, eflags); + GETREG(regs, CS, sc, cs); + +#undef GETREG +} + static int copy_sc_from_user_skas(struct pt_regs *regs, struct sigcontext __user *from) { -- cgit v1.2.3 From 1d1497e1f9ffe2f7198c916abd112226a7a503f2 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:26 -0700 Subject: uml: comment early boot locking Commentary about missing locking. Also got rid of uml_start because it was pointless. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/um_arch.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index cfa35763405..9bf31533a8f 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -44,7 +44,7 @@ #define DEFAULT_COMMAND_LINE "root=98:0" -/* Changed in linux_main and setup_arch, which run before SMP is started */ +/* Changed in add_arg and setup_arch, which run before SMP is started */ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; static void __init add_arg(char *arg) @@ -58,7 +58,12 @@ static void __init add_arg(char *arg) strcat(command_line, arg); } -struct cpuinfo_um boot_cpu_data = { +/* + * These fields are initialized at boot time and not changed. + * XXX This structure is used only in the non-SMP case. Maybe this + * should be moved to smp.c. + */ +struct cpuinfo_um boot_cpu_data = { .loops_per_jiffy = 0, .ipi_pipe = { -1, -1 } }; @@ -119,14 +124,12 @@ const struct seq_operations cpuinfo_op = { /* Set in linux_main */ unsigned long host_task_size; unsigned long task_size; - -unsigned long uml_start; - -/* Set in early boot */ unsigned long uml_physmem; -unsigned long uml_reserved; +unsigned long uml_reserved; /* Also modified in mem_init */ unsigned long start_vm; unsigned long end_vm; + +/* Set in uml_ncpus_setup */ int ncpus = 1; #ifdef CONFIG_CMDLINE_ON_HOST @@ -140,6 +143,8 @@ static char *argv1_end = NULL; /* Set in early boot */ static int have_root __initdata = 0; + +/* Set in uml_mem_setup and modified in linux_main */ long long physmem_size = 32 * 1024 * 1024; void set_cmdline(char *cmd) @@ -378,7 +383,6 @@ int __init linux_main(int argc, char **argv) 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); @@ -400,7 +404,7 @@ int __init linux_main(int argc, char **argv) physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); } - uml_physmem = uml_start & PAGE_MASK; + uml_physmem = (unsigned long) &__binary_start & PAGE_MASK; /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); -- cgit v1.2.3 From d973a77bdb3ade9240173b6ed6e003a319499211 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:27 -0700 Subject: uml: irq locking commentary Locking commentary. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/irq.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch/um') diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index a1e8c460b75..8f2ed369031 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -78,6 +78,14 @@ skip: return 0; } +/* + * This list is accessed under irq_lock, except in sigio_handler, + * where it is safe from being modified. IRQ handlers won't change it - + * if an IRQ source has vanished, it will be freed by free_irqs just + * before returning from sigio_handler. That will process a separate + * list of irqs to free, with its own locking, coming back here to + * remove list elements, taking the irq_lock to do so. + */ static struct irq_fd *active_fds = NULL; static struct irq_fd **last_irq_ptr = &active_fds; @@ -243,6 +251,7 @@ void free_irq_by_fd(int fd) free_irq_by_cb(same_fd, &fd); } +/* Must be called with irq_lock held */ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) { struct irq_fd *irq; @@ -308,6 +317,12 @@ void deactivate_fd(int fd, int irqnum) ignore_sigio_fd(fd); } +/* + * Called just before shutdown in order to provide a clean exec + * environment in case the system is rebooting. No locking because + * that would cause a pointless shutdown hang if something hadn't + * released the lock. + */ int deactivate_all_fds(void) { struct irq_fd *irq; -- cgit v1.2.3 From d8839354a04181b4cc95cebf7f7622cf336bd58e Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:28 -0700 Subject: uml: delete HOST_FRAME_SIZE HOST_FRAME_SIZE isn't used any more. It has been replaced with MAX_REG_NR. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/user-offsets.c | 1 - arch/um/sys-x86_64/user-offsets.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index 447306b20ae..ee42c27abd3 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -47,7 +47,6 @@ void foo(void) OFFSET(HOST_SC_FP_ST, _fpstate, _st); OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env); - DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct)); DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct)); diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 899cebb57c3..7bb532567c4 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -57,7 +57,6 @@ void foo(void) OFFSET(HOST_SC_SS, sigcontext, ss); #endif - DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); DEFINE(HOST_XFP_SIZE, 0); DEFINE_LONGS(HOST_RBX, RBX); -- cgit v1.2.3 From 2e3f5251ac716879df6b6271f243f657c6e02e9a Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:29 -0700 Subject: uml: drivers get release methods Define release methods for the ubd and net drivers. They contain as much of the remove methods as make sense. All error checking must have already been done as well as anything else that might be holding a reference on the device kobject. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 19 +++++++++++++++---- arch/um/drivers/ubd_kern.c | 17 ++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index b2c292a6621..baac4ad5e68 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -341,6 +341,19 @@ static struct platform_driver uml_net_driver = { }; static int driver_registered; +static void net_device_release(struct device *dev) +{ + struct uml_net *device = dev->driver_data; + struct net_device *netdev = device->dev; + struct uml_net_private *lp = netdev->priv; + + if(lp->remove != NULL) + (*lp->remove)(&lp->user); + list_del(&device->list); + kfree(device); + free_netdev(netdev); +} + static void eth_configure(int n, void *init, char *mac, struct transport *transport) { @@ -396,6 +409,8 @@ static void eth_configure(int n, void *init, char *mac, } device->pdev.id = n; device->pdev.name = DRIVER_NAME; + device->pdev.dev.release = net_device_release; + device->pdev.dev.driver_data = device; if(platform_device_register(&device->pdev)) goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); @@ -689,13 +704,9 @@ static int net_remove(int n, char **error_out) lp = dev->priv; if(lp->fd > 0) return -EBUSY; - if(lp->remove != NULL) (*lp->remove)(&lp->user); unregister_netdev(dev); platform_device_unregister(&device->pdev); - list_del(&device->list); - kfree(device); - free_netdev(dev); return 0; } diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 962b8fb35f8..83189e188c3 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -622,6 +622,14 @@ static int ubd_open_dev(struct ubd *ubd_dev) return(err); } +static void ubd_device_release(struct device *dev) +{ + struct ubd *ubd_dev = dev->driver_data; + + blk_cleanup_queue(ubd_dev->queue); + *ubd_dev = ((struct ubd) DEFAULT_UBD); +} + static int ubd_disk_register(int major, u64 size, int unit, struct gendisk **disk_out) { @@ -644,6 +652,8 @@ static int ubd_disk_register(int major, u64 size, int unit, if (major == MAJOR_NR) { ubd_devs[unit].pdev.id = unit; ubd_devs[unit].pdev.name = DRIVER_NAME; + ubd_devs[unit].pdev.dev.release = ubd_device_release; + ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit]; platform_device_register(&ubd_devs[unit].pdev); disk->driverfs_dev = &ubd_devs[unit].pdev.dev; } @@ -787,7 +797,7 @@ static int ubd_id(char **str, int *start_out, int *end_out) static int ubd_remove(int n, char **error_out) { - struct gendisk *disk; + struct gendisk *disk = ubd_gendisk[n]; struct ubd *ubd_dev; int err = -ENODEV; @@ -803,7 +813,6 @@ static int ubd_remove(int n, char **error_out) if(ubd_dev->count > 0) goto out; - disk = ubd_gendisk[n]; ubd_gendisk[n] = NULL; if(disk != NULL){ del_gendisk(disk); @@ -816,10 +825,8 @@ static int ubd_remove(int n, char **error_out) fake_gendisk[n] = NULL; } - blk_cleanup_queue(ubd_dev->queue); - platform_device_unregister(&ubd_dev->pdev); - *ubd_dev = ((struct ubd) DEFAULT_UBD); err = 0; + platform_device_unregister(&ubd_dev->pdev); out: mutex_unlock(&ubd_lock); return err; -- cgit v1.2.3 From f30c2c983e09470446ee00472f9d4a927fe2e9cb Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:29 -0700 Subject: uml: dump registers on ptrace or wait failure Provide a register dump if handle_trap fails. Abstract out ptrace_dump_regs since it now has two callers. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/skas/process.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 29fd079c30b..41bf8d1e14e 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -44,6 +44,22 @@ int is_skas_winch(int pid, int fd, void *data) return(1); } +static int ptrace_dump_regs(int pid) +{ + unsigned long regs[MAX_REG_NR]; + int i; + + if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + return -errno; + else { + printk("Stub registers -\n"); + for(i = 0; i < ARRAY_SIZE(regs); i++) + printk("\t%d - %lx\n", i, regs[i]); + } + + return 0; +} + void wait_stub_done(int pid, int sig, char * fname) { int n, status, err; @@ -67,18 +83,10 @@ void wait_stub_done(int pid, int sig, char * fname) if((n < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ - unsigned long regs[MAX_REG_NR]; - - if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + err = ptrace_dump_regs(pid); + if(err) printk("Failed to get registers from stub, " - "errno = %d\n", errno); - else { - int i; - - printk("Stub registers -\n"); - for(i = 0; i < ARRAY_SIZE(regs); i++) - printk("\t%d - %lx\n", i, regs[i]); - } + "errno = %d\n", -err); panic("%s : failed to wait for SIGUSR1/SIGTRAP, " "pid = %d, n = %d, errno = %d, status = 0x%x\n", fname, pid, n, errno, status); @@ -142,9 +150,14 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if((err < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGTRAP + 0x80)) + (WSTOPSIG(status) != SIGTRAP + 0x80)){ + err = ptrace_dump_regs(pid); + if(err) + printk("Failed to get registers from process, " + "errno = %d\n", -err); panic("handle_trap - failed to wait at end of syscall, " "errno = %d, status = %d\n", errno, status); + } } handle_syscall(regs); -- cgit v1.2.3 From 7f0536f80cfbefd753eb123ed20940978f223900 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:30 -0700 Subject: uml: speed up page table walking The previous page table walking code was horribly inefficient. This patch replaces it with code taken from elsewhere in the kernel. Forking from bash is now ~5% faster and page faults are handled ~10% faster. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tlb.c | 202 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 82 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index e40f3352bd2..153dec13cf9 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -6,6 +6,7 @@ #include "linux/mm.h" #include "asm/page.h" #include "asm/pgalloc.h" +#include "asm/pgtable.h" #include "asm/tlbflush.h" #include "choose-mode.h" #include "mode_kern.h" @@ -123,106 +124,143 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) +static inline int update_pte_range(pmd_t *pmd, unsigned long addr, + unsigned long end, struct host_vm_op *ops, + int last_op, int *op_index, int force, + union mm_context *mmu, void **flush, + int (*do_ops)(union mm_context *, + struct host_vm_op *, int, int, + void **)) +{ + pte_t *pte; + int r, w, x, ret = 0; + + pte = pte_offset_kernel(pmd, addr); + do { + r = pte_read(*pte); + w = pte_write(*pte); + x = pte_exec(*pte); + if (!pte_young(*pte)) { + r = 0; + w = 0; + } else if (!pte_dirty(*pte)) { + w = 0; + } + if(force || pte_newpage(*pte)){ + if(pte_present(*pte)) + ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, + PAGE_SIZE, r, w, x, ops, + op_index, last_op, mmu, flush, + do_ops); + else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, + last_op, mmu, flush, do_ops); + } + else if(pte_newprot(*pte)) + ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, + op_index, last_op, mmu, flush, + do_ops); + *pte = pte_mkuptodate(*pte); + } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); + return ret; +} + +static inline int update_pmd_range(pud_t *pud, unsigned long addr, + unsigned long end, struct host_vm_op *ops, + int last_op, int *op_index, int force, + union mm_context *mmu, void **flush, + int (*do_ops)(union mm_context *, + struct host_vm_op *, int, int, + void **)) +{ + pmd_t *pmd; + unsigned long next; + int ret = 0; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if(!pmd_present(*pmd)){ + if(force || pmd_newpage(*pmd)){ + ret = add_munmap(addr, next - addr, ops, + op_index, last_op, mmu, + flush, do_ops); + pmd_mkuptodate(*pmd); + } + } + else ret = update_pte_range(pmd, addr, next, ops, last_op, + op_index, force, mmu, flush, + do_ops); + } while (pmd++, addr = next, ((addr != end) && !ret)); + return ret; +} + +static inline int update_pud_range(pgd_t *pgd, unsigned long addr, + unsigned long end, struct host_vm_op *ops, + int last_op, int *op_index, int force, + union mm_context *mmu, void **flush, + int (*do_ops)(union mm_context *, + struct host_vm_op *, int, int, + void **)) +{ + pud_t *pud; + unsigned long next; + int ret = 0; + + pud = pud_offset(pgd, addr); + do { + next = pud_addr_end(addr, end); + if(!pud_present(*pud)){ + if(force || pud_newpage(*pud)){ + ret = add_munmap(addr, next - addr, ops, + op_index, last_op, mmu, + flush, do_ops); + pud_mkuptodate(*pud); + } + } + else ret = update_pmd_range(pud, addr, next, ops, last_op, + op_index, force, mmu, flush, + do_ops); + } while (pud++, addr = next, ((addr != end) && !ret)); + return ret; +} + void fix_range_common(struct mm_struct *mm, unsigned long start_addr, unsigned long end_addr, int force, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) { - pgd_t *npgd; - pud_t *npud; - pmd_t *npmd; - pte_t *npte; + pgd_t *pgd; union mm_context *mmu = &mm->context; - unsigned long addr, end; - int r, w, x; struct host_vm_op ops[1]; + unsigned long addr = start_addr, next; + int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; void *flush = NULL; - int op_index = -1, last_op = ARRAY_SIZE(ops) - 1; - int ret = 0; - - if(mm == NULL) - return; + unsigned long long start_time, end_time; + start_time = os_nsecs(); ops[0].type = NONE; - for(addr = start_addr; addr < end_addr && !ret;){ - npgd = pgd_offset(mm, addr); - if(!pgd_present(*npgd)){ - end = ADD_ROUND(addr, PGDIR_SIZE); - if(end > end_addr) - end = end_addr; - if(force || pgd_newpage(*npgd)){ - ret = add_munmap(addr, end - addr, ops, - &op_index, last_op, mmu, - &flush, do_ops); - pgd_mkuptodate(*npgd); - } - addr = end; - continue; - } - - npud = pud_offset(npgd, addr); - if(!pud_present(*npud)){ - end = ADD_ROUND(addr, PUD_SIZE); - if(end > end_addr) - end = end_addr; - if(force || pud_newpage(*npud)){ - ret = add_munmap(addr, end - addr, ops, - &op_index, last_op, mmu, - &flush, do_ops); - pud_mkuptodate(*npud); - } - addr = end; - continue; - } - - npmd = pmd_offset(npud, addr); - if(!pmd_present(*npmd)){ - end = ADD_ROUND(addr, PMD_SIZE); - if(end > end_addr) - end = end_addr; - if(force || pmd_newpage(*npmd)){ - ret = add_munmap(addr, end - addr, ops, + pgd = pgd_offset(mm, addr); + do { + next = pgd_addr_end(addr, end_addr); + if(!pgd_present(*pgd)){ + if (force || pgd_newpage(*pgd)){ + ret = add_munmap(addr, next - addr, ops, &op_index, last_op, mmu, &flush, do_ops); - pmd_mkuptodate(*npmd); + pgd_mkuptodate(*pgd); } - addr = end; - continue; } + else ret = update_pud_range(pgd, addr, next, ops, last_op, + &op_index, force, mmu, &flush, + do_ops); + } while (pgd++, addr = next, ((addr != end_addr) && !ret)); + end_time = os_nsecs(); + log_info("total flush time - %Ld nsecs\n", end_time - start_time); - npte = pte_offset_kernel(npmd, addr); - r = pte_read(*npte); - w = pte_write(*npte); - x = pte_exec(*npte); - if (!pte_young(*npte)) { - r = 0; - w = 0; - } else if (!pte_dirty(*npte)) { - w = 0; - } - if(force || pte_newpage(*npte)){ - if(pte_present(*npte)) - ret = add_mmap(addr, - pte_val(*npte) & PAGE_MASK, - PAGE_SIZE, r, w, x, ops, - &op_index, last_op, mmu, - &flush, do_ops); - else ret = add_munmap(addr, PAGE_SIZE, ops, - &op_index, last_op, mmu, - &flush, do_ops); - } - else if(pte_newprot(*npte)) - ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, - &op_index, last_op, mmu, - &flush, do_ops); - - *npte = pte_mkuptodate(*npte); - addr += PAGE_SIZE; - } if(!ret) ret = (*do_ops)(mmu, ops, op_index, 1, &flush); -/* This is not an else because ret is modified above */ + /* This is not an else because ret is modified above */ if(ret) { printk("fix_range_common: failed, killing current process\n"); force_sig(SIGKILL, current); -- cgit v1.2.3 From f9d6e5f83b40d8ff73a74d4bba2c5f51d6048b12 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:31 -0700 Subject: uml: remove unused x86_64 code It turns out that essentially none of the x86_64 bugs.c is needed. So, we can delete most of it. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-x86_64/bugs.c | 69 ----------------------------------------------- 1 file changed, 69 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c index 9fa5392e312..09547889037 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/um/sys-x86_64/bugs.c @@ -4,12 +4,7 @@ * Licensed under the GPL */ -#include "linux/sched.h" -#include "linux/errno.h" -#include "asm/system.h" -#include "asm/pda.h" #include "sysdep/ptrace.h" -#include "os.h" void arch_init_thread(void) { @@ -23,67 +18,3 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) { return 0; } - -#define MAXTOKEN 64 - -/* Set during early boot */ -int host_has_cmov = 1; -int host_has_xmm = 0; - -static char token(int fd, char *buf, int len, char stop) -{ - int n; - char *ptr, *end, c; - - ptr = buf; - end = &buf[len]; - do { - n = os_read_file(fd, ptr, sizeof(*ptr)); - c = *ptr++; - if(n != sizeof(*ptr)){ - if(n == 0) - return 0; - printk("Reading /proc/cpuinfo failed, err = %d\n", -n); - if(n < 0) - return n; - else return -EIO; - } - } while((c != '\n') && (c != stop) && (ptr < end)); - - if(ptr == end){ - printk("Failed to find '%c' in /proc/cpuinfo\n", stop); - return -1; - } - *(ptr - 1) = '\0'; - return c; -} - -static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) -{ - int n; - char c; - - scratch[len - 1] = '\0'; - while(1){ - c = token(fd, scratch, len - 1, ':'); - if(c <= 0) - return 0; - else if(c != ':'){ - printk("Failed to find ':' in /proc/cpuinfo\n"); - return 0; - } - - if(!strncmp(scratch, key, strlen(key))) - return 1; - - do { - n = os_read_file(fd, &c, sizeof(c)); - if(n != sizeof(c)){ - printk("Failed to find newline in " - "/proc/cpuinfo, err = %d\n", -n); - return 0; - } - } while(c != '\n'); - } - return 0; -} -- cgit v1.2.3 From 3d564047a5f45cb628ec72514f68076e532988f3 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:32 -0700 Subject: uml: start fixing os_read_file and os_write_file This patch starts the removal of a very old, very broken piece of code. This stems from the problem of passing a userspace buffer into read() or write() on the host. If that buffer had not yet been faulted in, read and write will return -EFAULT. To avoid this problem, the solution was to fault the buffer in before the system call by touching the pages that hold the buffer by doing a copy-user of a byte to each page. This is obviously bogus, but it does usually work, in tt mode, since the kernel and process are in the same address space and userspace addresses can be accessed directly in the kernel. In skas mode, where the kernel and process are in separate address spaces, it is completely bogus because the userspace address, which is invalid in the kernel, is passed into the system call instead of the corresponding physical address, which would be valid. Here, it appears that this code, on every host read() or write(), tries to fault in a random process page. This doesn't seem to cause any correctness problems, but there is a performance impact. This patch, and the ones following, result in a 10-15% performance gain on a kernel build. This code can't be immediately tossed out because when it is, you can't log in. Apparently, there is some code in the console driver which depends on this somehow. However, we can start removing it by switching the code which does I/O using kernel addresses to using plain read() and write(). This patch introduces os_read_file_k and os_write_file_k for use with kernel buffers and converts all call locations which use obvious kernel buffers to use them. These include I/O using buffers which are local variables which are on the stack or kmalloc-ed. Later patches will handle the less obvious cases, followed by a mass conversion back to the original interface. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 10 +++++----- arch/um/drivers/daemon_user.c | 4 ++-- arch/um/drivers/harddog_user.c | 4 ++-- arch/um/drivers/hostaudio_kern.c | 4 ++-- arch/um/drivers/net_user.c | 2 +- arch/um/drivers/port_kern.c | 2 +- arch/um/drivers/random.c | 2 +- arch/um/drivers/ubd_kern.c | 17 ++++++++--------- arch/um/include/os.h | 2 ++ arch/um/kernel/ksyms.c | 2 ++ arch/um/kernel/physmem.c | 2 +- arch/um/kernel/sigio.c | 2 +- arch/um/kernel/smp.c | 12 ++++++------ arch/um/kernel/tt/process_kern.c | 7 ++++--- arch/um/kernel/tt/ptproxy/proxy.c | 9 +++++---- arch/um/kernel/tt/tracer.c | 2 +- arch/um/os-Linux/file.c | 18 ++++++++++++++++++ arch/um/sys-i386/bugs.c | 2 +- arch/um/sys-i386/ldt.c | 2 +- 19 files changed, 64 insertions(+), 41 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index ee53cf882f4..d226f103462 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -85,7 +85,7 @@ static int winch_thread(void *arg) pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; - count = os_write_file(pipe_fd, &c, sizeof(c)); + count = os_write_file_k(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to write synchronization " "byte, err = %d\n", -count); @@ -120,7 +120,7 @@ static int winch_thread(void *arg) * host - since they are not different kernel threads, we cannot use * kernel semaphores. We don't use SysV semaphores because they are * persistent. */ - count = os_read_file(pipe_fd, &c, sizeof(c)); + count = os_read_file_k(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to read synchronization byte, " "err = %d\n", -count); @@ -130,7 +130,7 @@ static int winch_thread(void *arg) * are blocked.*/ sigsuspend(&sigs); - count = os_write_file(pipe_fd, &c, sizeof(c)); + count = os_write_file_k(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : write failed, err = %d\n", -count); @@ -162,7 +162,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) } *fd_out = fds[0]; - n = os_read_file(fds[0], &c, sizeof(c)); + n = os_read_file_k(fds[0], &c, sizeof(c)); if(n != sizeof(c)){ printk("winch_tramp : failed to read synchronization byte\n"); printk("read failed, err = %d\n", -n); @@ -195,7 +195,7 @@ void register_winch(int fd, struct tty_struct *tty) if(thread > 0){ register_winch_irq(thread_fd, fd, thread, tty); - count = os_write_file(thread_fd, &c, sizeof(c)); + count = os_write_file_k(thread_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("register_winch : failed to write " "synchronization byte, err = %d\n", diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index b869e389968..e1fd26c1b72 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -94,7 +94,7 @@ static int connect_to_switch(struct daemon_data *pri) req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = *local_addr; - n = os_write_file(pri->control, &req, sizeof(req)); + n = os_write_file_k(pri->control, &req, sizeof(req)); if(n != sizeof(req)){ printk("daemon_open : control setup request failed, err = %d\n", -n); @@ -102,7 +102,7 @@ static int connect_to_switch(struct daemon_data *pri) goto out_free; } - n = os_read_file(pri->control, sun, sizeof(*sun)); + n = os_read_file_k(pri->control, sun, sizeof(*sun)); if(n != sizeof(*sun)){ printk("daemon_open : read of data socket failed, err = %d\n", -n); diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 5eeecf8917c..0fbb1615171 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -79,7 +79,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) goto out_close_out; } - n = os_read_file(in_fds[0], &c, sizeof(c)); + n = os_read_file_k(in_fds[0], &c, sizeof(c)); if(n == 0){ printk("harddog_open - EOF on watchdog pipe\n"); helper_wait(pid); @@ -118,7 +118,7 @@ int ping_watchdog(int fd) int n; char c = '\n'; - n = os_write_file(fd, &c, sizeof(c)); + n = os_write_file_k(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("ping_watchdog - write failed, err = %d\n", -n); if(n < 0) diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 10e08a8c17c..bd6688ea96d 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -84,7 +84,7 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, if(kbuf == NULL) return(-ENOMEM); - err = os_read_file(state->fd, kbuf, count); + err = os_read_file_k(state->fd, kbuf, count); if(err < 0) goto out; @@ -115,7 +115,7 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer, if(copy_from_user(kbuf, buffer, count)) goto out; - err = os_write_file(state->fd, kbuf, count); + err = os_write_file_k(state->fd, kbuf, count); if(err < 0) goto out; *ppos += err; diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 3503cff867c..2dc57a37e4b 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -63,7 +63,7 @@ void read_output(int fd, char *output, int len) } *output = '\0'; - ret = os_read_file(fd, &remain, sizeof(remain)); + ret = os_read_file_k(fd, &remain, sizeof(remain)); if (ret != sizeof(remain)) { expected = sizeof(remain); diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 1c8efd95c42..75bb40126c2 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -113,7 +113,7 @@ static int port_accept(struct port_list *port) } if(atomic_read(&port->wait_count) == 0){ - os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); + os_write_file_k(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); printk("No one waiting for port\n"); } list_add(&conn->list, &port->pending); diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index e942e836f99..94838f4c164 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -44,7 +44,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, int n, ret = 0, have_data; while(size){ - n = os_read_file(random_fd, &data, sizeof(data)); + n = os_read_file_k(random_fd, &data, sizeof(data)); if(n > 0){ have_data = n; while (have_data && size) { diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 83189e188c3..6d163c9e288 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -504,7 +504,7 @@ static void ubd_handler(void) struct ubd *dev; int n; - n = os_read_file(thread_fd, &req, sizeof(req)); + n = os_read_file_k(thread_fd, &req, sizeof(req)); if(n != sizeof(req)){ printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " "err = %d\n", os_getpid(), -n); @@ -1092,8 +1092,7 @@ static void do_ubd_request(request_queue_t *q) err = prepare_request(req, &io_req); if(!err){ dev->active = 1; - n = os_write_file(thread_fd, (char *) &io_req, - sizeof(io_req)); + n = os_write_file_k(thread_fd, &io_req, sizeof(io_req)); if(n != sizeof(io_req)) printk("write to io thread failed, " "errno = %d\n", -n); @@ -1336,8 +1335,8 @@ static int update_bitmap(struct io_thread_req *req) return(1); } - n = os_write_file(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words)); + n = os_write_file_k(req->fds[1], &req->bitmap_words, + sizeof(req->bitmap_words)); if(n != sizeof(req->bitmap_words)){ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, req->fds[1]); @@ -1381,7 +1380,7 @@ void do_io(struct io_thread_req *req) do { buf = &buf[n]; len -= n; - n = os_read_file(req->fds[bit], buf, len); + n = os_read_file_k(req->fds[bit], buf, len); if (n < 0) { printk("do_io - read failed, err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1391,7 +1390,7 @@ void do_io(struct io_thread_req *req) } while((n < len) && (n != 0)); if (n < len) memset(&buf[n], 0, len - n); } else { - n = os_write_file(req->fds[bit], buf, len); + n = os_write_file_k(req->fds[bit], buf, len); if(n != len){ printk("do_io - write failed err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1421,7 +1420,7 @@ int io_thread(void *arg) ignore_sigwinch_sig(); while(1){ - n = os_read_file(kernel_fd, &req, sizeof(req)); + n = os_read_file_k(kernel_fd, &req, sizeof(req)); if(n != sizeof(req)){ if(n < 0) printk("io_thread - read failed, fd = %d, " @@ -1434,7 +1433,7 @@ int io_thread(void *arg) } io_count++; do_io(&req); - n = os_write_file(kernel_fd, &req, sizeof(req)); + n = os_write_file_k(kernel_fd, &req, sizeof(req)); if(n != sizeof(req)) printk("io_thread - write failed, fd = %d, err = %d\n", kernel_fd, -n); diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 394adcded0b..b463170a530 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -144,7 +144,9 @@ extern int os_mode_fd(int fd, int mode); extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_read_file(int fd, void *buf, int len); +extern int os_read_file_k(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); +extern int os_write_file_k(int fd, const void *buf, int len); extern int os_file_size(char *file, unsigned long long *size_out); extern int os_file_modtime(char *file, unsigned long *modtime); extern int os_pipe(int *fd, int stream, int close_on_exec); diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 7b3e53fb807..7c158448b9f 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -62,7 +62,9 @@ EXPORT_SYMBOL(os_get_exec_close); EXPORT_SYMBOL(os_set_exec_close); EXPORT_SYMBOL(os_getpid); EXPORT_SYMBOL(os_open_file); +EXPORT_SYMBOL(os_read_file_k); EXPORT_SYMBOL(os_read_file); +EXPORT_SYMBOL(os_write_file_k); EXPORT_SYMBOL(os_write_file); EXPORT_SYMBOL(os_seek_file); EXPORT_SYMBOL(os_lock_file); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index df1ad3ba130..a9856209006 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -341,7 +341,7 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, * from physmem_fd, so it needs to be written out there. */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); - os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); + os_write_file_k(physmem_fd, &__syscall_stub_start, PAGE_SIZE); bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index 89f9866a135..f756e78085e 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c @@ -21,7 +21,7 @@ static irqreturn_t sigio_interrupt(int irq, void *data) { char c; - os_read_file(sigio_irq_fd, &c, sizeof(c)); + os_read_file_k(sigio_irq_fd, &c, sizeof(c)); reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); return IRQ_HANDLED; } diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 62dd093cbcd..47b690893c0 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -47,7 +47,7 @@ struct task_struct *idle_threads[NR_CPUS]; void smp_send_reschedule(int cpu) { - os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); + os_write_file_k(cpu_data[cpu].ipi_pipe[1], "R", 1); num_reschedules_sent++; } @@ -59,7 +59,7 @@ void smp_send_stop(void) for(i = 0; i < num_online_cpus(); i++){ if(i == current_thread->cpu) continue; - os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); + os_write_file_k(cpu_data[i].ipi_pipe[1], "S", 1); } printk("done\n"); } @@ -108,8 +108,8 @@ static struct task_struct *idle_thread(int cpu) { .pid = new_task->thread.mode.tt.extern_pid, .task = new_task } ); idle_threads[cpu] = new_task; - CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, - sizeof(c)), + CHOOSE_MODE(os_write_file_k(new_task->thread.mode.tt.switch_pipe[1], &c, + sizeof(c)), ({ panic("skas mode doesn't support SMP"); })); return(new_task); } @@ -179,7 +179,7 @@ void IPI_handler(int cpu) int fd; fd = cpu_data[cpu].ipi_pipe[0]; - while (os_read_file(fd, &c, 1) == 1) { + while (os_read_file_k(fd, &c, 1) == 1) { switch (c) { case 'C': smp_call_function_slave(cpu); @@ -239,7 +239,7 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, info = _info; for_each_online_cpu(i) - os_write_file(cpu_data[i].ipi_pipe[1], "C", 1); + os_write_file_k(cpu_data[i].ipi_pipe[1], "C", 1); while (atomic_read(&scf_started) != cpus) barrier(); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 8029f72afaa..c81bd207493 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -57,14 +57,15 @@ void switch_to_tt(void *prev, void *next) * nor the value in "to" (since it was the task which stole us the CPU, * which we don't care about). */ - err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); + err = os_write_file_k(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); - err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); + err = os_read_file_k(from->thread.mode.tt.switch_pipe[0], &c, + sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); @@ -113,7 +114,7 @@ void suspend_new_thread(int fd) char c; os_stop_process(os_getpid()); - err = os_read_file(fd, &c, sizeof(c)); + err = os_read_file_k(fd, &c, sizeof(c)); if(err != sizeof(c)) panic("read failed in suspend_new_thread, err = %d", -err); } diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c index c88e7b5d8a7..007beb6b7c0 100644 --- a/arch/um/kernel/tt/ptproxy/proxy.c +++ b/arch/um/kernel/tt/ptproxy/proxy.c @@ -338,13 +338,14 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out) "err = %d\n", -fd); exit(1); } - os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1); + os_write_file_k(fd, gdb_init_string, + sizeof(gdb_init_string) - 1); if(startup){ if(stop){ - os_write_file(fd, "b start_kernel\n", - strlen("b start_kernel\n")); + os_write_file_k(fd, "b start_kernel\n", + strlen("b start_kernel\n")); } - os_write_file(fd, "c\n", strlen("c\n")); + os_write_file_k(fd, "c\n", strlen("c\n")); } if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ printk("start_debugger : PTRACE_TRACEME failed, " diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index c23588393f6..264da6c5a5c 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -44,7 +44,7 @@ static void tracer_winch_handler(int sig) int n; char c = 1; - n = os_write_file(tracer_winch[1], &c, sizeof(c)); + n = os_write_file_k(tracer_winch[1], &c, sizeof(c)); if(n != sizeof(c)) printk("tracer_winch_handler - write failed, err = %d\n", -n); } diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 4a9510c6762..5e9b8dcf34d 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -334,12 +334,30 @@ int os_read_file(int fd, void *buf, int len) copy_from_user_proc); } +int os_read_file_k(int fd, void *buf, int len) +{ + int n = read(fd, buf, len); + + if(n < 0) + return -errno; + return n; +} + int os_write_file(int fd, const void *buf, int len) { return file_io(fd, (void *) buf, len, (int (*)(int, void *, int)) write, copy_to_user_proc); } +int os_write_file_k(int fd, const void *buf, int len) +{ + int n = write(fd, (void *) buf, len); + + if(n < 0) + return -errno; + return n; +} + int os_file_size(char *file, unsigned long long *size_out) { struct uml_stat buf; diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index 0393e44813e..74fd062b201 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -67,7 +67,7 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return 1; do { - n = os_read_file(fd, &c, sizeof(c)); + n = os_read_file_k(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index a939a7ef022..d031a13bd96 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -517,7 +517,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm, .u = { .copy_segments = from_mm->id.u.mm_fd } } ); - i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); + i = os_write_file_k(new_mm->id.u.mm_fd, ©, sizeof(copy)); if(i != sizeof(copy)) printk("new_mm : /proc/mm copy_segments failed, " "err = %d\n", -i); -- cgit v1.2.3 From ef0470c053274c343b2be8737e0146d65e17f9be Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:33 -0700 Subject: uml: tidy libc code This patch lays some groundwork for the next one, which converts calls to os_{read,write}_file into {read,write}, by doing some tidying in the affected areas. do_not_aio gets restructured to make the final result a bit cleaner. There are also whitespace and other formatting fixes, fixes in error messages, and a typo fix. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 20 ++++++-------------- arch/um/os-Linux/drivers/ethertap_user.c | 10 +++++++--- arch/um/os-Linux/helper.c | 9 ++++++--- arch/um/os-Linux/process.c | 29 +++++++++++++++-------------- arch/um/os-Linux/sigio.c | 7 ++++--- arch/um/os-Linux/skas/process.c | 2 +- arch/um/os-Linux/tty_log.c | 16 ++++++++-------- 7 files changed, 47 insertions(+), 46 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 6ff12743a0b..c1f0f76291c 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -146,28 +146,21 @@ static int aio_thread(void *arg) static int do_not_aio(struct aio_thread_req *req) { char c; + unsigned long long actual; int err; + actual = lseek64(req->io_fd, req->offset, SEEK_SET); + if(actual != req->offset) + return -errno; + switch(req->type){ case AIO_READ: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - err = os_read_file(req->io_fd, req->buf, req->len); break; case AIO_WRITE: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - err = os_write_file(req->io_fd, req->buf, req->len); break; case AIO_MMAP: - err = os_seek_file(req->io_fd, req->offset); - if(err) - goto out; - err = os_read_file(req->io_fd, &c, sizeof(c)); break; default: @@ -176,7 +169,6 @@ static int do_not_aio(struct aio_thread_req *req) break; } -out: return err; } @@ -207,7 +199,7 @@ static int not_aio_thread(void *arg) } err = do_not_aio(&req); reply = ((struct aio_thread_reply) { .data = req.aio, - .err = err }); + .err = err }); err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("not_aio_thread - write failed, fd = %d, " diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 96e12ea8172..fd6cfa5b4a7 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. @@ -49,8 +49,11 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); n = os_write_file(fd, &change, sizeof(change)); - if(n != sizeof(change)) + if(n != sizeof(change)){ printk("etap_change - request failed, err = %d\n", -n); + return; + } + output = um_kmalloc(UM_KERN_PAGE_SIZE); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); @@ -116,7 +119,8 @@ static int etap_tramp(char *dev, char *gate, int control_me, pe_data.data_me = data_me; pid = run_helper(etap_pre_exec, &pe_data, args, NULL); - if(pid < 0) err = pid; + if(pid < 0) + err = pid; os_close_file(data_remote); os_close_file(control_remote); n = os_read_file(control_me, &c, sizeof(c)); diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 2184ddb9cb3..8a4c9e47326 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -34,7 +34,8 @@ static int helper_child(void *arg) if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); errval = execvp_noalloc(data->buf, argv[0], argv); - printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); + printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], + -errval); os_write_file(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); return 0; @@ -87,8 +88,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, close(fds[1]); fds[1] = -1; - /* Read the errno value from the child, if the exec failed, or get 0 if - * the exec succeeded because the pipe fd was set as close-on-exec. */ + /* + * Read the errno value from the child, if the exec failed, or get 0 if + * the exec succeeded because the pipe fd was set as close-on-exec. + */ n = os_read_file(fds[0], &ret, sizeof(ret)); if (n == 0) { ret = pid; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 37933d3f92b..a84a45843f8 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -40,14 +40,14 @@ unsigned long os_process_pc(int pid) if(fd < 0){ printk("os_process_pc - couldn't open '%s', err = %d\n", proc_stat, -fd); - return(ARBITRARY_ADDR); + return ARBITRARY_ADDR; } err = os_read_file(fd, buf, sizeof(buf)); if(err < 0){ printk("os_process_pc - couldn't read '%s', err = %d\n", proc_stat, -err); os_close_file(fd); - return(ARBITRARY_ADDR); + return ARBITRARY_ADDR; } os_close_file(fd); pc = ARBITRARY_ADDR; @@ -56,7 +56,7 @@ unsigned long os_process_pc(int pid) "%*d %*d %*d %*d %*d %lu", &pc) != 1){ printk("os_process_pc - couldn't find pc in '%s'\n", buf); } - return(pc); + return pc; } int os_process_parent(int pid) @@ -65,13 +65,14 @@ int os_process_parent(int pid) char data[256]; int parent, n, fd; - if(pid == -1) return(-1); + if(pid == -1) + return -1; snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); fd = os_open_file(stat, of_read(OPENFLAGS()), 0); if(fd < 0){ printk("Couldn't open '%s', err = %d\n", stat, -fd); - return(FAILURE_PID); + return FAILURE_PID; } n = os_read_file(fd, data, sizeof(data)); @@ -79,7 +80,7 @@ int os_process_parent(int pid) if(n < 0){ printk("Couldn't read '%s', err = %d\n", stat, -n); - return(FAILURE_PID); + return FAILURE_PID; } parent = FAILURE_PID; @@ -87,7 +88,7 @@ int os_process_parent(int pid) if(n != 1) printk("Failed to scan '%s'\n", data); - return(parent); + return parent; } void os_stop_process(int pid) @@ -145,7 +146,7 @@ void os_usr1_process(int pid) int os_getpid(void) { - return(syscall(__NR_getpid)); + return syscall(__NR_getpid); } int os_getpgrp(void) @@ -165,8 +166,8 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, fd, off); if(loc == MAP_FAILED) - return(-errno); - return(0); + return -errno; + return 0; } int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) @@ -175,8 +176,8 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) (x ? PROT_EXEC : 0)); if(mprotect(addr, len, prot) < 0) - return(-errno); - return(0); + return -errno; + return 0; } int os_unmap_memory(void *addr, int len) @@ -185,8 +186,8 @@ int os_unmap_memory(void *addr, int len) err = munmap(addr, len); if(err < 0) - return(-errno); - return(0); + return -errno; + return 0; } #ifndef MADV_REMOVE diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index f77ce3d6f7c..8ccf6a36f1c 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -461,15 +461,16 @@ static void tty_output(int master, int slave) while(os_write_file(master, buf, sizeof(buf)) > 0) ; if(errno != EAGAIN) - panic("check_sigio : write failed, errno = %d\n", errno); + panic("tty_output : write failed, errno = %d\n", errno); while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; if(got_sigio){ printk("Yes\n"); pty_output_sigio = 1; } - else if(n == -EAGAIN) printk("No, enabling workaround\n"); - else panic("check_sigio : read failed, err = %d\n", n); + else if(n == -EAGAIN) + printk("No, enabling workaround\n"); + else panic("tty_output : read failed, err = %d\n", n); } static void tty_close(int master, int slave) diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 41bf8d1e14e..47852698d5e 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -409,7 +409,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* * This is used only, if stub pages are needed, while proc_mm is - * availabl. Opening /proc/mm creates a new mm_context, which lacks + * available. Opening /proc/mm creates a new mm_context, which lacks * the stub-pages. Thus, we map them using /proc/mm-fd */ void map_stub_pages(int fd, unsigned long code, diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c index c6ba56c1560..ae9adb1b74f 100644 --- a/arch/um/os-Linux/tty_log.c +++ b/arch/um/os-Linux/tty_log.c @@ -55,7 +55,7 @@ int open_tty_log(void *tty, void *current_tty) .usec = tv.tv_usec } ); os_write_file(tty_log_fd, &data, sizeof(data)); os_write_file(tty_log_fd, ¤t_tty, data.len); - return(tty_log_fd); + return tty_log_fd; } sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, @@ -67,7 +67,7 @@ int open_tty_log(void *tty, void *current_tty) printk("open_tty_log : couldn't open '%s', errno = %d\n", buf, -fd); } - return(fd); + return fd; } void close_tty_log(int fd, void *tty) @@ -101,18 +101,18 @@ static int log_chunk(int fd, const char *buf, int len) n = os_write_file(fd, chunk, try); if(n != try) { if(n < 0) - return(n); - return(-EIO); + return n; + return -EIO; } if(missed != 0) - return(-EFAULT); + return -EFAULT; len -= try; total += try; buf += try; } - return(total); + return total; } int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) @@ -133,7 +133,7 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) os_write_file(tty_log_fd, &data, sizeof(data)); } - return(log_chunk(fd, buf, len)); + return log_chunk(fd, buf, len); } void log_exec(char **argv, void *tty) @@ -179,7 +179,7 @@ extern void register_tty_logger(int (*opener)(void *, void *), static int register_logger(void) { register_tty_logger(open_tty_log, write_tty_log, close_tty_log); - return(0); + return 0; } __uml_initcall(register_logger); -- cgit v1.2.3 From a61f334fd2864b9b040f7e882726426ed7e8a317 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:35 -0700 Subject: uml: convert libc layer to call read and write This patch converts calls in the os layer to os_{read,write}_file to calls directly to libc read() and write() where it is clear that the I/O buffer is in the kernel. We can do that here instead of calling os_{read,write}_file_k since we are in libc code and can call libc directly. With the change in the calls, error handling needs to be changed to refer to errno directly rather than the return value of the call. CATCH_EINTR wrappers were also added where needed. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 36 ++++++++++++++++++-------------- arch/um/os-Linux/drivers/ethertap_user.c | 11 +++++----- arch/um/os-Linux/helper.c | 5 +++-- arch/um/os-Linux/mem.c | 5 ++--- arch/um/os-Linux/process.c | 8 +++---- arch/um/os-Linux/sigio.c | 21 ++++++++++--------- arch/um/os-Linux/skas/mem.c | 19 +++++++++++------ arch/um/os-Linux/skas/process.c | 9 ++++---- arch/um/os-Linux/tty_log.c | 14 ++++++------- 9 files changed, 71 insertions(+), 57 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index c1f0f76291c..5d258eb4f50 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -132,10 +132,10 @@ static int aio_thread(void *arg) { .data = (void *) (long) event.data, .err = event.res }); reply_fd = ((struct aio_context *) reply.data)->reply_fd; - err = os_write_file(reply_fd, &reply, sizeof(reply)); + err = write(reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("aio_thread - write failed, fd = %d, " - "err = %d\n", reply_fd, -err); + "err = %d\n", reply_fd, errno); } } return 0; @@ -147,7 +147,7 @@ static int do_not_aio(struct aio_thread_req *req) { char c; unsigned long long actual; - int err; + int n; actual = lseek64(req->io_fd, req->offset, SEEK_SET); if(actual != req->offset) @@ -155,21 +155,22 @@ static int do_not_aio(struct aio_thread_req *req) switch(req->type){ case AIO_READ: - err = os_read_file(req->io_fd, req->buf, req->len); + n = read(req->io_fd, req->buf, req->len); break; case AIO_WRITE: - err = os_write_file(req->io_fd, req->buf, req->len); + n = write(req->io_fd, req->buf, req->len); break; case AIO_MMAP: - err = os_read_file(req->io_fd, &c, sizeof(c)); + n = read(req->io_fd, &c, sizeof(c)); break; default: printk("do_not_aio - bad request type : %d\n", req->type); - err = -EINVAL; - break; + return -EINVAL; } - return err; + if(n < 0) + return -errno; + return 0; } /* These are initialized in initcalls and not changed */ @@ -185,12 +186,12 @@ static int not_aio_thread(void *arg) signal(SIGWINCH, SIG_IGN); while(1){ - err = os_read_file(aio_req_fd_r, &req, sizeof(req)); + err = read(aio_req_fd_r, &req, sizeof(req)); if(err != sizeof(req)){ if(err < 0) printk("not_aio_thread - read failed, " "fd = %d, err = %d\n", aio_req_fd_r, - -err); + errno); else { printk("not_aio_thread - short read, fd = %d, " "length = %d\n", aio_req_fd_r, err); @@ -200,10 +201,10 @@ static int not_aio_thread(void *arg) err = do_not_aio(&req); reply = ((struct aio_thread_reply) { .data = req.aio, .err = err }); - err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); + err = write(req.aio->reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("not_aio_thread - write failed, fd = %d, " - "err = %d\n", req.aio->reply_fd, -err); + "err = %d\n", req.aio->reply_fd, errno); } return 0; @@ -277,10 +278,12 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, if(err){ reply = ((struct aio_thread_reply) { .data = aio, .err = err }); - err = os_write_file(aio->reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)) + err = write(aio->reply_fd, &reply, sizeof(reply)); + if(err != sizeof(reply)){ + err = -errno; printk("submit_aio_26 - write failed, " "fd = %d, err = %d\n", aio->reply_fd, -err); + } else err = 0; } @@ -375,9 +378,10 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, }; int err; - err = os_write_file(aio_req_fd_w, &req, sizeof(req)); + err = write(aio_req_fd_w, &req, sizeof(req)); if(err == sizeof(req)) err = 0; + else err = -errno; return err; } diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index fd6cfa5b4a7..acba3016128 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -48,9 +48,9 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, change.what = op; memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); - n = os_write_file(fd, &change, sizeof(change)); + CATCH_EINTR(n = write(fd, &change, sizeof(change))); if(n != sizeof(change)){ - printk("etap_change - request failed, err = %d\n", -n); + printk("etap_change - request failed, err = %d\n", errno); return; } @@ -123,10 +123,11 @@ static int etap_tramp(char *dev, char *gate, int control_me, err = pid; os_close_file(data_remote); os_close_file(control_remote); - n = os_read_file(control_me, &c, sizeof(c)); + CATCH_EINTR(n = read(control_me, &c, sizeof(c))); if(n != sizeof(c)){ - printk("etap_tramp : read of status failed, err = %d\n", -n); - return -EINVAL; + err = -errno; + printk("etap_tramp : read of status failed, err = %d\n", -err); + return err; } if(c != 1){ printk("etap_tramp : uml_net failed\n"); diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 8a4c9e47326..97bed16bf4c 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -36,7 +36,7 @@ static int helper_child(void *arg) errval = execvp_noalloc(data->buf, argv[0], argv); printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); - os_write_file(data->fd, &errval, sizeof(errval)); + write(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); return 0; } @@ -92,11 +92,12 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, * Read the errno value from the child, if the exec failed, or get 0 if * the exec succeeded because the pipe fd was set as close-on-exec. */ - n = os_read_file(fds[0], &ret, sizeof(ret)); + n = read(fds[0], &ret, sizeof(ret)); if (n == 0) { ret = pid; } else { if (n < 0) { + n = -errno; printk("run_helper : read on pipe failed, ret = %d\n", -n); ret = n; diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 77d16023c28..c6378c6d10d 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -232,10 +232,9 @@ int __init create_tmp_file(unsigned long long len) zero = 0; - err = os_write_file(fd, &zero, 1); + err = write(fd, &zero, 1); if(err != 1){ - errno = -err; - perror("os_write_file"); + perror("write"); exit(1); } diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index a84a45843f8..92a7b59120d 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -42,10 +42,10 @@ unsigned long os_process_pc(int pid) proc_stat, -fd); return ARBITRARY_ADDR; } - err = os_read_file(fd, buf, sizeof(buf)); + CATCH_EINTR(err = read(fd, buf, sizeof(buf))); if(err < 0){ printk("os_process_pc - couldn't read '%s', err = %d\n", - proc_stat, -err); + proc_stat, errno); os_close_file(fd); return ARBITRARY_ADDR; } @@ -75,11 +75,11 @@ int os_process_parent(int pid) return FAILURE_PID; } - n = os_read_file(fd, data, sizeof(data)); + CATCH_EINTR(n = read(fd, data, sizeof(data))); os_close_file(fd); if(n < 0){ - printk("Couldn't read '%s', err = %d\n", stat, -n); + printk("Couldn't read '%s', err = %d\n", stat, errno); return FAILURE_PID; } diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 8ccf6a36f1c..8d4e0c6b8c9 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -69,11 +69,12 @@ static int write_sigio_thread(void *unused) p = &fds->poll[i]; if(p->revents == 0) continue; if(p->fd == sigio_private[1]){ - n = os_read_file(sigio_private[1], &c, sizeof(c)); + CATCH_EINTR(n = read(sigio_private[1], &c, + sizeof(c))); if(n != sizeof(c)) printk("write_sigio_thread : " "read on socket failed, " - "err = %d\n", -n); + "err = %d\n", errno); tmp = current_poll; current_poll = next_poll; next_poll = tmp; @@ -86,10 +87,10 @@ static int write_sigio_thread(void *unused) (fds->used - i) * sizeof(*fds->poll)); } - n = os_write_file(respond_fd, &c, sizeof(c)); + CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); if(n != sizeof(c)) printk("write_sigio_thread : write on socket " - "failed, err = %d\n", -n); + "failed, err = %d\n", errno); } } @@ -127,15 +128,15 @@ static void update_thread(void) char c; flags = set_signals(0); - n = os_write_file(sigio_private[0], &c, sizeof(c)); + n = write(sigio_private[0], &c, sizeof(c)); if(n != sizeof(c)){ - printk("update_thread : write failed, err = %d\n", -n); + printk("update_thread : write failed, err = %d\n", errno); goto fail; } - n = os_read_file(sigio_private[0], &c, sizeof(c)); + CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); if(n != sizeof(c)){ - printk("update_thread : read failed, err = %d\n", -n); + printk("update_thread : read failed, err = %d\n", errno); goto fail; } @@ -459,10 +460,10 @@ static void tty_output(int master, int slave) memset(buf, 0, sizeof(buf)); - while(os_write_file(master, buf, sizeof(buf)) > 0) ; + while(write(master, buf, sizeof(buf)) > 0) ; if(errno != EAGAIN) panic("tty_output : write failed, errno = %d\n", errno); - while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; + while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; if(got_sigio){ printk("Yes\n"); diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 470ec531aa5..6cdfda807b6 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -199,9 +200,11 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, .fd = phys_fd, .offset= offset } } } ); - ret = os_write_file(fd, &map, sizeof(map)); - if(ret != sizeof(map)) + CATCH_EINTR(ret = write(fd, &map, sizeof(map))); + if(ret != sizeof(map)){ + ret = -errno; printk("map : /proc/mm map failed, err = %d\n", -ret); + } else ret = 0; } else { @@ -231,9 +234,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, { .addr = (unsigned long) addr, .len = len } } } ); - ret = os_write_file(fd, &unmap, sizeof(unmap)); - if(ret != sizeof(unmap)) + CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap))); + if(ret != sizeof(unmap)){ + ret = -errno; printk("unmap - proc_mm write returned %d\n", ret); + } else ret = 0; } else { @@ -266,9 +271,11 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, .len = len, .prot = prot } } } ); - ret = os_write_file(fd, &protect, sizeof(protect)); - if(ret != sizeof(protect)) + CATCH_EINTR(ret = write(fd, &protect, sizeof(protect))); + if(ret != sizeof(protect)){ + ret = -errno; printk("protect failed, err = %d", -ret); + } else ret = 0; } else { diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 47852698d5e..5b1943dc15e 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -431,12 +431,13 @@ void map_stub_pages(int fd, unsigned long code, .fd = code_fd, .offset = code_offset } } }); - n = os_write_file(fd, &mmop, sizeof(mmop)); + CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); if(n != sizeof(mmop)){ + n = errno; printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", code, code_fd, (unsigned long long) code_offset); panic("map_stub_pages : /proc/mm map for code failed, " - "err = %d\n", -n); + "err = %d\n", n); } if ( stack ) { @@ -453,10 +454,10 @@ void map_stub_pages(int fd, unsigned long code, .fd = map_fd, .offset = map_offset } } }); - n = os_write_file(fd, &mmop, sizeof(mmop)); + CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); if(n != sizeof(mmop)) panic("map_stub_pages : /proc/mm map for data failed, " - "err = %d\n", -n); + "err = %d\n", errno); } } diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c index ae9adb1b74f..d11a55baa6b 100644 --- a/arch/um/os-Linux/tty_log.c +++ b/arch/um/os-Linux/tty_log.c @@ -53,8 +53,8 @@ int open_tty_log(void *tty, void *current_tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); - os_write_file(tty_log_fd, ¤t_tty, data.len); + write(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, ¤t_tty, data.len); return tty_log_fd; } @@ -83,7 +83,7 @@ void close_tty_log(int fd, void *tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, &data, sizeof(data)); return; } os_close_file(fd); @@ -98,10 +98,10 @@ static int log_chunk(int fd, const char *buf, int len) try = (len > sizeof(chunk)) ? sizeof(chunk) : len; missed = copy_from_user_proc(chunk, (char *) buf, try); try -= missed; - n = os_write_file(fd, chunk, try); + n = write(fd, chunk, try); if(n != try) { if(n < 0) - return n; + return -errno; return -EIO; } if(missed != 0) @@ -130,7 +130,7 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) .direction = direction, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, &data, sizeof(data)); } return log_chunk(fd, buf, len); @@ -161,7 +161,7 @@ void log_exec(char **argv, void *tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - os_write_file(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, &data, sizeof(data)); for(ptr = argv; ; ptr++){ if(copy_from_user_proc(&arg, ptr, sizeof(arg))) -- cgit v1.2.3 From a0044bdf60c212366a314da09ca624cb315906e2 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:36 -0700 Subject: uml: batch I/O requests Send as many I/O requests to the I/O thread as possible, even though it will still only handle one at a time. This provides an opportunity to reduce latency by starting one request before the previous one has been finished in the driver. Request handling is somewhat modernized by requesting sg pieces of a request and handling them separately, finishing off the entire request after all the pieces are done. When a request queue stalls, normally because its pipe to the I/O thread is full, it is put on the restart list. This list is processed by starting up the queues on it whenever there is some indication that progress might be possible again. Currently, this happens in the driver interrupt routine. Some requests have been finished, so there is likely to be room in the pipe again. This almost doubles throughput when copying data between devices, but made no noticable difference on anything else I tried. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 176 +++++++++++++++++++++++++-------------------- 1 file changed, 99 insertions(+), 77 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 6d163c9e288..5ef47b73ce9 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -149,7 +149,10 @@ struct cow { int data_offset; }; +#define MAX_SG 64 + struct ubd { + struct list_head restart; /* name (and fd, below) of the file opened for writing, either the * backing or the cow file. */ char *file; @@ -164,7 +167,9 @@ struct ubd { struct platform_device pdev; struct request_queue *queue; spinlock_t lock; - int active; + struct scatterlist sg[MAX_SG]; + struct request *request; + int start_sg, end_sg; }; #define DEFAULT_COW { \ @@ -186,7 +191,9 @@ struct ubd { .shared = 0, \ .cow = DEFAULT_COW, \ .lock = SPIN_LOCK_UNLOCKED, \ - .active = 0, \ + .request = NULL, \ + .start_sg = 0, \ + .end_sg = 0, \ } /* Protected by ubd_lock */ @@ -466,60 +473,67 @@ static void do_ubd_request(request_queue_t * q); /* Only changed by ubd_init, which is an initcall. */ int thread_fd = -1; -/* call ubd_finish if you need to serialize */ -static void __ubd_finish(struct request *req, int error) +static void ubd_end_request(struct request *req, int bytes, int uptodate) { - int nsect; - - if(error){ - end_request(req, 0); - return; + if (!end_that_request_first(req, uptodate, bytes >> 9)) { + struct ubd *dev = req->rq_disk->private_data; + unsigned long flags; + + add_disk_randomness(req->rq_disk); + spin_lock_irqsave(&dev->lock, flags); + end_that_request_last(req, uptodate); + spin_unlock_irqrestore(&dev->lock, flags); } - nsect = req->current_nr_sectors; - req->sector += nsect; - req->buffer += nsect << 9; - req->errors = 0; - req->nr_sectors -= nsect; - req->current_nr_sectors = 0; - end_request(req, 1); } /* Callable only from interrupt context - otherwise you need to do * spin_lock_irq()/spin_lock_irqsave() */ -static inline void ubd_finish(struct request *req, int error) +static inline void ubd_finish(struct request *req, int bytes) { - struct ubd *dev = req->rq_disk->private_data; - - spin_lock(&dev->lock); - __ubd_finish(req, error); - spin_unlock(&dev->lock); + if(bytes < 0){ + ubd_end_request(req, 0, 0); + return; + } + ubd_end_request(req, bytes, 1); } +static LIST_HEAD(restart); + /* XXX - move this inside ubd_intr. */ /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { struct io_thread_req req; struct request *rq; - struct ubd *dev; + struct ubd *ubd; + struct list_head *list, *next_ele; + unsigned long flags; int n; - n = os_read_file_k(thread_fd, &req, sizeof(req)); - if(n != sizeof(req)){ - printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " - "err = %d\n", os_getpid(), -n); - return; - } - - rq = req.req; - dev = rq->rq_disk->private_data; - dev->active = 0; + while(1){ + n = os_read_file_k(thread_fd, &req, sizeof(req)); + if(n != sizeof(req)){ + if(n == -EAGAIN) + break; + printk(KERN_ERR "spurious interrupt in ubd_handler, " + "err = %d\n", -n); + return; + } - ubd_finish(rq, req.error); + rq = req.req; + rq->nr_sectors -= req.length >> 9; + if(rq->nr_sectors == 0) + ubd_finish(rq, rq->hard_nr_sectors << 9); + } reactivate_fd(thread_fd, UBD_IRQ); - spin_lock(&dev->lock); - do_ubd_request(dev->queue); - spin_unlock(&dev->lock); + + list_for_each_safe(list, next_ele, &restart){ + ubd = container_of(list, struct ubd, restart); + list_del_init(&ubd->restart); + spin_lock_irqsave(&ubd->lock, flags); + do_ubd_request(ubd->queue); + spin_unlock_irqrestore(&ubd->lock, flags); + } } static irqreturn_t ubd_intr(int irq, void *dev) @@ -684,6 +698,8 @@ static int ubd_add(int n, char **error_out) ubd_dev->size = ROUND_BLOCK(ubd_dev->size); + INIT_LIST_HEAD(&ubd_dev->restart); + err = -ENOMEM; ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock); if (ubd_dev->queue == NULL) { @@ -692,6 +708,7 @@ static int ubd_add(int n, char **error_out) } ubd_dev->queue->queuedata = ubd_dev; + blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; @@ -1029,26 +1046,16 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, } /* Called with dev->lock held */ -static int prepare_request(struct request *req, struct io_thread_req *io_req) +static void prepare_request(struct request *req, struct io_thread_req *io_req, + unsigned long long offset, int page_offset, + int len, struct page *page) { struct gendisk *disk = req->rq_disk; struct ubd *ubd_dev = disk->private_data; - __u64 offset; - int len; - - /* This should be impossible now */ - if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){ - printk("Write attempted on readonly ubd device %s\n", - disk->disk_name); - end_request(req, 0); - return(1); - } - - offset = ((__u64) req->sector) << 9; - len = req->current_nr_sectors << 9; io_req->req = req; - io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; + io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : + ubd_dev->fd; io_req->fds[1] = ubd_dev->fd; io_req->cow_offset = -1; io_req->offset = offset; @@ -1059,14 +1066,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; io_req->offsets[0] = 0; io_req->offsets[1] = ubd_dev->cow.data_offset; - io_req->buffer = req->buffer; + io_req->buffer = page_address(page) + page_offset; io_req->sectorsize = 1 << 9; if(ubd_dev->cow.file != NULL) - cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, - ubd_dev->cow.bitmap_len); + cowify_req(io_req, ubd_dev->cow.bitmap, + ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len); - return(0); } /* Called with dev->lock held */ @@ -1074,29 +1080,45 @@ static void do_ubd_request(request_queue_t *q) { struct io_thread_req io_req; struct request *req; - int err, n; - - if(thread_fd == -1){ - while((req = elv_next_request(q)) != NULL){ - err = prepare_request(req, &io_req); - if(!err){ - do_io(&io_req); - __ubd_finish(req, io_req.error); - } - } - } - else { + int n; + + while(1){ struct ubd *dev = q->queuedata; - if(dev->active || (req = elv_next_request(q)) == NULL) - return; - err = prepare_request(req, &io_req); - if(!err){ - dev->active = 1; - n = os_write_file_k(thread_fd, &io_req, sizeof(io_req)); - if(n != sizeof(io_req)) - printk("write to io thread failed, " - "errno = %d\n", -n); + if(dev->end_sg == 0){ + struct request *req = elv_next_request(q); + if(req == NULL) + return; + + dev->request = req; + blkdev_dequeue_request(req); + dev->start_sg = 0; + dev->end_sg = blk_rq_map_sg(q, req, dev->sg); + } + + req = dev->request; + while(dev->start_sg < dev->end_sg){ + struct scatterlist *sg = &dev->sg[dev->start_sg]; + + prepare_request(req, &io_req, + (unsigned long long) req->sector << 9, + sg->offset, sg->length, sg->page); + + n = os_write_file_k(thread_fd, (char *) &io_req, + sizeof(io_req)); + if(n != sizeof(io_req)){ + if(n != -EAGAIN) + printk("write to io thread failed, " + "errno = %d\n", -n); + else if(list_empty(&dev->restart)) + list_add(&dev->restart, &restart); + return; + } + + req->sector += sg->length >> 9; + dev->start_sg++; } + dev->end_sg = 0; + dev->request = NULL; } } -- cgit v1.2.3 From 2adcec2197897365e0a0f657f1098cbfdb44bc8b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:37 -0700 Subject: uml: send pointers instead of structures to I/O thread Instead of writing entire structures between UML and the I/O thread, we send pointers. This cuts down on the amount of data being copied and possibly allows more requests to be pending between the two. This requires that the requests be kmalloced and freed instead of living on the stack. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 5ef47b73ce9..9200a457eb9 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -503,7 +503,7 @@ static LIST_HEAD(restart); /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req req; + struct io_thread_req *req; struct request *rq; struct ubd *ubd; struct list_head *list, *next_ele; @@ -511,7 +511,8 @@ static void ubd_handler(void) int n; while(1){ - n = os_read_file_k(thread_fd, &req, sizeof(req)); + n = os_read_file_k(thread_fd, &req, + sizeof(struct io_thread_req *)); if(n != sizeof(req)){ if(n == -EAGAIN) break; @@ -520,10 +521,11 @@ static void ubd_handler(void) return; } - rq = req.req; - rq->nr_sectors -= req.length >> 9; + rq = req->req; + rq->nr_sectors -= req->length >> 9; if(rq->nr_sectors == 0) ubd_finish(rq, rq->hard_nr_sectors << 9); + kfree(req); } reactivate_fd(thread_fd, UBD_IRQ); @@ -1078,7 +1080,7 @@ static void prepare_request(struct request *req, struct io_thread_req *io_req, /* Called with dev->lock held */ static void do_ubd_request(request_queue_t *q) { - struct io_thread_req io_req; + struct io_thread_req *io_req; struct request *req; int n; @@ -1099,13 +1101,20 @@ static void do_ubd_request(request_queue_t *q) while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; - prepare_request(req, &io_req, + io_req = kmalloc(sizeof(struct io_thread_req), + GFP_KERNEL | GFP_ATOMIC); + if(io_req == NULL){ + if(list_empty(&dev->restart)) + list_add(&dev->restart, &restart); + return; + } + prepare_request(req, io_req, (unsigned long long) req->sector << 9, sg->offset, sg->length, sg->page); - n = os_write_file_k(thread_fd, (char *) &io_req, - sizeof(io_req)); - if(n != sizeof(io_req)){ + n = os_write_file_k(thread_fd, &io_req, + sizeof(struct io_thread_req *)); + if(n != sizeof(struct io_thread_req *)){ if(n != -EAGAIN) printk("write to io thread failed, " "errno = %d\n", -n); @@ -1437,13 +1446,14 @@ static int io_count = 0; int io_thread(void *arg) { - struct io_thread_req req; + struct io_thread_req *req; int n; ignore_sigwinch_sig(); while(1){ - n = os_read_file_k(kernel_fd, &req, sizeof(req)); - if(n != sizeof(req)){ + n = os_read_file_k(kernel_fd, &req, + sizeof(struct io_thread_req *)); + if(n != sizeof(struct io_thread_req *)){ if(n < 0) printk("io_thread - read failed, fd = %d, " "err = %d\n", kernel_fd, -n); @@ -1454,9 +1464,10 @@ int io_thread(void *arg) continue; } io_count++; - do_io(&req); - n = os_write_file_k(kernel_fd, &req, sizeof(req)); - if(n != sizeof(req)) + do_io(req); + n = os_write_file_k(kernel_fd, &req, + sizeof(struct io_thread_req *)); + if(n != sizeof(struct io_thread_req *)) printk("io_thread - write failed, fd = %d, err = %d\n", kernel_fd, -n); } -- cgit v1.2.3 From 990c55871b655156ffd7787af791be977d946ef6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 6 May 2007 14:51:38 -0700 Subject: uml: fixup allocation in the ubd driver Sanitise gfp flags; it actually is an atomic context, so drop the GFP_KERNEL part. Signed-off-by: Peter Zijlstra Acked-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 9200a457eb9..88a246edb61 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1102,7 +1102,7 @@ static void do_ubd_request(request_queue_t *q) struct scatterlist *sg = &dev->sg[dev->start_sg]; io_req = kmalloc(sizeof(struct io_thread_req), - GFP_KERNEL | GFP_ATOMIC); + GFP_ATOMIC); if(io_req == NULL){ if(list_empty(&dev->restart)) list_add(&dev->restart, &restart); -- cgit v1.2.3 From 63843c265fd0e0c7894f713e0db5777560e756ae Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:39 -0700 Subject: uml: dump core on panic Dump core after a panic. This will provide better debugging information than is currently available. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 1 + arch/um/kernel/um_arch.c | 2 +- arch/um/os-Linux/util.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index b463170a530..901804db3c3 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -279,6 +279,7 @@ extern int raw(int fd); extern void setup_machinename(char *machine_out); extern void setup_hostinfo(char *buf, int len); extern int setjmp_wrapper(void (*proc)(void *, void *), ...); +extern void os_dump_core(void); /* time.c */ #define BILLION (1000 * 1000 * 1000) diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 9bf31533a8f..1cf954a47fd 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -474,7 +474,7 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1, show_regs(&(current->thread.regs)); bust_spinlocks(0); uml_exitcode = 1; - machine_halt(); + os_dump_core(); return 0; } diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 48bc4927b99..c307a89ed25 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -119,3 +119,9 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...) va_end(args); return n; } + +void os_dump_core(void) +{ + signal(SIGSEGV, SIG_DFL); + abort(); +} -- cgit v1.2.3 From 77f6af778dc23514d897f4fdc7935329285ecb1b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:40 -0700 Subject: uml: don't try to handle signals on initial process stack Code running on the initial UML stack can't receive or process signals since current must be valid when IRQs are handled, and there is no current for this stack. So, instead of using UML_LONGJMP and UML_SETJMP, which are careful to save and restore signal state, and, as a side-effect, handle any deferred signals, start_idle_thread must use the bare equivalents, which don't do anything with signals. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/skas/process.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 5b1943dc15e..1f39f2bf7ce 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -494,7 +494,15 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, SIGVTALRM, -1); - n = UML_SETJMP(&initial_jmpbuf); + /* + * Can't use UML_SETJMP or UML_LONGJMP here because they save + * and restore signals, with the possible side-effect of + * trying to handle any signals which came when they were + * blocked, which can't be done on this stack. + * Signals must be blocked when jumping back here and restored + * after returning to the jumper. + */ + n = setjmp(initial_jmpbuf); switch(n){ case INIT_JMP_NEW_THREAD: (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; @@ -504,7 +512,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) break; case INIT_JMP_CALLBACK: (*cb_proc)(cb_arg); - UML_LONGJMP(cb_back, 1); + longjmp(*cb_back, 1); break; case INIT_JMP_HALT: kmalloc_ok = 0; @@ -515,7 +523,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) default: panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); } - UML_LONGJMP(switch_buf, 1); + longjmp(*switch_buf, 1); } void initial_thread_cb_skas(void (*proc)(void *), void *arg) -- cgit v1.2.3 From fda83a99b2b49016b9d7ed562745969db25c4ef9 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:41 -0700 Subject: uml: change remaining callers of os_{read_write}_file Convert all remaining os_{read_write}_file users to use the simple {read,write} wrappers, os_{read_write}_file_k. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 4 ++-- arch/um/drivers/cow_sys.h | 2 +- arch/um/drivers/net_user.c | 6 +++--- arch/um/drivers/ubd_kern.c | 2 +- arch/um/kernel/initrd.c | 2 +- arch/um/kernel/physmem.c | 2 +- arch/um/sys-i386/bugs.c | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 3aa35161176..92e069e8253 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -98,7 +98,7 @@ int generic_read(int fd, char *c_out, void *unused) { int n; - n = os_read_file(fd, c_out, sizeof(*c_out)); + n = os_read_file_k(fd, c_out, sizeof(*c_out)); if(n == -EAGAIN) return 0; @@ -111,7 +111,7 @@ int generic_read(int fd, char *c_out, void *unused) int generic_write(int fd, const char *buf, int n, void *unused) { - return os_write_file(fd, buf, n); + return os_write_file_k(fd, buf, n); } int generic_window_size(int fd, void *unused, unsigned short *rows_out, diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index c702943769c..3255583eccb 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -35,7 +35,7 @@ static inline int cow_file_size(char *file, unsigned long long *size_out) static inline int cow_write_file(int fd, void *buf, int size) { - return(os_write_file(fd, buf, size)); + return(os_write_file_k(fd, buf, size)); } #endif diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 2dc57a37e4b..8bc6688c4f0 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -73,7 +73,7 @@ void read_output(int fd, char *output, int len) while(remain != 0){ expected = (remain < len) ? remain : len; - ret = os_read_file(fd, output, expected); + ret = os_read_file_k(fd, output, expected); if (ret != expected) { str = "data"; goto err; @@ -94,7 +94,7 @@ int net_read(int fd, void *buf, int len) { int n; - n = os_read_file(fd, buf, len); + n = os_read_file_k(fd, buf, len); if(n == -EAGAIN) return 0; @@ -122,7 +122,7 @@ int net_write(int fd, void *buf, int len) { int n; - n = os_write_file(fd, buf, len); + n = os_write_file_k(fd, buf, len); if(n == -EAGAIN) return 0; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 88a246edb61..2a00203e101 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1246,7 +1246,7 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len) if(err < 0) return(err); - err = os_read_file(fd, buf, len); + err = os_read_file_k(fd, buf, len); if(err < 0) return(err); diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index 6ab1539108e..bf3dd965986 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -55,7 +55,7 @@ int load_initrd(char *filename, void *buf, int size) printk("Opening '%s' failed - err = %d\n", filename, -fd); return(-1); } - n = os_read_file(fd, buf, size); + n = os_read_file_k(fd, buf, size); if(n != size){ printk("Read of %d bytes from '%s' failed, err = %d\n", size, filename, -n); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index a9856209006..77021a627da 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -211,7 +211,7 @@ void physmem_forget_descriptor(int fd) panic("physmem_forget_descriptor - failed to seek " "to %lld in fd %d, error = %d\n", offset, fd, -err); - err = os_read_file(fd, addr, PAGE_SIZE); + err = os_read_file_k(fd, addr, PAGE_SIZE); if(err < 0) panic("physmem_forget_descriptor - failed to read " "from fd %d to 0x%p, error = %d\n", diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index 74fd062b201..f5dfe49c844 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -28,7 +28,7 @@ static char token(int fd, char *buf, int len, char stop) ptr = buf; end = &buf[len]; do { - n = os_read_file(fd, ptr, sizeof(*ptr)); + n = os_read_file_k(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ if(n == 0) -- cgit v1.2.3 From dc764e5087bceeb26714bb7975b711062b39d804 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:41 -0700 Subject: uml: formatting fixes around os_{read_write}_file callers Formatting fixes ahead of renaming os_{read_write}_file_k to os_{read_write}_file and fixing all the callers. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 11 ---- arch/um/drivers/cow_sys.h | 17 ++---- arch/um/drivers/ubd_kern.c | 124 ++++++++++++++++++++++---------------------- arch/um/kernel/initrd.c | 32 ++++++------ arch/um/kernel/smp.c | 25 +++------ 5 files changed, 89 insertions(+), 120 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index d226f103462..a15be1720e0 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -203,14 +203,3 @@ void register_winch(int fd, struct tty_struct *tty) } } } - -/* - * 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: - */ diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index 3255583eccb..aa7bef9c38d 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -8,7 +8,7 @@ static inline void *cow_malloc(int size) { - return(um_kmalloc(size)); + return um_kmalloc(size); } static inline void cow_free(void *ptr) @@ -20,29 +20,22 @@ static inline void cow_free(void *ptr) static inline char *cow_strdup(char *str) { - return(uml_strdup(str)); + return uml_strdup(str); } static inline int cow_seek_file(int fd, __u64 offset) { - return(os_seek_file(fd, offset)); + return os_seek_file(fd, offset); } static inline int cow_file_size(char *file, unsigned long long *size_out) { - return(os_file_size(file, size_out)); + return os_file_size(file, size_out); } static inline int cow_write_file(int fd, void *buf, int size) { - return(os_write_file_k(fd, buf, size)); + return os_write_file_k(fd, buf, size); } #endif - -/* - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 2a00203e101..614fe25a31b 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -89,7 +89,7 @@ static inline int ubd_test_bit(__u64 bit, unsigned char *data) bits = sizeof(data[0]) * 8; n = bit / bits; off = bit % bits; - return((data[n] & (1 << off)) != 0); + return (data[n] & (1 << off)) != 0; } static inline void ubd_set_bit(__u64 bit, unsigned char *data) @@ -146,7 +146,7 @@ struct cow { unsigned long *bitmap; unsigned long bitmap_len; int bitmap_offset; - int data_offset; + int data_offset; }; #define MAX_SG 64 @@ -174,10 +174,10 @@ struct ubd { #define DEFAULT_COW { \ .file = NULL, \ - .fd = -1, \ - .bitmap = NULL, \ + .fd = -1, \ + .bitmap = NULL, \ .bitmap_offset = 0, \ - .data_offset = 0, \ + .data_offset = 0, \ } #define DEFAULT_UBD { \ @@ -187,9 +187,9 @@ struct ubd { .size = -1, \ .boot_openflags = OPEN_FLAGS, \ .openflags = OPEN_FLAGS, \ - .no_cow = 0, \ + .no_cow = 0, \ .shared = 0, \ - .cow = DEFAULT_COW, \ + .cow = DEFAULT_COW, \ .lock = SPIN_LOCK_UNLOCKED, \ .request = NULL, \ .start_sg = 0, \ @@ -249,7 +249,7 @@ static void make_ide_entries(char *dev_name) static int fake_ide_setup(char *str) { fake_ide = 1; - return(1); + return 1; } __setup("fake_ide", fake_ide_setup); @@ -267,7 +267,7 @@ static int parse_unit(char **ptr) if(isdigit(*str)) { n = simple_strtoul(str, &end, 0); if(end == str) - return(-1); + return -1; *ptr = end; } else if (('a' <= *str) && (*str <= 'z')) { @@ -275,7 +275,7 @@ static int parse_unit(char **ptr) str++; *ptr = str; } - return(n); + return n; } /* If *index_out == -1 at exit, the passed option was a general one; @@ -442,7 +442,7 @@ static int udb_setup(char *str) { printk("udb%s specified on command line is almost certainly a ubd -> " "udb TYPO\n", str); - return(1); + return 1; } __setup("udb", udb_setup); @@ -541,7 +541,7 @@ static void ubd_handler(void) static irqreturn_t ubd_intr(int irq, void *dev) { ubd_handler(); - return(IRQ_HANDLED); + return IRQ_HANDLED; } /* Only changed by ubd_init, which is an initcall. */ @@ -560,7 +560,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) char *file; file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; - return(os_file_size(file, size_out)); + return os_file_size(file, size_out); } static void ubd_close_dev(struct ubd *ubd_dev) @@ -632,10 +632,10 @@ static int ubd_open_dev(struct ubd *ubd_dev) if(err < 0) goto error; ubd_dev->cow.fd = err; } - return(0); + return 0; error: os_close_file(ubd_dev->fd); - return(err); + return err; } static void ubd_device_release(struct device *dev) @@ -653,7 +653,7 @@ static int ubd_disk_register(int major, u64 size, int unit, disk = alloc_disk(1 << UBD_SHIFT); if(disk == NULL) - return(-ENOMEM); + return -ENOMEM; disk->major = major; disk->first_minor = unit << UBD_SHIFT; @@ -758,14 +758,14 @@ static int ubd_config(char *str, char **error_out) goto err_free; } - mutex_lock(&ubd_lock); + mutex_lock(&ubd_lock); ret = ubd_add(n, error_out); if (ret) ubd_devs[n].file = NULL; - mutex_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); out: - return ret; + return ret; err_free: kfree(str); @@ -780,7 +780,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) n = parse_unit(&name); if((n >= MAX_DEV) || (n < 0)){ *error_out = "ubd_get_config : device number out of range"; - return(-1); + return -1; } ubd_dev = &ubd_devs[n]; @@ -801,17 +801,17 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) out: mutex_unlock(&ubd_lock); - return(len); + return len; } static int ubd_id(char **str, int *start_out, int *end_out) { - int n; + int n; n = parse_unit(str); - *start_out = 0; - *end_out = MAX_DEV - 1; - return n; + *start_out = 0; + *end_out = MAX_DEV - 1; + return n; } static int ubd_remove(int n, char **error_out) @@ -832,7 +832,7 @@ static int ubd_remove(int n, char **error_out) if(ubd_dev->count > 0) goto out; - ubd_gendisk[n] = NULL; + ubd_gendisk[n] = NULL; if(disk != NULL){ del_gendisk(disk); put_disk(disk); @@ -858,7 +858,7 @@ static struct mc_device ubd_mc = { .list = LIST_HEAD_INIT(ubd_mc.list), .name = "ubd", .config = ubd_config, - .get_config = ubd_get_config, + .get_config = ubd_get_config, .id = ubd_id, .remove = ubd_remove, }; @@ -880,7 +880,7 @@ static int __init ubd0_init(void) ubd_dev->file = "root_fs"; mutex_unlock(&ubd_lock); - return(0); + return 0; } __initcall(ubd0_init); @@ -908,14 +908,14 @@ static int __init ubd_init(void) return -1; } platform_driver_register(&ubd_driver); - mutex_lock(&ubd_lock); + mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ err = ubd_add(i, &error); if(err) printk(KERN_ERR "Failed to initialize ubd device %d :" "%s\n", i, error); } - mutex_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return 0; } @@ -939,7 +939,7 @@ static int __init ubd_driver_init(void){ "ubd : Failed to start I/O thread (errno = %d) - " "falling back to synchronous I/O\n", -io_pid); io_pid = -1; - return(0); + return 0; } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, IRQF_DISABLED, "ubd", ubd_devs); @@ -974,7 +974,7 @@ static int ubd_open(struct inode *inode, struct file *filp) err = -EROFS; }*/ out: - return(err); + return err; } static int ubd_release(struct inode * inode, struct file * file) @@ -984,7 +984,7 @@ static int ubd_release(struct inode * inode, struct file * file) if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); - return(0); + return 0; } static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, @@ -1040,7 +1040,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) ubd_set_bit(i, (unsigned char *) &req->sector_mask); - } + } } else cowify_bitmap(req->offset, req->length, &req->sector_mask, &req->cow_offset, bitmap, bitmap_offset, @@ -1157,21 +1157,21 @@ static int ubd_ioctl(struct inode * inode, struct file * file, ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); if(copy_to_user((char __user *) arg, (char *) &ubd_id, sizeof(ubd_id))) - return(-EFAULT); - return(0); + return -EFAULT; + return 0; case CDROMVOLREAD: if(copy_from_user(&volume, (char __user *) arg, sizeof(volume))) - return(-EFAULT); + return -EFAULT; volume.channel0 = 255; volume.channel1 = 255; volume.channel2 = 255; volume.channel3 = 255; if(copy_to_user((char __user *) arg, &volume, sizeof(volume))) - return(-EFAULT); - return(0); + return -EFAULT; + return 0; } - return(-EINVAL); + return -EINVAL; } static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow) @@ -1213,29 +1213,29 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime) if(err < 0){ printk("Failed to get modification time of backing file " "\"%s\", err = %d\n", file, -err); - return(err); + return err; } err = os_file_size(file, &actual); if(err < 0){ printk("Failed to get size of backing file \"%s\", " "err = %d\n", file, -err); - return(err); + return err; } - if(actual != size){ + if(actual != size){ /*__u64 can be a long on AMD64 and with %lu GCC complains; so * the typecast.*/ printk("Size mismatch (%llu vs %llu) of COW header vs backing " "file\n", (unsigned long long) size, actual); - return(-EINVAL); + return -EINVAL; } if(modtime != mtime){ printk("mtime mismatch (%ld vs %ld) of COW header vs backing " "file\n", mtime, modtime); - return(-EINVAL); + return -EINVAL; } - return(0); + return 0; } int read_cow_bitmap(int fd, void *buf, int offset, int len) @@ -1244,13 +1244,13 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len) err = os_seek_file(fd, offset); if(err < 0) - return(err); + return err; - err = os_read_file_k(fd, buf, len); + err = os_read_file(fd, buf, len); if(err < 0) - return(err); + return err; - return(0); + return 0; } int open_ubd_file(char *file, struct openflags *openflags, int shared, @@ -1268,14 +1268,14 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, if (fd < 0) { if ((fd == -ENOENT) && (create_cow_out != NULL)) *create_cow_out = 1; - if (!openflags->w || - ((fd != -EROFS) && (fd != -EACCES))) + if (!openflags->w || + ((fd != -EROFS) && (fd != -EACCES))) return fd; openflags->w = 0; fd = os_open_file(file, *openflags, mode); if (fd < 0) return fd; - } + } if(shared) printk("Not locking \"%s\" on the host\n", file); @@ -1289,7 +1289,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, /* Successful return case! */ if(backing_file_out == NULL) - return(fd); + return fd; err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, &size, §orsize, &align, bitmap_offset_out); @@ -1299,7 +1299,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, goto out_close; } if(err) - return(fd); + return fd; asked_switch = path_requires_switch(*backing_file_out, backing_file, file); @@ -1322,7 +1322,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, bitmap_len_out, data_offset_out); - return fd; + return fd; out_close: os_close_file(fd); return err; @@ -1347,10 +1347,10 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, bitmap_offset_out, bitmap_len_out, data_offset_out); if(!err) - return(fd); + return fd; os_close_file(fd); out: - return(err); + return err; } static int update_bitmap(struct io_thread_req *req) @@ -1358,12 +1358,12 @@ static int update_bitmap(struct io_thread_req *req) int n; if(req->cow_offset == -1) - return(0); + return 0; n = os_seek_file(req->fds[1], req->cow_offset); if(n < 0){ printk("do_io - bitmap lseek failed : err = %d\n", -n); - return(1); + return 1; } n = os_write_file_k(req->fds[1], &req->bitmap_words, @@ -1371,10 +1371,10 @@ static int update_bitmap(struct io_thread_req *req) if(n != sizeof(req->bitmap_words)){ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, req->fds[1]); - return(1); + return 1; } - return(0); + return 0; } void do_io(struct io_thread_req *req) diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index bf3dd965986..cff73faae99 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -21,12 +21,20 @@ static int __init read_initrd(void) long long size; int err; - if(initrd == NULL) return 0; + if(initrd == NULL) + return 0; + err = os_file_size(initrd, &size); - if(err) return 0; + if(err) + return 0; + area = alloc_bootmem(size); - if(area == NULL) return 0; - if(load_initrd(initrd, area, size) == -1) return 0; + if(area == NULL) + return 0; + + if(load_initrd(initrd, area, size) == -1) + return 0; + initrd_start = (unsigned long) area; initrd_end = initrd_start + size; return 0; @@ -53,25 +61,15 @@ int load_initrd(char *filename, void *buf, int size) fd = os_open_file(filename, of_read(OPENFLAGS()), 0); if(fd < 0){ printk("Opening '%s' failed - err = %d\n", filename, -fd); - return(-1); + return -1; } n = os_read_file_k(fd, buf, size); if(n != size){ printk("Read of %d bytes from '%s' failed, err = %d\n", size, filename, -n); - return(-1); + return -1; } os_close_file(fd); - return(0); + return 0; } -/* - * 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: - */ diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 47b690893c0..9ac56212465 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -89,7 +89,7 @@ static int idle_proc(void *cpup) cpu_set(cpu, cpu_online_map); default_idle(); - return(0); + return 0; } static struct task_struct *idle_thread(int cpu) @@ -97,8 +97,8 @@ static struct task_struct *idle_thread(int cpu) struct task_struct *new_task; unsigned char c; - current->thread.request.u.thread.proc = idle_proc; - current->thread.request.u.thread.arg = (void *) cpu; + current->thread.request.u.thread.proc = idle_proc; + current->thread.request.u.thread.arg = (void *) cpu; new_task = fork_idle(cpu); if(IS_ERR(new_task)) panic("copy_process failed in idle_thread, error = %ld", @@ -111,7 +111,7 @@ static struct task_struct *idle_thread(int cpu) CHOOSE_MODE(os_write_file_k(new_task->thread.mode.tt.switch_pipe[1], &c, sizeof(c)), ({ panic("skas mode doesn't support SMP"); })); - return(new_task); + return new_task; } void smp_prepare_cpus(unsigned int maxcpus) @@ -162,13 +162,13 @@ int __cpu_up(unsigned int cpu) cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) mb(); - return(0); + return 0; } int setup_profiling_timer(unsigned int multiplier) { printk(KERN_INFO "setup_profiling_timer\n"); - return(0); + return 0; } void smp_call_function_slave(int cpu); @@ -204,7 +204,7 @@ void IPI_handler(int cpu) int hard_smp_processor_id(void) { - return(pid_to_processor_id(os_getpid())); + return pid_to_processor_id(os_getpid()); } static DEFINE_SPINLOCK(call_lock); @@ -253,14 +253,3 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, } #endif - -/* - * 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: - */ -- cgit v1.2.3 From a263672424e591067e42e1d8371e56927fe73af8 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:42 -0700 Subject: uml: remove debugging remnants I accidentally left the remnants of some debugging in an earlier patch. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tlb.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 153dec13cf9..e201ccf0ec8 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -235,9 +235,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, unsigned long addr = start_addr, next; int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; void *flush = NULL; - unsigned long long start_time, end_time; - start_time = os_nsecs(); ops[0].type = NONE; pgd = pgd_offset(mm, addr); do { @@ -254,7 +252,6 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, &op_index, force, mmu, &flush, do_ops); } while (pgd++, addr = next, ((addr != end_addr) && !ret)); - end_time = os_nsecs(); log_info("total flush time - %Ld nsecs\n", end_time - start_time); if(!ret) -- cgit v1.2.3 From a6ea4cceed18edebe1eb6001cb9e0f88cd741a6c Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:43 -0700 Subject: uml: rename os_{read_write}_file_k back to os_{read_write}_file Rename os_{read_write}_file_k back to os_{read_write}_file, delete the originals and their bogus infrastructure, and fix all the callers. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 4 ++-- arch/um/drivers/chan_user.c | 10 ++++---- arch/um/drivers/cow_sys.h | 2 +- arch/um/drivers/daemon_user.c | 4 ++-- arch/um/drivers/harddog_user.c | 4 ++-- arch/um/drivers/hostaudio_kern.c | 4 ++-- arch/um/drivers/net_user.c | 8 +++---- arch/um/drivers/port_kern.c | 2 +- arch/um/drivers/random.c | 2 +- arch/um/drivers/ubd_kern.c | 20 ++++++++-------- arch/um/include/os.h | 2 -- arch/um/kernel/initrd.c | 2 +- arch/um/kernel/ksyms.c | 2 -- arch/um/kernel/physmem.c | 4 ++-- arch/um/kernel/sigio.c | 2 +- arch/um/kernel/smp.c | 12 +++++----- arch/um/kernel/tt/process_kern.c | 6 ++--- arch/um/kernel/tt/ptproxy/proxy.c | 8 +++---- arch/um/kernel/tt/tracer.c | 2 +- arch/um/os-Linux/file.c | 50 --------------------------------------- arch/um/sys-i386/bugs.c | 4 ++-- arch/um/sys-i386/ldt.c | 2 +- 22 files changed, 51 insertions(+), 105 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 92e069e8253..3aa35161176 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -98,7 +98,7 @@ int generic_read(int fd, char *c_out, void *unused) { int n; - n = os_read_file_k(fd, c_out, sizeof(*c_out)); + n = os_read_file(fd, c_out, sizeof(*c_out)); if(n == -EAGAIN) return 0; @@ -111,7 +111,7 @@ int generic_read(int fd, char *c_out, void *unused) int generic_write(int fd, const char *buf, int n, void *unused) { - return os_write_file_k(fd, buf, n); + return os_write_file(fd, buf, n); } int generic_window_size(int fd, void *unused, unsigned short *rows_out, diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index a15be1720e0..13f0bf852b2 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -85,7 +85,7 @@ static int winch_thread(void *arg) pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; - count = os_write_file_k(pipe_fd, &c, sizeof(c)); + count = os_write_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to write synchronization " "byte, err = %d\n", -count); @@ -120,7 +120,7 @@ static int winch_thread(void *arg) * host - since they are not different kernel threads, we cannot use * kernel semaphores. We don't use SysV semaphores because they are * persistent. */ - count = os_read_file_k(pipe_fd, &c, sizeof(c)); + count = os_read_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to read synchronization byte, " "err = %d\n", -count); @@ -130,7 +130,7 @@ static int winch_thread(void *arg) * are blocked.*/ sigsuspend(&sigs); - count = os_write_file_k(pipe_fd, &c, sizeof(c)); + count = os_write_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : write failed, err = %d\n", -count); @@ -162,7 +162,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) } *fd_out = fds[0]; - n = os_read_file_k(fds[0], &c, sizeof(c)); + n = os_read_file(fds[0], &c, sizeof(c)); if(n != sizeof(c)){ printk("winch_tramp : failed to read synchronization byte\n"); printk("read failed, err = %d\n", -n); @@ -195,7 +195,7 @@ void register_winch(int fd, struct tty_struct *tty) if(thread > 0){ register_winch_irq(thread_fd, fd, thread, tty); - count = os_write_file_k(thread_fd, &c, sizeof(c)); + count = os_write_file(thread_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("register_winch : failed to write " "synchronization byte, err = %d\n", diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index aa7bef9c38d..15453845d2b 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -35,7 +35,7 @@ static inline int cow_file_size(char *file, unsigned long long *size_out) static inline int cow_write_file(int fd, void *buf, int size) { - return os_write_file_k(fd, buf, size); + return os_write_file(fd, buf, size); } #endif diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index e1fd26c1b72..b869e389968 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -94,7 +94,7 @@ static int connect_to_switch(struct daemon_data *pri) req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = *local_addr; - n = os_write_file_k(pri->control, &req, sizeof(req)); + n = os_write_file(pri->control, &req, sizeof(req)); if(n != sizeof(req)){ printk("daemon_open : control setup request failed, err = %d\n", -n); @@ -102,7 +102,7 @@ static int connect_to_switch(struct daemon_data *pri) goto out_free; } - n = os_read_file_k(pri->control, sun, sizeof(*sun)); + n = os_read_file(pri->control, sun, sizeof(*sun)); if(n != sizeof(*sun)){ printk("daemon_open : read of data socket failed, err = %d\n", -n); diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 0fbb1615171..5eeecf8917c 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -79,7 +79,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) goto out_close_out; } - n = os_read_file_k(in_fds[0], &c, sizeof(c)); + n = os_read_file(in_fds[0], &c, sizeof(c)); if(n == 0){ printk("harddog_open - EOF on watchdog pipe\n"); helper_wait(pid); @@ -118,7 +118,7 @@ int ping_watchdog(int fd) int n; char c = '\n'; - n = os_write_file_k(fd, &c, sizeof(c)); + n = os_write_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("ping_watchdog - write failed, err = %d\n", -n); if(n < 0) diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index bd6688ea96d..10e08a8c17c 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -84,7 +84,7 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, if(kbuf == NULL) return(-ENOMEM); - err = os_read_file_k(state->fd, kbuf, count); + err = os_read_file(state->fd, kbuf, count); if(err < 0) goto out; @@ -115,7 +115,7 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer, if(copy_from_user(kbuf, buffer, count)) goto out; - err = os_write_file_k(state->fd, kbuf, count); + err = os_write_file(state->fd, kbuf, count); if(err < 0) goto out; *ppos += err; diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 8bc6688c4f0..3503cff867c 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -63,7 +63,7 @@ void read_output(int fd, char *output, int len) } *output = '\0'; - ret = os_read_file_k(fd, &remain, sizeof(remain)); + ret = os_read_file(fd, &remain, sizeof(remain)); if (ret != sizeof(remain)) { expected = sizeof(remain); @@ -73,7 +73,7 @@ void read_output(int fd, char *output, int len) while(remain != 0){ expected = (remain < len) ? remain : len; - ret = os_read_file_k(fd, output, expected); + ret = os_read_file(fd, output, expected); if (ret != expected) { str = "data"; goto err; @@ -94,7 +94,7 @@ int net_read(int fd, void *buf, int len) { int n; - n = os_read_file_k(fd, buf, len); + n = os_read_file(fd, buf, len); if(n == -EAGAIN) return 0; @@ -122,7 +122,7 @@ int net_write(int fd, void *buf, int len) { int n; - n = os_write_file_k(fd, buf, len); + n = os_write_file(fd, buf, len); if(n == -EAGAIN) return 0; diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 75bb40126c2..1c8efd95c42 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -113,7 +113,7 @@ static int port_accept(struct port_list *port) } if(atomic_read(&port->wait_count) == 0){ - os_write_file_k(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); + os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); printk("No one waiting for port\n"); } list_add(&conn->list, &port->pending); diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 94838f4c164..e942e836f99 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -44,7 +44,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, int n, ret = 0, have_data; while(size){ - n = os_read_file_k(random_fd, &data, sizeof(data)); + n = os_read_file(random_fd, &data, sizeof(data)); if(n > 0){ have_data = n; while (have_data && size) { diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 614fe25a31b..70509ddaac0 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -511,8 +511,8 @@ static void ubd_handler(void) int n; while(1){ - n = os_read_file_k(thread_fd, &req, - sizeof(struct io_thread_req *)); + n = os_read_file(thread_fd, &req, + sizeof(struct io_thread_req *)); if(n != sizeof(req)){ if(n == -EAGAIN) break; @@ -1112,8 +1112,8 @@ static void do_ubd_request(request_queue_t *q) (unsigned long long) req->sector << 9, sg->offset, sg->length, sg->page); - n = os_write_file_k(thread_fd, &io_req, - sizeof(struct io_thread_req *)); + n = os_write_file(thread_fd, &io_req, + sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ if(n != -EAGAIN) printk("write to io thread failed, " @@ -1366,8 +1366,8 @@ static int update_bitmap(struct io_thread_req *req) return 1; } - n = os_write_file_k(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words)); + n = os_write_file(req->fds[1], &req->bitmap_words, + sizeof(req->bitmap_words)); if(n != sizeof(req->bitmap_words)){ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, req->fds[1]); @@ -1411,7 +1411,7 @@ void do_io(struct io_thread_req *req) do { buf = &buf[n]; len -= n; - n = os_read_file_k(req->fds[bit], buf, len); + n = os_read_file(req->fds[bit], buf, len); if (n < 0) { printk("do_io - read failed, err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1421,7 +1421,7 @@ void do_io(struct io_thread_req *req) } while((n < len) && (n != 0)); if (n < len) memset(&buf[n], 0, len - n); } else { - n = os_write_file_k(req->fds[bit], buf, len); + n = os_write_file(req->fds[bit], buf, len); if(n != len){ printk("do_io - write failed err = %d " "fd = %d\n", -n, req->fds[bit]); @@ -1451,7 +1451,7 @@ int io_thread(void *arg) ignore_sigwinch_sig(); while(1){ - n = os_read_file_k(kernel_fd, &req, + n = os_read_file(kernel_fd, &req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ if(n < 0) @@ -1465,7 +1465,7 @@ int io_thread(void *arg) } io_count++; do_io(req); - n = os_write_file_k(kernel_fd, &req, + n = os_write_file(kernel_fd, &req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)) printk("io_thread - write failed, fd = %d, err = %d\n", diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 901804db3c3..d6638090870 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -144,9 +144,7 @@ extern int os_mode_fd(int fd, int mode); extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_read_file(int fd, void *buf, int len); -extern int os_read_file_k(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); -extern int os_write_file_k(int fd, const void *buf, int len); extern int os_file_size(char *file, unsigned long long *size_out); extern int os_file_modtime(char *file, unsigned long *modtime); extern int os_pipe(int *fd, int stream, int close_on_exec); diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index cff73faae99..16dc43e9d94 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -63,7 +63,7 @@ int load_initrd(char *filename, void *buf, int size) printk("Opening '%s' failed - err = %d\n", filename, -fd); return -1; } - n = os_read_file_k(fd, buf, size); + n = os_read_file(fd, buf, size); if(n != size){ printk("Read of %d bytes from '%s' failed, err = %d\n", size, filename, -n); diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 7c158448b9f..7b3e53fb807 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -62,9 +62,7 @@ EXPORT_SYMBOL(os_get_exec_close); EXPORT_SYMBOL(os_set_exec_close); EXPORT_SYMBOL(os_getpid); EXPORT_SYMBOL(os_open_file); -EXPORT_SYMBOL(os_read_file_k); EXPORT_SYMBOL(os_read_file); -EXPORT_SYMBOL(os_write_file_k); EXPORT_SYMBOL(os_write_file); EXPORT_SYMBOL(os_seek_file); EXPORT_SYMBOL(os_lock_file); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 77021a627da..df1ad3ba130 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -211,7 +211,7 @@ void physmem_forget_descriptor(int fd) panic("physmem_forget_descriptor - failed to seek " "to %lld in fd %d, error = %d\n", offset, fd, -err); - err = os_read_file_k(fd, addr, PAGE_SIZE); + err = os_read_file(fd, addr, PAGE_SIZE); if(err < 0) panic("physmem_forget_descriptor - failed to read " "from fd %d to 0x%p, error = %d\n", @@ -341,7 +341,7 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, * from physmem_fd, so it needs to be written out there. */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); - os_write_file_k(physmem_fd, &__syscall_stub_start, PAGE_SIZE); + os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index f756e78085e..89f9866a135 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c @@ -21,7 +21,7 @@ static irqreturn_t sigio_interrupt(int irq, void *data) { char c; - os_read_file_k(sigio_irq_fd, &c, sizeof(c)); + os_read_file(sigio_irq_fd, &c, sizeof(c)); reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); return IRQ_HANDLED; } diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 9ac56212465..e6a7778006a 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -47,7 +47,7 @@ struct task_struct *idle_threads[NR_CPUS]; void smp_send_reschedule(int cpu) { - os_write_file_k(cpu_data[cpu].ipi_pipe[1], "R", 1); + os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); num_reschedules_sent++; } @@ -59,7 +59,7 @@ void smp_send_stop(void) for(i = 0; i < num_online_cpus(); i++){ if(i == current_thread->cpu) continue; - os_write_file_k(cpu_data[i].ipi_pipe[1], "S", 1); + os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); } printk("done\n"); } @@ -108,8 +108,8 @@ static struct task_struct *idle_thread(int cpu) { .pid = new_task->thread.mode.tt.extern_pid, .task = new_task } ); idle_threads[cpu] = new_task; - CHOOSE_MODE(os_write_file_k(new_task->thread.mode.tt.switch_pipe[1], &c, - sizeof(c)), + CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, + sizeof(c)), ({ panic("skas mode doesn't support SMP"); })); return new_task; } @@ -179,7 +179,7 @@ void IPI_handler(int cpu) int fd; fd = cpu_data[cpu].ipi_pipe[0]; - while (os_read_file_k(fd, &c, 1) == 1) { + while (os_read_file(fd, &c, 1) == 1) { switch (c) { case 'C': smp_call_function_slave(cpu); @@ -239,7 +239,7 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, info = _info; for_each_online_cpu(i) - os_write_file_k(cpu_data[i].ipi_pipe[1], "C", 1); + os_write_file(cpu_data[i].ipi_pipe[1], "C", 1); while (atomic_read(&scf_started) != cpus) barrier(); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index c81bd207493..c631303cb80 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -57,14 +57,14 @@ void switch_to_tt(void *prev, void *next) * nor the value in "to" (since it was the task which stole us the CPU, * which we don't care about). */ - err = os_write_file_k(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); + err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); - err = os_read_file_k(from->thread.mode.tt.switch_pipe[0], &c, + err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); @@ -114,7 +114,7 @@ void suspend_new_thread(int fd) char c; os_stop_process(os_getpid()); - err = os_read_file_k(fd, &c, sizeof(c)); + err = os_read_file(fd, &c, sizeof(c)); if(err != sizeof(c)) panic("read failed in suspend_new_thread, err = %d", -err); } diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c index 007beb6b7c0..420c23f311f 100644 --- a/arch/um/kernel/tt/ptproxy/proxy.c +++ b/arch/um/kernel/tt/ptproxy/proxy.c @@ -338,14 +338,14 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out) "err = %d\n", -fd); exit(1); } - os_write_file_k(fd, gdb_init_string, - sizeof(gdb_init_string) - 1); + os_write_file(fd, gdb_init_string, + sizeof(gdb_init_string) - 1); if(startup){ if(stop){ - os_write_file_k(fd, "b start_kernel\n", + os_write_file(fd, "b start_kernel\n", strlen("b start_kernel\n")); } - os_write_file_k(fd, "c\n", strlen("c\n")); + os_write_file(fd, "c\n", strlen("c\n")); } if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ printk("start_debugger : PTRACE_TRACEME failed, " diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 264da6c5a5c..c23588393f6 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -44,7 +44,7 @@ static void tracer_winch_handler(int sig) int n; char c = 1; - n = os_write_file_k(tracer_winch[1], &c, sizeof(c)); + n = os_write_file(tracer_winch[1], &c, sizeof(c)); if(n != sizeof(c)) printk("tracer_winch_handler - write failed, err = %d\n", -n); } diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 5e9b8dcf34d..6f92f732d25 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -290,51 +290,7 @@ int os_seek_file(int fd, __u64 offset) return 0; } -static int fault_buffer(void *start, int len, - int (*copy_proc)(void *addr, void *buf, int len)) -{ - int page = getpagesize(), i; - char c; - - for(i = 0; i < len; i += page){ - if((*copy_proc)(start + i, &c, sizeof(c))) - return -EFAULT; - } - if((len % page) != 0){ - if((*copy_proc)(start + len - 1, &c, sizeof(c))) - return -EFAULT; - } - return 0; -} - -static int file_io(int fd, void *buf, int len, - int (*io_proc)(int fd, void *buf, int len), - int (*copy_user_proc)(void *addr, void *buf, int len)) -{ - int n, err; - - do { - n = (*io_proc)(fd, buf, len); - if((n < 0) && (errno == EFAULT)){ - err = fault_buffer(buf, len, copy_user_proc); - if(err) - return err; - n = (*io_proc)(fd, buf, len); - } - } while((n < 0) && (errno == EINTR)); - - if(n < 0) - return -errno; - return n; -} - int os_read_file(int fd, void *buf, int len) -{ - return file_io(fd, buf, len, (int (*)(int, void *, int)) read, - copy_from_user_proc); -} - -int os_read_file_k(int fd, void *buf, int len) { int n = read(fd, buf, len); @@ -344,12 +300,6 @@ int os_read_file_k(int fd, void *buf, int len) } int os_write_file(int fd, const void *buf, int len) -{ - return file_io(fd, (void *) buf, len, - (int (*)(int, void *, int)) write, copy_to_user_proc); -} - -int os_write_file_k(int fd, const void *buf, int len) { int n = write(fd, (void *) buf, len); diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index f5dfe49c844..0393e44813e 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -28,7 +28,7 @@ static char token(int fd, char *buf, int len, char stop) ptr = buf; end = &buf[len]; do { - n = os_read_file_k(fd, ptr, sizeof(*ptr)); + n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ if(n == 0) @@ -67,7 +67,7 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) return 1; do { - n = os_read_file_k(fd, &c, sizeof(c)); + n = os_read_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index d031a13bd96..a939a7ef022 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -517,7 +517,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm, .u = { .copy_segments = from_mm->id.u.mm_fd } } ); - i = os_write_file_k(new_mm->id.u.mm_fd, ©, sizeof(copy)); + i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); if(i != sizeof(copy)) printk("new_mm : /proc/mm copy_segments failed, " "err = %d\n", -i); -- cgit v1.2.3 From 8603ec81487a5fefbc29611ff0d635b33b6da990 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:44 -0700 Subject: uml: aIO deadlock avoidance Allow deadlocks to be avoided in the AIO code by setting the pipe to the I/O thread non-blocking. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/um') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 5d258eb4f50..9bf944f6a1d 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -221,6 +221,11 @@ static int init_aio_24(void) aio_req_fd_w = fds[0]; aio_req_fd_r = fds[1]; + + err = os_set_fd_block(aio_req_fd_w, 0); + if(err) + goto out_close_pipe; + err = run_helper_thread(not_aio_thread, NULL, CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); if(err < 0) -- cgit v1.2.3 From 64f60841c096594b8073e408cd9b40d7d08dcfdd Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:45 -0700 Subject: uml: speed page fault path Give the page fault code a specialized path. There is only one page to look at, so there's no point in going into the general page table walking code. There's only going to be one host operation, so there are no opportunities for merging. So, we go straight to the pte we want, figure out what needs doing, and do it. While I was in here, I fixed the wart where the address passed to unmap was a void *, but an unsigned long to map and protect. This gives me just under 10% on a kernel build. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 2 +- arch/um/include/skas/mode_kern_skas.h | 2 ++ arch/um/kernel/skas/tlb.c | 66 +++++++++++++++++++++++++++++++++-- arch/um/kernel/tlb.c | 4 ++- arch/um/os-Linux/skas/mem.c | 4 +-- 5 files changed, 72 insertions(+), 6 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index d6638090870..e11bdcd8afc 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -302,7 +302,7 @@ extern long syscall_stub_data(struct mm_id * mm_idp, extern int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int r, int w, int x, int phys_fd, unsigned long long offset, int done, void **data); -extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, +extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, int done, void **data); extern int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, int r, int w, int x, int done, diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h index 9cd9c6ec9a6..8ee6285dfac 100644 --- a/arch/um/include/skas/mode_kern_skas.h +++ b/arch/um/include/skas/mode_kern_skas.h @@ -33,6 +33,8 @@ extern unsigned long set_task_sizes_skas(unsigned long *task_size_out); extern int start_uml_skas(void); extern int external_pid_skas(struct task_struct *task); extern int thread_pid_skas(struct task_struct *task); +extern void flush_tlb_page_skas(struct vm_area_struct *vma, + unsigned long address); #define kmem_end_skas (host_task_size - 1024 * 1024) diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index 304a5b0695a..c43901aa936 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -32,8 +32,7 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, op->u.mmap.offset, finished, flush); break; case MUNMAP: - ret = unmap(&mmu->skas.id, - (void *) op->u.munmap.addr, + ret = unmap(&mmu->skas.id, op->u.munmap.addr, op->u.munmap.len, finished, flush); break; case MPROTECT: @@ -94,3 +93,66 @@ void force_flush_all_skas(void) unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; fix_range(current->mm, 0, end, 1); } + +void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + struct mm_struct *mm = vma->vm_mm; + void *flush = NULL; + int r, w, x, err = 0; + struct mm_id *mm_id; + + pgd = pgd_offset(vma->vm_mm, address); + if(!pgd_present(*pgd)) + goto kill; + + pud = pud_offset(pgd, address); + if(!pud_present(*pud)) + goto kill; + + pmd = pmd_offset(pud, address); + if(!pmd_present(*pmd)) + goto kill; + + pte = pte_offset_kernel(pmd, address); + + r = pte_read(*pte); + w = pte_write(*pte); + x = pte_exec(*pte); + if (!pte_young(*pte)) { + r = 0; + w = 0; + } else if (!pte_dirty(*pte)) { + w = 0; + } + + mm_id = &mm->context.skas.id; + if(pte_newpage(*pte)){ + if(pte_present(*pte)){ + unsigned long long offset; + int fd; + + fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); + err = map(mm_id, address, PAGE_SIZE, r, w, x, fd, + offset, 1, &flush); + } + else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); + } + else if(pte_newprot(*pte)) + err = protect(mm_id, address, PAGE_SIZE, r, w, x, 1, &flush); + + if(err) + goto kill; + + *pte = pte_mkuptodate(*pte); + + return; + +kill: + printk("Failed to flush page for address 0x%lx\n", address); + force_sig(SIGKILL, current); +} + diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index e201ccf0ec8..00de86efcca 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -381,7 +381,9 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) { address &= PAGE_MASK; - flush_tlb_range(vma, address, address + PAGE_SIZE); + + CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE), + flush_tlb_page_skas(vma, address)); } void flush_tlb_all(void) diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 6cdfda807b6..af0790719b7 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -219,8 +219,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, return ret; } -int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, - void **data) +int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, + int done, void **data) { int ret; -- cgit v1.2.3 From 3ec704e6660aa58505110a50102e57cdb9daa044 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:47 -0700 Subject: uml: eliminate a piece of debugging code I missed removing another piece of debugging in an earlier patch. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tlb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 00de86efcca..4a39d50d2d6 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -252,7 +252,6 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, &op_index, force, mmu, &flush, do_ops); } while (pgd++, addr = next, ((addr != end_addr) && !ret)); - log_info("total flush time - %Ld nsecs\n", end_time - start_time); if(!ret) ret = (*do_ops)(mmu, ops, op_index, 1, &flush); -- cgit v1.2.3 From 16dd07bc6404c8da0bdfeb7a5cde4e4a63991c00 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:48 -0700 Subject: uml: more page fault path trimming More trimming of the page fault path. Permissions are passed around in a single int rather than one bit per int. The permission values are copied from libc so that they can be passed to mmap and mprotect without any further conversion. The register sets used by do_syscall_stub and copy_context_skas0 are initialized once, at boot time, rather than once per call. wait_stub_done checks whether it is getting the signals it expects by comparing the wait status to a mask containing bits for the signals of interest rather than comparing individually to the signal numbers. It also has one check for a wait failure instead of two. The caller is expected to do the initial continue of the stub. This gets rid of an argument and some logic. The fname argument is gone, as that can be had from a stack trace. user_signal() is collapsed into userspace() as it is basically one or two lines of code afterwards. The physical memory remapping stuff is gone, as it is unused. flush_tlb_page is inlined. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 6 +- arch/um/include/tlb.h | 8 +- arch/um/kernel/physmem.c | 228 +------------------------------------- arch/um/kernel/skas/tlb.c | 21 ++-- arch/um/kernel/tlb.c | 42 +++---- arch/um/os-Linux/skas/mem.c | 51 +++++---- arch/um/os-Linux/skas/process.c | 122 ++++++++++++-------- arch/um/os-Linux/skas/trap.c | 17 --- arch/um/sys-i386/user-offsets.c | 9 +- arch/um/sys-x86_64/user-offsets.c | 5 + 10 files changed, 145 insertions(+), 364 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index e11bdcd8afc..688d181b5f8 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -300,13 +300,12 @@ extern long syscall_stub_data(struct mm_id * mm_idp, unsigned long *data, int data_count, void **addr, void **stub_addr); extern int map(struct mm_id * mm_idp, unsigned long virt, - unsigned long len, int r, int w, int x, int phys_fd, + unsigned long len, int prot, int phys_fd, unsigned long long offset, int done, void **data); extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, int done, void **data); extern int protect(struct mm_id * mm_idp, unsigned long addr, - unsigned long len, int r, int w, int x, int done, - void **data); + unsigned long len, unsigned int prot, int done, void **data); /* skas/process.c */ extern int is_skas_winch(int pid, int fd, void *data); @@ -342,7 +341,6 @@ extern void maybe_sigio_broken(int fd, int read); /* skas/trap */ extern void sig_handler_common_skas(int sig, void *sc_ptr); -extern void user_signal(int sig, union uml_pt_regs *regs, int pid); /* sys-x86_64/prctl.c */ extern int os_arch_prctl(int pid, int code, unsigned long *addr); diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h index 8efc1e0f1b8..bcd1a4afb84 100644 --- a/arch/um/include/tlb.h +++ b/arch/um/include/tlb.h @@ -14,9 +14,7 @@ struct host_vm_op { struct { unsigned long addr; unsigned long len; - unsigned int r:1; - unsigned int w:1; - unsigned int x:1; + unsigned int prot; int fd; __u64 offset; } mmap; @@ -27,9 +25,7 @@ struct host_vm_op { struct { unsigned long addr; unsigned long len; - unsigned int r:1; - unsigned int w:1; - unsigned int x:1; + unsigned int prot; } mprotect; } u; }; diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index df1ad3ba130..3ba6e4c841d 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -21,229 +21,8 @@ #include "kern.h" #include "init.h" -struct phys_desc { - struct rb_node rb; - int fd; - __u64 offset; - void *virt; - unsigned long phys; - struct list_head list; -}; - -static struct rb_root phys_mappings = RB_ROOT; - -static struct rb_node **find_rb(void *virt) -{ - struct rb_node **n = &phys_mappings.rb_node; - struct phys_desc *d; - - while(*n != NULL){ - d = rb_entry(*n, struct phys_desc, rb); - if(d->virt == virt) - return n; - - if(d->virt > virt) - n = &(*n)->rb_left; - else - n = &(*n)->rb_right; - } - - return n; -} - -static struct phys_desc *find_phys_mapping(void *virt) -{ - struct rb_node **n = find_rb(virt); - - if(*n == NULL) - return NULL; - - return rb_entry(*n, struct phys_desc, rb); -} - -static void insert_phys_mapping(struct phys_desc *desc) -{ - struct rb_node **n = find_rb(desc->virt); - - if(*n != NULL) - panic("Physical remapping for %p already present", - desc->virt); - - rb_link_node(&desc->rb, rb_parent(*n), n); - rb_insert_color(&desc->rb, &phys_mappings); -} - -LIST_HEAD(descriptor_mappings); - -struct desc_mapping { - int fd; - struct list_head list; - struct list_head pages; -}; - -static struct desc_mapping *find_mapping(int fd) -{ - struct desc_mapping *desc; - struct list_head *ele; - - list_for_each(ele, &descriptor_mappings){ - desc = list_entry(ele, struct desc_mapping, list); - if(desc->fd == fd) - return desc; - } - - return NULL; -} - -static struct desc_mapping *descriptor_mapping(int fd) -{ - struct desc_mapping *desc; - - desc = find_mapping(fd); - if(desc != NULL) - return desc; - - desc = kmalloc(sizeof(*desc), GFP_ATOMIC); - if(desc == NULL) - return NULL; - - *desc = ((struct desc_mapping) - { .fd = fd, - .list = LIST_HEAD_INIT(desc->list), - .pages = LIST_HEAD_INIT(desc->pages) }); - list_add(&desc->list, &descriptor_mappings); - - return desc; -} - -int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) -{ - struct desc_mapping *fd_maps; - struct phys_desc *desc; - unsigned long phys; - int err; - - fd_maps = descriptor_mapping(fd); - if(fd_maps == NULL) - return -ENOMEM; - - phys = __pa(virt); - desc = find_phys_mapping(virt); - if(desc != NULL) - panic("Address 0x%p is already substituted\n", virt); - - err = -ENOMEM; - desc = kmalloc(sizeof(*desc), GFP_ATOMIC); - if(desc == NULL) - goto out; - - *desc = ((struct phys_desc) - { .fd = fd, - .offset = offset, - .virt = virt, - .phys = __pa(virt), - .list = LIST_HEAD_INIT(desc->list) }); - insert_phys_mapping(desc); - - list_add(&desc->list, &fd_maps->pages); - - virt = (void *) ((unsigned long) virt & PAGE_MASK); - err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0); - if(!err) - goto out; - - rb_erase(&desc->rb, &phys_mappings); - kfree(desc); - out: - return err; -} - static int physmem_fd = -1; -static void remove_mapping(struct phys_desc *desc) -{ - void *virt = desc->virt; - int err; - - rb_erase(&desc->rb, &phys_mappings); - list_del(&desc->list); - kfree(desc); - - err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0); - if(err) - panic("Failed to unmap block device page from physical memory, " - "errno = %d", -err); -} - -int physmem_remove_mapping(void *virt) -{ - struct phys_desc *desc; - - virt = (void *) ((unsigned long) virt & PAGE_MASK); - desc = find_phys_mapping(virt); - if(desc == NULL) - return 0; - - remove_mapping(desc); - return 1; -} - -void physmem_forget_descriptor(int fd) -{ - struct desc_mapping *desc; - struct phys_desc *page; - struct list_head *ele, *next; - __u64 offset; - void *addr; - int err; - - desc = find_mapping(fd); - if(desc == NULL) - return; - - list_for_each_safe(ele, next, &desc->pages){ - page = list_entry(ele, struct phys_desc, list); - offset = page->offset; - addr = page->virt; - remove_mapping(page); - err = os_seek_file(fd, offset); - if(err) - panic("physmem_forget_descriptor - failed to seek " - "to %lld in fd %d, error = %d\n", - offset, fd, -err); - err = os_read_file(fd, addr, PAGE_SIZE); - if(err < 0) - panic("physmem_forget_descriptor - failed to read " - "from fd %d to 0x%p, error = %d\n", - fd, addr, -err); - } - - list_del(&desc->list); - kfree(desc); -} - -EXPORT_SYMBOL(physmem_forget_descriptor); -EXPORT_SYMBOL(physmem_remove_mapping); -EXPORT_SYMBOL(physmem_subst_mapping); - -void arch_free_page(struct page *page, int order) -{ - void *virt; - int i; - - for(i = 0; i < (1 << order); i++){ - virt = __va(page_to_phys(page + i)); - physmem_remove_mapping(virt); - } -} - -int is_remapped(void *virt) -{ - struct phys_desc *desc = find_phys_mapping(virt); - - return desc != NULL; -} - /* Changed during early boot */ unsigned long high_physmem; @@ -350,14 +129,9 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, int phys_mapping(unsigned long phys, __u64 *offset_out) { - struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK)); int fd = -1; - if(desc != NULL){ - fd = desc->fd; - *offset_out = desc->offset; - } - else if(phys < physmem_size){ + if(phys < physmem_size){ fd = physmem_fd; *offset_out = phys; } diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index c43901aa936..b3d722ddde3 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -27,9 +27,9 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, switch(op->type){ case MMAP: ret = map(&mmu->skas.id, op->u.mmap.addr, - op->u.mmap.len, op->u.mmap.r, op->u.mmap.w, - op->u.mmap.x, op->u.mmap.fd, - op->u.mmap.offset, finished, flush); + op->u.mmap.len, op->u.mmap.prot, + op->u.mmap.fd, op->u.mmap.offset, finished, + flush); break; case MUNMAP: ret = unmap(&mmu->skas.id, op->u.munmap.addr, @@ -37,8 +37,7 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, break; case MPROTECT: ret = protect(&mmu->skas.id, op->u.mprotect.addr, - op->u.mprotect.len, op->u.mprotect.r, - op->u.mprotect.w, op->u.mprotect.x, + op->u.mprotect.len, op->u.mprotect.prot, finished, flush); break; default: @@ -102,10 +101,10 @@ void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) pte_t *pte; struct mm_struct *mm = vma->vm_mm; void *flush = NULL; - int r, w, x, err = 0; + int r, w, x, prot, err = 0; struct mm_id *mm_id; - pgd = pgd_offset(vma->vm_mm, address); + pgd = pgd_offset(mm, address); if(!pgd_present(*pgd)) goto kill; @@ -130,19 +129,21 @@ void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) } mm_id = &mm->context.skas.id; + prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | + (x ? UM_PROT_EXEC : 0)); if(pte_newpage(*pte)){ if(pte_present(*pte)){ unsigned long long offset; int fd; fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); - err = map(mm_id, address, PAGE_SIZE, r, w, x, fd, - offset, 1, &flush); + err = map(mm_id, address, PAGE_SIZE, prot, fd, offset, + 1, &flush); } else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); } else if(pte_newprot(*pte)) - err = protect(mm_id, address, PAGE_SIZE, r, w, x, 1, &flush); + err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); if(err) goto kill; diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 4a39d50d2d6..8a8d5285144 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -17,7 +17,7 @@ #include "os.h" static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, - int r, int w, int x, struct host_vm_op *ops, int *index, + unsigned int prot, struct host_vm_op *ops, int *index, int last_filled, union mm_context *mmu, void **flush, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) @@ -31,8 +31,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, last = &ops[*index]; if((last->type == MMAP) && (last->u.mmap.addr + last->u.mmap.len == virt) && - (last->u.mmap.r == r) && (last->u.mmap.w == w) && - (last->u.mmap.x == x) && (last->u.mmap.fd == fd) && + (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && (last->u.mmap.offset + last->u.mmap.len == offset)){ last->u.mmap.len += len; return 0; @@ -48,9 +47,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, .u = { .mmap = { .addr = virt, .len = len, - .r = r, - .w = w, - .x = x, + .prot = prot, .fd = fd, .offset = offset } } }); @@ -87,8 +84,8 @@ static int add_munmap(unsigned long addr, unsigned long len, return ret; } -static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, - int x, struct host_vm_op *ops, int *index, +static int add_mprotect(unsigned long addr, unsigned long len, + unsigned int prot, struct host_vm_op *ops, int *index, int last_filled, union mm_context *mmu, void **flush, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) @@ -100,8 +97,7 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, last = &ops[*index]; if((last->type == MPROTECT) && (last->u.mprotect.addr + last->u.mprotect.len == addr) && - (last->u.mprotect.r == r) && (last->u.mprotect.w == w) && - (last->u.mprotect.x == x)){ + (last->u.mprotect.prot == prot)){ last->u.mprotect.len += len; return 0; } @@ -116,9 +112,7 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, .u = { .mprotect = { .addr = addr, .len = len, - .r = r, - .w = w, - .x = x } } }); + .prot = prot } } }); return ret; } @@ -133,7 +127,7 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr, void **)) { pte_t *pte; - int r, w, x, ret = 0; + int r, w, x, prot, ret = 0; pte = pte_offset_kernel(pmd, addr); do { @@ -146,19 +140,19 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr, } else if (!pte_dirty(*pte)) { w = 0; } + prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | + (x ? UM_PROT_EXEC : 0)); if(force || pte_newpage(*pte)){ if(pte_present(*pte)) ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, - PAGE_SIZE, r, w, x, ops, - op_index, last_op, mmu, flush, - do_ops); + PAGE_SIZE, prot, ops, op_index, + last_op, mmu, flush, do_ops); else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, last_op, mmu, flush, do_ops); } else if(pte_newprot(*pte)) - ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, - op_index, last_op, mmu, flush, - do_ops); + ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, + last_op, mmu, flush, do_ops); *pte = pte_mkuptodate(*pte); } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); return ret; @@ -377,14 +371,6 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) return(pte_offset_map(pmd, addr)); } -void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) -{ - address &= PAGE_MASK; - - CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE), - flush_tlb_page_skas(vma, address)); -} - void flush_tlb_all(void) { flush_tlb_mm(current->mm); diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index af0790719b7..8e490fff3d4 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -24,10 +24,11 @@ #include "uml-config.h" #include "sysdep/ptrace.h" #include "sysdep/stub.h" +#include "init.h" extern unsigned long batch_syscall_stub, __syscall_stub_start; -extern void wait_stub_done(int pid, int sig, char * fname); +extern void wait_stub_done(int pid); static inline unsigned long *check_init_stack(struct mm_id * mm_idp, unsigned long *stack) @@ -39,6 +40,19 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp, return stack; } +static unsigned long syscall_regs[MAX_REG_NR]; + +static int __init init_syscall_regs(void) +{ + get_safe_registers(syscall_regs, NULL); + syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + ((unsigned long) &batch_syscall_stub - + (unsigned long) &__syscall_stub_start); + return 0; +} + +__initcall(init_syscall_regs); + extern int proc_mm; int single_count = 0; @@ -47,12 +61,11 @@ int multi_op_count = 0; static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) { - unsigned long regs[MAX_REG_NR]; int n, i; long ret, offset; unsigned long * data; unsigned long * syscall; - int pid = mm_idp->u.pid; + int err, pid = mm_idp->u.pid; if(proc_mm) #warning Need to look up userspace_pid by cpu @@ -60,21 +73,21 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) multi_count++; - get_safe_registers(regs, NULL); - regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + - ((unsigned long) &batch_syscall_stub - - (unsigned long) &__syscall_stub_start); - - n = ptrace_setregs(pid, regs); + n = ptrace_setregs(pid, syscall_regs); if(n < 0){ printk("Registers - \n"); for(i = 0; i < MAX_REG_NR; i++) - printk("\t%d\t0x%lx\n", i, regs[i]); + printk("\t%d\t0x%lx\n", i, syscall_regs[i]); panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", -n); } - wait_stub_done(pid, 0, "do_syscall_stub"); + err = ptrace(PTRACE_CONT, pid, 0, 0); + if(err) + panic("Failed to continue stub, pid = %d, errno = %d\n", pid, + errno); + + wait_stub_done(pid); /* When the stub stops, we find the following values on the * beginning of the stack: @@ -176,14 +189,10 @@ long syscall_stub_data(struct mm_id * mm_idp, return 0; } -int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, - int r, int w, int x, int phys_fd, unsigned long long offset, - int done, void **data) +int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, + int phys_fd, unsigned long long offset, int done, void **data) { - int prot, ret; - - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); + int ret; if(proc_mm){ struct proc_mm_op map; @@ -253,13 +262,11 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, } int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, - int r, int w, int x, int done, void **data) + unsigned int prot, int done, void **data) { struct proc_mm_op protect; - int prot, ret; + int ret; - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); if(proc_mm){ int fd = mm_idp->u.mm_fd; diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 1f39f2bf7ce..5c088a55396 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -34,6 +34,7 @@ #include "process.h" #include "longjmp.h" #include "kern_constants.h" +#include "as-layout.h" int is_skas_winch(int pid, int fd, void *data) { @@ -60,37 +61,42 @@ static int ptrace_dump_regs(int pid) return 0; } -void wait_stub_done(int pid, int sig, char * fname) +/* + * Signals that are OK to receive in the stub - we'll just continue it. + * SIGWINCH will happen when UML is inside a detached screen. + */ +#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH)) + +/* Signals that the stub will finish with - anything else is an error */ +#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP)) + +void wait_stub_done(int pid) { int n, status, err; - do { - if ( sig != -1 ) { - err = ptrace(PTRACE_CONT, pid, 0, sig); - if(err) - panic("%s : continue failed, errno = %d\n", - fname, errno); - } - sig = 0; - + while(1){ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - } while((n >= 0) && WIFSTOPPED(status) && - ((WSTOPSIG(status) == SIGVTALRM) || - /* running UML inside a detached screen can cause - * SIGWINCHes - */ - (WSTOPSIG(status) == SIGWINCH))); - - if((n < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ - err = ptrace_dump_regs(pid); + if((n < 0) || !WIFSTOPPED(status)) + goto bad_wait; + + if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0) + break; + + err = ptrace(PTRACE_CONT, pid, 0, 0); if(err) - printk("Failed to get registers from stub, " - "errno = %d\n", -err); - panic("%s : failed to wait for SIGUSR1/SIGTRAP, " - "pid = %d, n = %d, errno = %d, status = 0x%x\n", - fname, pid, n, errno, status); + panic("wait_stub_done : continue failed, errno = %d\n", + errno); } + + if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) + return; + +bad_wait: + err = ptrace_dump_regs(pid); + if(err) + printk("Failed to get registers from stub, errno = %d\n", -err); + panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " + "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); } extern unsigned long current_stub_stack(void); @@ -112,7 +118,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) sizeof(struct ptrace_faultinfo)); } else { - wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo"); + err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); + if(err) + panic("Failed to continue stub, pid = %d, errno = %d\n", + pid, errno); + wait_stub_done(pid); /* faultinfo is prepared by the stub-segv-handler at start of * the stub stack page. We just have to copy it. @@ -304,10 +314,13 @@ void userspace(union uml_pt_regs *regs) UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if(WIFSTOPPED(status)){ - switch(WSTOPSIG(status)){ + int sig = WSTOPSIG(status); + switch(sig){ case SIGSEGV: - if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) - user_signal(SIGSEGV, regs, pid); + if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){ + get_skas_faultinfo(pid, ®s->skas.faultinfo); + (*sig_info[SIGSEGV])(SIGSEGV, regs); + } else handle_segv(pid, regs); break; case SIGTRAP + 0x80: @@ -322,11 +335,13 @@ void userspace(union uml_pt_regs *regs) case SIGBUS: case SIGFPE: case SIGWINCH: - user_signal(WSTOPSIG(status), regs, pid); + block_signals(); + (*sig_info[sig])(sig, regs); + unblock_signals(); break; default: printk("userspace - child stopped with signal " - "%d\n", WSTOPSIG(status)); + "%d\n", sig); } pid = userspace_pid[0]; interrupt_end(); @@ -338,11 +353,29 @@ void userspace(union uml_pt_regs *regs) } } +static unsigned long thread_regs[MAX_REG_NR]; +static unsigned long thread_fp_regs[HOST_FP_SIZE]; + +static int __init init_thread_regs(void) +{ + get_safe_registers(thread_regs, thread_fp_regs); + /* Set parent's instruction pointer to start of clone-stub */ + thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + (unsigned long) stub_clone_handler - + (unsigned long) &__syscall_stub_start; + thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - + sizeof(void *); +#ifdef __SIGNAL_FRAMESIZE + thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; +#endif + return 0; +} + +__initcall(init_thread_regs); + int copy_context_skas0(unsigned long new_stack, int pid) { int err; - unsigned long regs[MAX_REG_NR]; - unsigned long fp_regs[HOST_FP_SIZE]; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; struct stub_data *child_data = (struct stub_data *) new_stack; @@ -357,23 +390,12 @@ int copy_context_skas0(unsigned long new_stack, int pid) .timer = ((struct itimerval) { { 0, 1000000 / hz() }, { 0, 1000000 / hz() }})}); - get_safe_registers(regs, fp_regs); - - /* Set parent's instruction pointer to start of clone-stub */ - regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + - (unsigned long) stub_clone_handler - - (unsigned long) &__syscall_stub_start; - regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - - sizeof(void *); -#ifdef __SIGNAL_FRAMESIZE - regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; -#endif - err = ptrace_setregs(pid, regs); + err = ptrace_setregs(pid, thread_regs); if(err < 0) panic("copy_context_skas0 : PTRACE_SETREGS failed, " "pid = %d, errno = %d\n", pid, -err); - err = ptrace_setfpregs(pid, fp_regs); + err = ptrace_setfpregs(pid, thread_fp_regs); if(err < 0) panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " "pid = %d, errno = %d\n", pid, -err); @@ -384,7 +406,11 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* Wait, until parent has finished its work: read child's pid from * parent's stack, and check, if bad result. */ - wait_stub_done(pid, 0, "copy_context_skas0"); + err = ptrace(PTRACE_CONT, pid, 0, 0); + if(err) + panic("Failed to continue new process, pid = %d, " + "errno = %d\n", pid, errno); + wait_stub_done(pid); pid = data->err; if(pid < 0) @@ -394,7 +420,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* Wait, until child has finished too: read child's result from * child's stack and check it. */ - wait_stub_done(pid, -1, "copy_context_skas0"); + wait_stub_done(pid); if (child_data->err != UML_CONFIG_STUB_DATA) panic("copy_context_skas0 - stub-child reports error %ld\n", child_data->err); diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 5110eff51b9..3b600c2e63b 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -64,20 +64,3 @@ void sig_handler_common_skas(int sig, void *sc_ptr) errno = save_errno; r->skas.is_user = save_user; } - -extern int ptrace_faultinfo; - -void user_signal(int sig, union uml_pt_regs *regs, int pid) -{ - void (*handler)(int, union uml_pt_regs *); - int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || - (sig == SIGILL) || (sig == SIGTRAP)); - - if (segv) - get_skas_faultinfo(pid, ®s->skas.faultinfo); - - handler = sig_info[sig]; - handler(sig, (union uml_pt_regs *) regs); - - unblock_signals(); -} diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index ee42c27abd3..29118cf5ff2 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -1,9 +1,10 @@ #include +#include #include +#include +#include #include #include -#include -#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -72,4 +73,8 @@ void foo(void) DEFINE(UM_POLLIN, POLLIN); DEFINE(UM_POLLPRI, POLLPRI); DEFINE(UM_POLLOUT, POLLOUT); + + DEFINE(UM_PROT_READ, PROT_READ); + DEFINE(UM_PROT_WRITE, PROT_WRITE); + DEFINE(UM_PROT_EXEC, PROT_EXEC); } diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 7bb532567c4..0d5fd764c21 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -2,6 +2,7 @@ #include #include #include +#include #define __FRAME_OFFSETS #include #include @@ -93,4 +94,8 @@ void foo(void) DEFINE(UM_POLLIN, POLLIN); DEFINE(UM_POLLPRI, POLLPRI); DEFINE(UM_POLLOUT, POLLOUT); + + DEFINE(UM_PROT_READ, PROT_READ); + DEFINE(UM_PROT_WRITE, PROT_WRITE); + DEFINE(UM_PROT_EXEC, PROT_EXEC); } -- cgit v1.2.3 From 1e7371c1a11f041d641cc0ff113bf1daa1bd98b9 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:49 -0700 Subject: uml: only flush areas covered by VMA When doing a full address space flush, only look at areas covered by a VMA. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/tlb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index b3d722ddde3..c0f0693743b 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -89,8 +89,13 @@ void flush_tlb_mm_skas(struct mm_struct *mm) void force_flush_all_skas(void) { - unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; - fix_range(current->mm, 0, end, 1); + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma = mm->mmap; + + while(vma != NULL) { + fix_range(mm, vma->vm_start, vma->vm_end, 1); + vma = vma->vm_next; + } } void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) -- cgit v1.2.3 From 83ff7df5f1c1c44efd84d7341211aa0138fd9504 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:50 -0700 Subject: uml: out of tmpfs space error clarification It turns out that the message complaining about a lack of tmpfs space on the host can be misunderstood as referring to the UML. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/trap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 0c467fa0887..abab90c3803 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -229,8 +229,8 @@ void relay_signal(int sig, union uml_pt_regs *regs) if(!UPT_IS_USER(regs)){ if(sig == SIGBUS) - printk("Bus error - the /dev/shm or /tmp mount likely " - "just ran out of space\n"); + printk("Bus error - the host /dev/shm or /tmp mount " + "likely just ran out of space\n"); panic("Kernel mode signal %d", sig); } -- cgit v1.2.3 From b7ec15bd004f4524bf091f851348da2ccb519e4f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:51 -0700 Subject: uml: virtualized time fix With the current timekeeping, !CONFIG_UML_REAL_TIME_CLOCK has inconsistent behavior. Previously, gettimeofday could be (and was) isolated from the clock ticking. Now, it's not, so when CONFIG_UML_REAL_TIME_CLOCK is disabled, gettimeofday must progress in lockstep with the clock, making it fully virtual. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/time.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 9fd80ee3eef..cd7349de8ca 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -34,8 +34,8 @@ unsigned long long sched_clock(void) return (unsigned long long)jiffies_64 * (1000000000 / HZ); } -static unsigned long long prev_nsecs[NR_CPUS]; #ifdef CONFIG_UML_REAL_TIME_CLOCK +static unsigned long long prev_nsecs[NR_CPUS]; static long long delta[NR_CPUS]; /* Deviation per interval */ #endif @@ -94,7 +94,12 @@ irqreturn_t um_timer(int irq, void *dev) do_timer(1); +#ifdef CONFIG_UML_REAL_TIME_CLOCK nsecs = get_time(); +#else + nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec + + BILLION / HZ; +#endif xtime.tv_sec = nsecs / NSEC_PER_SEC; xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; @@ -127,13 +132,18 @@ void time_init(void) nsecs = os_nsecs(); set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, -nsecs % BILLION); + set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION); late_time_init = register_timer; } void do_gettimeofday(struct timeval *tv) { +#ifdef CONFIG_UML_REAL_TIME_CLOCK unsigned long long nsecs = get_time(); - +#else + unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION + + xtime.tv_nsec; +#endif tv->tv_sec = nsecs / NSEC_PER_SEC; /* Careful about calculations here - this was originally done as * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC -- cgit v1.2.3 From c2f239d93e8af991392871c57465cb2ac556b482 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:52 -0700 Subject: uml: fix prototypes Declare strlcpy and strlcat more correctly. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/user.h b/arch/um/include/user.h index a6da6260825..d380e6d91a9 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h @@ -14,6 +14,11 @@ */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/* + * This will provide the size_t definition in both kernel and userspace builds + */ +#include + extern void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern int printk(const char *fmt, ...) @@ -21,8 +26,7 @@ extern int printk(const char *fmt, ...) extern void schedule(void); extern int in_aton(char *str); extern int open_gdb_chan(void); -/* These use size_t, however unsigned long is correct on both i386 and x86_64. */ -extern unsigned long strlcpy(char *, const char *, unsigned long); -extern unsigned long strlcat(char *, const char *, unsigned long); +extern size_t strlcpy(char *, const char *, size_t); +extern size_t strlcat(char *, const char *, size_t); #endif -- cgit v1.2.3