From f6e34c6af6f18bd6c66bfb1c6a7c57068412aa73 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:43 -0700 Subject: [PATCH] uml: _switch_to code consolidation This patch moves code that is in both switch_to_tt and switch_to_skas to the top level _switch_to function, keeping us from duplicating code. It is required for the stack trace patch to work properly. Signed-off-by: Allan Graves Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process_kern.c | 12 ++++++++++-- arch/um/kernel/skas/include/mode_kern-skas.h | 2 +- arch/um/kernel/skas/process_kern.c | 7 +------ arch/um/kernel/tt/include/mode_kern-tt.h | 2 +- arch/um/kernel/tt/process_kern.c | 7 +------ 5 files changed, 14 insertions(+), 16 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index c23d8a08d0ff..1143f5e522b2 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -113,8 +113,16 @@ void set_current(void *t) void *_switch_to(void *prev, void *next, void *last) { - return(CHOOSE_MODE(switch_to_tt(prev, next), - switch_to_skas(prev, next))); + struct task_struct *from = prev; + struct task_struct *to= next; + + to->thread.prev_sched = from; + set_current(to); + + CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next); + + return(current->thread.prev_sched); + } void interrupt_end(void) diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h index e48490028111..c97a80dfe370 100644 --- a/arch/um/kernel/skas/include/mode_kern-skas.h +++ b/arch/um/kernel/skas/include/mode_kern-skas.h @@ -11,7 +11,7 @@ #include "asm/ptrace.h" extern void flush_thread_skas(void); -extern void *switch_to_skas(void *prev, void *next); +extern void switch_to_skas(void *prev, void *next); extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, unsigned long esp); extern int copy_thread_skas(int nr, unsigned long clone_flags, diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 3d1b227226e6..efe92e8aa2a9 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c @@ -24,7 +24,7 @@ #include "proc_mm.h" #include "registers.h" -void *switch_to_skas(void *prev, void *next) +void switch_to_skas(void *prev, void *next) { struct task_struct *from, *to; @@ -35,16 +35,11 @@ void *switch_to_skas(void *prev, void *next) if(current->pid == 0) switch_timers(0); - to->thread.prev_sched = from; - set_current(to); - switch_threads(&from->thread.mode.skas.switch_buf, to->thread.mode.skas.switch_buf); if(current->pid == 0) switch_timers(1); - - return(current->thread.prev_sched); } extern void schedule_tail(struct task_struct *prev); diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h index e0ca0e0b2516..2a35b15c5fef 100644 --- a/arch/um/kernel/tt/include/mode_kern-tt.h +++ b/arch/um/kernel/tt/include/mode_kern-tt.h @@ -11,7 +11,7 @@ #include "asm/ptrace.h" #include "asm/uaccess.h" -extern void *switch_to_tt(void *prev, void *next); +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); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index a189a2b92935..0de05a268b22 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -26,7 +26,7 @@ #include "init.h" #include "tt.h" -void *switch_to_tt(void *prev, void *next, void *last) +int switch_to_tt(void *prev, void *next, void *last) { struct task_struct *from, *to, *prev_sched; unsigned long flags; @@ -36,8 +36,6 @@ void *switch_to_tt(void *prev, void *next, void *last) from = prev; to = next; - to->thread.prev_sched = from; - cpu = from->thread_info->cpu; if(cpu == 0) forward_interrupts(to->thread.mode.tt.extern_pid); @@ -53,7 +51,6 @@ void *switch_to_tt(void *prev, void *next, void *last) forward_pending_sigio(to->thread.mode.tt.extern_pid); c = 0; - set_current(to); err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) @@ -85,8 +82,6 @@ void *switch_to_tt(void *prev, void *next, void *last) flush_tlb_all(); local_irq_restore(flags); - - return(current->thread.prev_sched); } void release_thread_tt(struct task_struct *task) -- cgit v1.2.2 From 3eddddcf239c89bbd3c50d1440001a3d384ed40a Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:46 -0700 Subject: [PATCH] uml: breakpoint an arbitrary thread This patch implements a stack trace for a thread, not unlike sysrq-t does. The advantage to this is that a break point can be placed on showreqs, so that upon showing the stack, you jump immediately into the debugger. While sysrq-t does the same thing, sysrq-t shows *all* threads stacks. It also doesn't work right now. In the future, I thought it might be acceptable to make this show all pids stacks, but perhaps leaving well enough alone and just using sysrq-t would be okay. For now, upon receiving the stack command, UML switches context to that thread, dumps its registers, and then switches context back to the original thread. Since UML compacts all threads into one of 4 host threads, this sort of mechanism could be expanded in the future to include other debugging helpers that sysrq does not cover. Note by jdike - The main benefit to this is that it brings an arbitrary thread back into context, where it can be examined by gdb. The fact that it dumps it stack is secondary. This provides the capability to examine a sleeping thread, which has existed in tt mode, but not in skas mode until now. Also, the other threads, that sysrq doesn't cover, can be gdb-ed directly anyway. Signed-off-by: Allan Graves Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/mconsole_kern.c | 52 +++++++++++++++++++++++++++++++++++++++++ arch/um/drivers/mconsole_user.c | 1 + arch/um/include/mconsole.h | 1 + arch/um/kernel/process_kern.c | 9 ++++++- 4 files changed, 62 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index c190c2414197..12c95368124a 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -32,6 +32,7 @@ #include "os.h" #include "umid.h" #include "irq_kern.h" +#include "choose-mode.h" static int do_unlink_socket(struct notifier_block *notifier, unsigned long what, void *data) @@ -276,6 +277,7 @@ void mconsole_proc(struct mc_request *req) go - continue the UML after a 'stop' \n\ log - make UML enter into the kernel log\n\ proc - returns the contents of the UML's /proc/\n\ + stack - returns the stack of the specified pid\n\ " void mconsole_help(struct mc_request *req) @@ -479,6 +481,56 @@ void mconsole_sysrq(struct mc_request *req) } #endif +/* Mconsole stack trace + * Added by Allan Graves, Jeff Dike + * Dumps a stacks registers to the linux console. + * Usage stack . + */ +void do_stack(struct mc_request *req) +{ + char *ptr = req->request.data; + int pid_requested= -1; + struct task_struct *from = NULL; + struct task_struct *to = NULL; + + /* Would be nice: + * 1) Send showregs output to mconsole. + * 2) Add a way to stack dump all pids. + */ + + ptr += strlen("stack"); + while(isspace(*ptr)) ptr++; + + /* Should really check for multiple pids or reject bad args here */ + /* What do the arguments in mconsole_reply mean? */ + if(sscanf(ptr, "%d", &pid_requested) == 0){ + mconsole_reply(req, "Please specify a pid", 1, 0); + return; + } + + from = current; + to = find_task_by_pid(pid_requested); + + if((to == NULL) || (pid_requested == 0)) { + mconsole_reply(req, "Couldn't find that pid", 1, 0); + return; + } + to->thread.saved_task = current; + + switch_to(from, to, from); + mconsole_reply(req, "Stack Dumped to console and message log", 0, 0); +} + +void mconsole_stack(struct mc_request *req) +{ + /* This command doesn't work in TT mode, so let's check and then + * get out of here + */ + CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode", + 1, 0), + do_stack(req)); +} + /* Changed by mconsole_setup, which is __setup, and called before SMP is * active. */ diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index fe5afb13252c..a5b8aeade1c5 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -30,6 +30,7 @@ static struct mconsole_command commands[] = { { "go", mconsole_go, MCONSOLE_INTR }, { "log", mconsole_log, MCONSOLE_INTR }, { "proc", mconsole_proc, MCONSOLE_PROC }, + { "stack", mconsole_stack, MCONSOLE_INTR }, }; /* Initialized in mconsole_init, which is an initcall */ diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index cfa368e045a5..b1b512f47035 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h @@ -81,6 +81,7 @@ extern void mconsole_stop(struct mc_request *req); extern void mconsole_go(struct mc_request *req); extern void mconsole_log(struct mc_request *req); extern void mconsole_proc(struct mc_request *req); +extern void mconsole_stack(struct mc_request *req); extern int mconsole_get_request(int fd, struct mc_request *req); extern int mconsole_notify(char *sock_name, int type, const void *data, diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 1143f5e522b2..39cf568ccfaf 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -119,7 +119,14 @@ void *_switch_to(void *prev, void *next, void *last) to->thread.prev_sched = from; set_current(to); - CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next); + do { + current->thread.saved_task = NULL ; + CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next); + if(current->thread.saved_task) + show_regs(&(current->thread.regs)); + next= current->thread.saved_task; + prev= current; + } while(current->thread.saved_task); return(current->thread.prev_sched); -- cgit v1.2.2 From edcc2205d33d6baefc773c915b6e7ce517bc0b19 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:47 -0700 Subject: [PATCH] uml: Remove an unused file This removes a file which is no longer used. Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_user.c | 75 ---------------------------------------------- 1 file changed, 75 deletions(-) delete mode 100644 arch/um/drivers/ubd_user.c (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c deleted file mode 100644 index b94d2bc4fe06..000000000000 --- a/arch/um/drivers/ubd_user.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "asm/types.h" -#include "user_util.h" -#include "kern_util.h" -#include "user.h" -#include "ubd_user.h" -#include "os.h" -#include "cow.h" - -#include -#include - -void ignore_sigwinch_sig(void) -{ - signal(SIGWINCH, SIG_IGN); -} - -int start_io_thread(unsigned long sp, int *fd_out) -{ - int pid, fds[2], err; - - err = os_pipe(fds, 1, 1); - if(err < 0){ - printk("start_io_thread - os_pipe failed, err = %d\n", -err); - goto out; - } - - kernel_fd = fds[0]; - *fd_out = fds[1]; - - 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; - goto out_close; - } - - return(pid); - - out_close: - os_close_file(fds[0]); - os_close_file(fds[1]); - kernel_fd = -1; - *fd_out = -1; - out: - 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: - */ -- cgit v1.2.2 From d9f0d9151083a9a77331a020a7fee498cf828e3b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:47 -0700 Subject: [PATCH] uml: Remove a useless include linux/inet.h isn't needed, and on my system, is empty. Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/mcast_user.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 7a0d115b29d0..3fd69067a5f5 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include -- cgit v1.2.2 From 64b7673f91c0c3614028c5942b0d6a91d0b64a98 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:48 -0700 Subject: [PATCH] uml: Remove some build warnings These ugly double-casts are the result of gdb complaining about size Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 2 +- arch/um/os-Linux/elf_aux.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index b04897cd995d..182905be869e 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -142,7 +142,7 @@ static int aio_thread(void *arg) "errno = %d\n", errno); } else { - aio = (struct aio_context *) event.data; + aio = (struct aio_context *) (long) event.data; if(update_aio(aio, event.res)){ do_aio(ctx, aio); continue; diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 1399520a8588..5c02e3395225 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -9,6 +9,7 @@ */ #include #include +#include #include "init.h" #include "elf_user.h" #include "mem_user.h" @@ -54,7 +55,8 @@ __init void scan_elf_aux( char **envp) * a_un, so we have to use a_val, which is * all that's left. */ - elf_aux_platform = (char *) auxv->a_un.a_val; + elf_aux_platform = + (char *) (long) auxv->a_un.a_val; break; case AT_PAGESZ: page_size = auxv->a_un.a_val; -- cgit v1.2.2 From b4fd310e163477236a241580b3b8c29aee65f4cc Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:49 -0700 Subject: [PATCH] uml: preserve errno in error paths The poster child for this patch is the third tuntap_user hunk. When an ioctl fails, it properly closes the opened file descriptor and returns. However, the close resets errno to 0, and the 'return errno' that follows returns 0 rather than the value that ioctl set. This caused the caller to believe that the device open succeeded and had opened file descriptor 0, which caused no end of interesting behavior. The rest of this patch is a pass through the UML sources looking for places where errno could be reset before being passed back out. A common culprit is printk, which could call write, being called before errno is returned. In some cases, where the code ends up being much smaller, I just deleted the printk. There was another case where a caller of run_helper looked at errno after a failure, rather than the return value of run_helper, which was the errno value that it wanted. Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/mcast_user.c | 11 +++-- arch/um/drivers/mconsole_user.c | 6 +-- arch/um/drivers/pty.c | 3 +- arch/um/drivers/xterm.c | 6 ++- arch/um/kernel/helper.c | 12 ++--- arch/um/kernel/user_util.c | 12 ++--- arch/um/os-Linux/aio.c | 5 ++- arch/um/os-Linux/drivers/tuntap_user.c | 8 ++-- arch/um/os-Linux/file.c | 82 +++++++++++++--------------------- 9 files changed, 67 insertions(+), 78 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 3fd69067a5f5..5db136e2651c 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -54,7 +54,7 @@ static int mcast_open(void *data) struct mcast_data *pri = data; struct sockaddr_in *sin = pri->mcast_addr; struct ip_mreq mreq; - int fd = -EINVAL, yes = 1, err = -EINVAL;; + int fd, yes = 1, err = 0; if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) @@ -65,13 +65,14 @@ static int mcast_open(void *data) if (fd < 0){ printk("mcast_open : data socket failed, errno = %d\n", errno); - fd = -errno; + err = -errno; goto out; } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", errno); + err = -errno; goto out_close; } @@ -80,6 +81,7 @@ static int mcast_open(void *data) sizeof(pri->ttl)) < 0) { printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", errno); + err = -errno; goto out_close; } @@ -87,12 +89,14 @@ static int mcast_open(void *data) if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", errno); + err = -errno; goto out_close; } /* bind socket to mcast address */ if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { printk("mcast_open : data bind failed, errno = %d\n", errno); + err = -errno; goto out_close; } @@ -107,14 +111,15 @@ static int mcast_open(void *data) "interface on the host.\n"); printk("eth0 should be configured in order to use the " "multicast transport.\n"); + err = -errno; goto out_close; } - out: return fd; out_close: os_close_file(fd); + out: return err; } diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index a5b8aeade1c5..310c1f823f26 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -173,9 +173,9 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len) if(notify_sock < 0){ notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0); if(notify_sock < 0){ - printk("mconsole_notify - socket failed, errno = %d\n", - errno); err = -errno; + printk("mconsole_notify - socket failed, errno = %d\n", + err); } } unlock_notify(); @@ -198,8 +198,8 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len) n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, sizeof(target)); if(n < 0){ - printk("mconsole_notify - sendto failed, errno = %d\n", errno); err = -errno; + printk("mconsole_notify - sendto failed, errno = %d\n", errno); } return(err); } diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index ed84d01df6cc..0306a1b215b7 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -43,8 +43,9 @@ static int pts_open(int input, int output, int primary, void *d, fd = get_pty(); if(fd < 0){ + err = -errno; printk("open_pts : Failed to open pts\n"); - return(-errno); + return err; } if(data->raw){ CATCH_EINTR(err = tcgetattr(fd, &data->tt)); diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 93dc1911363f..90e0e5ff451e 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -110,13 +110,15 @@ int xterm_open(int input, int output, int primary, void *d, fd = mkstemp(file); if(fd < 0){ + err = -errno; printk("xterm_open : mkstemp failed, errno = %d\n", errno); - return(-errno); + return err; } if(unlink(file)){ + err = -errno; printk("xterm_open : unlink failed, errno = %d\n", errno); - return(-errno); + return err; } os_close_file(fd); diff --git a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c index f83e1e8e2392..33fb0bd3b11a 100644 --- a/arch/um/kernel/helper.c +++ b/arch/um/kernel/helper.c @@ -85,8 +85,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, data.fd = fds[1]; pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); if(pid < 0){ - printk("run_helper : clone failed, errno = %d\n", errno); ret = -errno; + printk("run_helper : clone failed, errno = %d\n", errno); goto out_close; } @@ -122,7 +122,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, unsigned long *stack_out, int stack_order) { unsigned long stack, sp; - int pid, status; + int pid, status, err; stack = alloc_stack(stack_order, um_in_interrupt()); if(stack == 0) return(-ENOMEM); @@ -130,16 +130,18 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, sp = stack + (page_size() << stack_order) - sizeof(void *); pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); if(pid < 0){ + err = -errno; printk("run_helper_thread : clone failed, errno = %d\n", errno); - return(-errno); + return err; } if(stack_out == NULL){ CATCH_EINTR(pid = waitpid(pid, &status, 0)); if(pid < 0){ + err = -errno; printk("run_helper_thread - wait failed, errno = %d\n", errno); - pid = -errno; + pid = err; } if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) printk("run_helper_thread - thread returned status " @@ -156,8 +158,8 @@ int helper_wait(int pid) CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); if(ret < 0){ + ret = -errno; printk("helper_wait : waitpid failed, errno = %d\n", errno); - return(-errno); } return(ret); } diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c index 954ff67cc8b3..a25f3ea11fd7 100644 --- a/arch/um/kernel/user_util.c +++ b/arch/um/kernel/user_util.c @@ -109,18 +109,14 @@ int raw(int fd) int err; CATCH_EINTR(err = tcgetattr(fd, &tt)); - if (err < 0) { - printk("tcgetattr failed, errno = %d\n", errno); - return(-errno); - } + if(err < 0) + return -errno; cfmakeraw(&tt); CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt)); - if (err < 0) { - printk("tcsetattr failed, errno = %d\n", errno); - return(-errno); - } + if(err < 0) + return -errno; /* XXX tcsetattr could have applied only some changes * (and cfmakeraw() is a set of changes) */ diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 182905be869e..e942beb4e108 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -313,15 +313,16 @@ static int init_aio_26(void) int err; if(io_setup(256, &ctx)){ + err = -errno; printk("aio_thread failed to initialize context, err = %d\n", errno); - return -errno; + return err; } err = run_helper_thread(aio_thread, NULL, CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); if(err < 0) - return -errno; + return err; aio_pid = err; diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 4b83c6c3f48d..4ba9b17adf13 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -75,7 +75,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, struct msghdr msg; struct cmsghdr *cmsg; struct iovec iov; - int pid, n; + int pid, n, err; sprintf(version_buf, "%d", UML_NET_VERSION); @@ -105,9 +105,10 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, n = recvmsg(me, &msg, 0); *used_out = n; if(n < 0){ + err = -errno; printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", errno); - return(-errno); + return err; } CATCH_EINTR(waitpid(pid, NULL, 0)); @@ -147,9 +148,10 @@ static int tuntap_open(void *data) ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name)); if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){ + err = -errno; printk("TUNSETIFF failed, errno = %d\n", errno); os_close_file(pri->fd); - return(-errno); + return err; } } else { diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index fd45bb260907..f55773c819e6 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -119,15 +119,11 @@ int os_window_size(int fd, int *rows, int *cols) int os_new_tty_pgrp(int fd, int pid) { - if(ioctl(fd, TIOCSCTTY, 0) < 0){ - printk("TIOCSCTTY failed, errno = %d\n", errno); - return(-errno); - } + if(ioctl(fd, TIOCSCTTY, 0) < 0) + return -errno; - if(tcsetpgrp(fd, pid) < 0){ - printk("tcsetpgrp failed, errno = %d\n", errno); - return(-errno); - } + if(tcsetpgrp(fd, pid) < 0) + return -errno; return(0); } @@ -146,18 +142,12 @@ int os_set_slip(int fd) int disc, sencap; disc = N_SLIP; - if(ioctl(fd, TIOCSETD, &disc) < 0){ - printk("Failed to set slip line discipline - " - "errno = %d\n", errno); - return(-errno); - } + if(ioctl(fd, TIOCSETD, &disc) < 0) + return -errno; sencap = 0; - if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){ - printk("Failed to set slip encapsulation - " - "errno = %d\n", errno); - return(-errno); - } + if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0) + return -errno; return(0); } @@ -180,22 +170,15 @@ int os_sigio_async(int master, int slave) int flags; flags = fcntl(master, F_GETFL); - if(flags < 0) { - printk("fcntl F_GETFL failed, errno = %d\n", errno); - return(-errno); - } + if(flags < 0) + return errno; if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || - (fcntl(master, F_SETOWN, os_getpid()) < 0)){ - printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", - errno); - return(-errno); - } + (fcntl(master, F_SETOWN, os_getpid()) < 0)) + return -errno; - if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){ - printk("fcntl F_SETFL failed, errno = %d\n", errno); - return(-errno); - } + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) + return -errno; return(0); } @@ -255,7 +238,7 @@ int os_file_mode(char *file, struct openflags *mode_out) int os_open_file(char *file, struct openflags flags, int mode) { - int fd, f = 0; + int fd, err, f = 0; if(flags.r && flags.w) f = O_RDWR; else if(flags.r) f = O_RDONLY; @@ -272,8 +255,9 @@ int os_open_file(char *file, struct openflags flags, int mode) return(-errno); if(flags.cl && fcntl(fd, F_SETFD, 1)){ + err = -errno; os_close_file(fd); - return(-errno); + return err; } return(fd); @@ -383,9 +367,9 @@ int os_file_size(char *file, unsigned long long *size_out) return(fd); } if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ + err = -errno; printk("Couldn't get the block size of \"%s\", " "errno = %d\n", file, errno); - err = -errno; os_close_file(fd); return(err); } @@ -473,11 +457,14 @@ int os_pipe(int *fds, int stream, int close_on_exec) int os_set_fd_async(int fd, int owner) { + int err; + /* XXX This should do F_GETFL first */ if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){ + err = -errno; printk("os_set_fd_async : failed to set O_ASYNC and " "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno); - return(-errno); + return err; } #ifdef notdef if(fcntl(fd, F_SETFD, 1) < 0){ @@ -488,10 +475,11 @@ int os_set_fd_async(int fd, int owner) if((fcntl(fd, F_SETSIG, SIGIO) < 0) || (fcntl(fd, F_SETOWN, owner) < 0)){ + err = -errno; printk("os_set_fd_async : Failed to fcntl F_SETOWN " "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, owner, errno); - return(-errno); + return err; } return(0); @@ -516,11 +504,9 @@ int os_set_fd_block(int fd, int blocking) if(blocking) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; - if(fcntl(fd, F_SETFL, flags) < 0){ - printk("Failed to change blocking on fd # %d, errno = %d\n", - fd, errno); - return(-errno); - } + if(fcntl(fd, F_SETFL, flags) < 0) + return -errno; + return(0); } @@ -609,11 +595,8 @@ int os_create_unix_socket(char *file, int len, int close_on_exec) int sock, err; sock = socket(PF_UNIX, SOCK_DGRAM, 0); - if (sock < 0){ - printk("create_unix_socket - socket failed, errno = %d\n", - errno); - return(-errno); - } + if(sock < 0) + return -errno; if(close_on_exec) { err = os_set_exec_close(sock, 1); @@ -628,11 +611,8 @@ int os_create_unix_socket(char *file, int len, int close_on_exec) snprintf(addr.sun_path, len, "%s", file); err = bind(sock, (struct sockaddr *) &addr, sizeof(addr)); - if (err < 0){ - printk("create_listening_socket at '%s' - bind failed, " - "errno = %d\n", file, errno); - return(-errno); - } + if(err < 0) + return -errno; return(sock); } -- cgit v1.2.2 From 0f80bc85c587e8fdeecece4f294a47eca4922ea2 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:50 -0700 Subject: [PATCH] uml: move libc code out of mem_user.c and tempfile.c The serial UML OS-abstraction layer patch (um/kernel dir). This moves all system calls from mem_user.c and tempfile.c files under os-Linux dir. Signed-off-by: Gennady Sharapov Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/mem_user.h | 15 ---- arch/um/include/os.h | 5 ++ arch/um/kernel/Makefile | 6 +- arch/um/kernel/init_task.c | 5 +- arch/um/kernel/mem_user.c | 205 +------------------------------------------ arch/um/kernel/tempfile.c | 82 ----------------- arch/um/kernel/tlb.c | 2 +- arch/um/kernel/tt/mem_user.c | 1 + arch/um/kernel/um_arch.c | 5 -- arch/um/os-Linux/Makefile | 8 +- arch/um/os-Linux/mem.c | 161 +++++++++++++++++++++++++++++++++ arch/um/os-Linux/start_up.c | 109 ++++++++++++++++++++++- arch/um/os-Linux/tt.c | 14 +++ 13 files changed, 300 insertions(+), 318 deletions(-) delete mode 100644 arch/um/kernel/tempfile.c create mode 100644 arch/um/os-Linux/mem.c (limited to 'arch/um') diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h index d6404bb64662..9fef4123a65a 100644 --- a/arch/um/include/mem_user.h +++ b/arch/um/include/mem_user.h @@ -51,7 +51,6 @@ extern unsigned long task_size; extern void check_devanon(void); extern int init_mem_user(void); -extern int create_mem_file(unsigned long len); extern void setup_memory(void *entry); extern unsigned long find_iomem(char *driver, unsigned long *len_out); extern int init_maps(unsigned long physmem, unsigned long iomem, @@ -64,20 +63,6 @@ extern unsigned long phys_offset(unsigned long phys); extern void unmap_physmem(void); extern void map_memory(unsigned long virt, unsigned long phys, unsigned long len, int r, int w, int x); -extern int protect_memory(unsigned long addr, unsigned long len, - int r, int w, int x, int must_succeed); extern unsigned long get_kmem_end(void); -extern void check_tmpexec(void); #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/os.h b/arch/um/include/os.h index 4c362458052c..583329d0a539 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -157,6 +157,9 @@ extern int os_lock_file(int fd, int excl); extern void os_early_checks(void); extern int can_do_skas(void); +/* mem.c */ +extern int create_mem_file(unsigned long len); + /* process.c */ extern unsigned long os_process_pc(int pid); extern int os_process_parent(int pid); @@ -181,6 +184,8 @@ extern unsigned long long os_usecs(void); /* tt.c * for tt mode only (will be deleted in future...) */ +extern int protect_memory(unsigned long addr, unsigned long len, + int r, int w, int x, int must_succeed); extern void forward_pending_sigio(int target); extern int start_fork_tramp(void *arg, unsigned long temp_stack, int clone_flags, int (*tramp)(void *)); diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 614b8ebeb0ed..7eb52c5a7cab 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -10,7 +10,7 @@ obj-y = config.o exec_kern.o exitcode.o \ helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ physmem.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \ sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o \ - tempfile.o time.o time_kern.o tlb.o trap_kern.o trap_user.o \ + time.o time_kern.o tlb.o trap_kern.o trap_user.o \ uaccess_user.o um_arch.o umid.o user_util.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o @@ -24,8 +24,8 @@ obj-$(CONFIG_MODE_SKAS) += skas/ user-objs-$(CONFIG_TTY_LOG) += tty_log.o -USER_OBJS := $(user-objs-y) config.o helper.o main.o tempfile.o time.o \ - tty_log.o umid.o user_util.o +USER_OBJS := $(user-objs-y) config.o helper.o main.o time.o tty_log.o umid.o \ + user_util.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index cd7c85be0a1b..49ed5ddf0704 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c @@ -13,6 +13,7 @@ #include "asm/pgtable.h" #include "user_util.h" #include "mem_user.h" +#include "os.h" static struct fs_struct init_fs = INIT_FS; struct mm_struct init_mm = INIT_MM(init_mm); @@ -45,8 +46,8 @@ __attribute__((__section__(".data.init_task"))) = void unprotect_stack(unsigned long stack) { - protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, - 1, 1, 0, 1); + os_protect_memory((void *) stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, + 1, 1, 0); } /* diff --git a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c index 4a663fd434bb..d49640d9923f 100644 --- a/arch/um/kernel/mem_user.c +++ b/arch/um/kernel/mem_user.c @@ -48,219 +48,16 @@ #include "tempfile.h" #include "kern_constants.h" -#define TEMPNAME_TEMPLATE "vm_file-XXXXXX" - -static int create_tmp_file(unsigned long len) -{ - int fd, err; - char zero; - - fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1); - if(fd < 0) { - os_print_error(fd, "make_tempfile"); - exit(1); - } - - err = os_mode_fd(fd, 0777); - if(err < 0){ - os_print_error(err, "os_mode_fd"); - exit(1); - } - err = os_seek_file(fd, len); - if(err < 0){ - os_print_error(err, "os_seek_file"); - exit(1); - } - zero = 0; - err = os_write_file(fd, &zero, 1); - if(err != 1){ - os_print_error(err, "os_write_file"); - exit(1); - } - - return(fd); -} - -void check_tmpexec(void) -{ - void *addr; - int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); - - addr = mmap(NULL, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); - printf("Checking PROT_EXEC mmap in /tmp..."); - fflush(stdout); - if(addr == MAP_FAILED){ - err = errno; - perror("failed"); - if(err == EPERM) - printf("/tmp must be not mounted noexec\n"); - exit(1); - } - printf("OK\n"); - munmap(addr, UM_KERN_PAGE_SIZE); - - os_close_file(fd); -} - -static int have_devanon = 0; - -void check_devanon(void) -{ - int fd; - - printk("Checking for /dev/anon on the host..."); - fd = open("/dev/anon", O_RDWR); - if(fd < 0){ - printk("Not available (open failed with errno %d)\n", errno); - return; - } - - printk("OK\n"); - have_devanon = 1; -} - -static int create_anon_file(unsigned long len) -{ - void *addr; - int fd; - - fd = open("/dev/anon", O_RDWR); - if(fd < 0) { - os_print_error(fd, "opening /dev/anon"); - exit(1); - } - - addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if(addr == MAP_FAILED){ - perror("mapping physmem file"); - exit(1); - } - munmap(addr, len); - - return(fd); -} - -int create_mem_file(unsigned long len) -{ - int err, fd; - - if(have_devanon) - fd = create_anon_file(len); - else fd = create_tmp_file(len); - - err = os_set_exec_close(fd, 1); - if(err < 0) - os_print_error(err, "exec_close"); - return(fd); -} - struct iomem_region *iomem_regions = NULL; int iomem_size = 0; -static int __init parse_iomem(char *str, int *add) -{ - struct iomem_region *new; - struct uml_stat buf; - char *file, *driver; - int fd, err, size; - - driver = str; - file = strchr(str,','); - if(file == NULL){ - printf("parse_iomem : failed to parse iomem\n"); - goto out; - } - *file = '\0'; - file++; - fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0); - if(fd < 0){ - os_print_error(fd, "parse_iomem - Couldn't open io file"); - goto out; - } - - err = os_stat_fd(fd, &buf); - if(err < 0){ - os_print_error(err, "parse_iomem - cannot stat_fd file"); - goto out_close; - } - - new = malloc(sizeof(*new)); - if(new == NULL){ - perror("Couldn't allocate iomem_region struct"); - goto out_close; - } - - size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1); - - *new = ((struct iomem_region) { .next = iomem_regions, - .driver = driver, - .fd = fd, - .size = size, - .phys = 0, - .virt = 0 }); - iomem_regions = new; - iomem_size += new->size + UM_KERN_PAGE_SIZE; - - return(0); - out_close: - os_close_file(fd); - out: - return(1); -} +extern int parse_iomem(char *str, int *add) __init; __uml_setup("iomem=", parse_iomem, "iomem=,\n" " Configure as an IO memory region named .\n\n" ); -int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, - int must_succeed) -{ - int err; - - err = os_protect_memory((void *) addr, len, r, w, x); - if(err < 0){ - if(must_succeed) - panic("protect failed, err = %d", -err); - else return(err); - } - return(0); -} - -#if 0 -/* Debugging facility for dumping stuff out to the host, avoiding the timing - * problems that come with printf and breakpoints. - * Enable in case of emergency. - */ - -int logging = 1; -int logging_fd = -1; - -int logging_line = 0; -char logging_buf[512]; - -void log(char *fmt, ...) -{ - va_list ap; - struct timeval tv; - struct openflags flags; - - if(logging == 0) return; - if(logging_fd < 0){ - flags = of_create(of_trunc(of_rdwr(OPENFLAGS()))); - logging_fd = os_open_file("log", flags, 0644); - } - gettimeofday(&tv, NULL); - sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec, - tv.tv_usec); - va_start(ap, fmt); - vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap); - va_end(ap); - write(logging_fd, logging_buf, strlen(logging_buf)); -} -#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 diff --git a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c deleted file mode 100644 index b1674bc1395d..000000000000 --- a/arch/um/kernel/tempfile.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include "init.h" - -/* Modified from create_mem_file and start_debugger */ -static char *tempdir = NULL; - -static void __init find_tempdir(void) -{ - char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL }; - int i; - char *dir = NULL; - - if(tempdir != NULL) return; /* We've already been called */ - for(i = 0; dirs[i]; i++){ - dir = getenv(dirs[i]); - if((dir != NULL) && (*dir != '\0')) - break; - } - if((dir == NULL) || (*dir == '\0')) - dir = "/tmp"; - - tempdir = malloc(strlen(dir) + 2); - if(tempdir == NULL){ - fprintf(stderr, "Failed to malloc tempdir, " - "errno = %d\n", errno); - return; - } - strcpy(tempdir, dir); - strcat(tempdir, "/"); -} - -int make_tempfile(const char *template, char **out_tempname, int do_unlink) -{ - char tempname[MAXPATHLEN]; - int fd; - - find_tempdir(); - if (*template != '/') - strcpy(tempname, tempdir); - else - *tempname = 0; - strcat(tempname, template); - fd = mkstemp(tempname); - if(fd < 0){ - fprintf(stderr, "open - cannot create %s: %s\n", tempname, - strerror(errno)); - return -1; - } - if(do_unlink && (unlink(tempname) < 0)){ - perror("unlink"); - return -1; - } - if(out_tempname){ - *out_tempname = strdup(tempname); - if(*out_tempname == NULL){ - perror("strdup"); - return -1; - } - } - return(fd); -} - -/* - * 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/tlb.c b/arch/um/kernel/tlb.c index 80ed6188e8a2..0a562c3c0fd8 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -307,7 +307,7 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) } else if(pte_newprot(*pte)){ updated = 1; - protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1); + os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1); } addr += PAGE_SIZE; } diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c index 3085267459b1..03e589895388 100644 --- a/arch/um/kernel/tt/mem_user.c +++ b/arch/um/kernel/tt/mem_user.c @@ -12,6 +12,7 @@ #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/um_arch.c b/arch/um/kernel/um_arch.c index 09f6f7ce4695..f0a275947d34 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -361,11 +361,6 @@ int linux_main(int argc, char **argv) uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, &host_task_size, &task_size); - /* Need to check this early because mmapping happens before the - * kernel is running. - */ - check_tmpexec(); - brk_start = (unsigned long) sbrk(0); CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); /* Increase physical memory size for exec-shield users diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 7a1662419c0c..d15ec2af6a22 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -3,11 +3,11 @@ # Licensed under the GPL # -obj-y = aio.o elf_aux.o file.o process.o signal.o start_up.o time.o tt.o \ - tty.o user_syms.o drivers/ sys-$(SUBARCH)/ +obj-y = aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o time.o \ + tt.o tty.o user_syms.o drivers/ sys-$(SUBARCH)/ -USER_OBJS := aio.o elf_aux.o file.o process.o signal.o start_up.o time.o tt.o \ - tty.o +USER_OBJS := aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o \ + time.o tt.o tty.o elf_aux.o: $(ARCH_DIR)/kernel-offsets.h CFLAGS_elf_aux.o += -I$(objtree)/arch/um diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c new file mode 100644 index 000000000000..8e71edaaf80b --- /dev/null +++ b/arch/um/os-Linux/mem.c @@ -0,0 +1,161 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kern_util.h" +#include "user.h" +#include "user_util.h" +#include "mem_user.h" +#include "init.h" +#include "os.h" +#include "tempfile.h" +#include "kern_constants.h" + +#include + +static char *tempdir = NULL; + +static void __init find_tempdir(void) +{ + char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL }; + int i; + char *dir = NULL; + + if(tempdir != NULL) return; /* We've already been called */ + for(i = 0; dirs[i]; i++){ + dir = getenv(dirs[i]); + if((dir != NULL) && (*dir != '\0')) + break; + } + if((dir == NULL) || (*dir == '\0')) + dir = "/tmp"; + + tempdir = malloc(strlen(dir) + 2); + if(tempdir == NULL){ + fprintf(stderr, "Failed to malloc tempdir, " + "errno = %d\n", errno); + return; + } + strcpy(tempdir, dir); + strcat(tempdir, "/"); +} + +/* + * This proc still used in tt-mode + * (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) +{ + char tempname[MAXPATHLEN]; + int fd; + + find_tempdir(); + if (*template != '/') + strcpy(tempname, tempdir); + else + *tempname = 0; + strcat(tempname, template); + fd = mkstemp(tempname); + if(fd < 0){ + fprintf(stderr, "open - cannot create %s: %s\n", tempname, + strerror(errno)); + return -1; + } + if(do_unlink && (unlink(tempname) < 0)){ + perror("unlink"); + return -1; + } + if(out_tempname){ + *out_tempname = strdup(tempname); + if(*out_tempname == NULL){ + perror("strdup"); + return -1; + } + } + return(fd); +} + +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX" + +/* + * This proc is used in start_up.c + * So it isn't 'static'. + */ +int create_tmp_file(unsigned long len) +{ + int fd, err; + char zero; + + fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1); + if(fd < 0) { + exit(1); + } + + err = fchmod(fd, 0777); + if(err < 0){ + perror("os_mode_fd"); + exit(1); + } + + if (lseek64(fd, len, SEEK_SET) < 0) { + perror("os_seek_file"); + exit(1); + } + + zero = 0; + + err = os_write_file(fd, &zero, 1); + if(err != 1){ + errno = -err; + perror("os_write_file"); + exit(1); + } + + return(fd); +} + +static int create_anon_file(unsigned long len) +{ + void *addr; + int fd; + + fd = open("/dev/anon", O_RDWR); + if(fd < 0) { + perror("opening /dev/anon"); + exit(1); + } + + addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if(addr == MAP_FAILED){ + perror("mapping physmem file"); + exit(1); + } + munmap(addr, len); + + return(fd); +} + +extern int have_devanon; + +int create_mem_file(unsigned long len) +{ + int err, fd; + + if(have_devanon) + fd = create_anon_file(len); + else fd = create_tmp_file(len); + + err = os_set_exec_close(fd, 1); + if(err < 0){ + errno = -err; + perror("exec_close"); + } + return(fd); +} diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 040cc1472bc7..6af83171ca4e 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -4,18 +4,22 @@ */ #include +#include +#include +#include +#include #include #include #include +#include #include -#include -#include #include #include #include #include #include #include +#include #include "user_util.h" #include "kern_util.h" #include "user.h" @@ -25,6 +29,7 @@ #include "sysdep/sigcontext.h" #include "irq_user.h" #include "ptrace_user.h" +#include "mem_user.h" #include "time_user.h" #include "init.h" #include "os.h" @@ -32,6 +37,8 @@ #include "choose-mode.h" #include "mode.h" #include "tempfile.h" +#include "kern_constants.h" + #ifdef UML_CONFIG_MODE_SKAS #include "skas.h" #include "skas_ptrace.h" @@ -276,9 +283,38 @@ static void __init check_ptrace(void) check_sysemu(); } +extern int create_tmp_file(unsigned long len); + +static void check_tmpexec(void) +{ + void *addr; + int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); + + addr = mmap(NULL, UM_KERN_PAGE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); + printf("Checking PROT_EXEC mmap in /tmp..."); + fflush(stdout); + if(addr == MAP_FAILED){ + err = errno; + perror("failed"); + if(err == EPERM) + printf("/tmp must be not mounted noexec\n"); + exit(1); + } + printf("OK\n"); + munmap(addr, UM_KERN_PAGE_SIZE); + + close(fd); +} + void os_early_checks(void) { check_ptrace(); + + /* Need to check this early because mmapping happens before the + * kernel is running. + */ + check_tmpexec(); } static int __init noprocmm_cmd_param(char *str, int* add) @@ -357,3 +393,72 @@ int can_do_skas(void) return(0); } #endif + +int have_devanon = 0; + +void check_devanon(void) +{ + int fd; + + printk("Checking for /dev/anon on the host..."); + fd = open("/dev/anon", O_RDWR); + if(fd < 0){ + printk("Not available (open failed with errno %d)\n", errno); + return; + } + + printk("OK\n"); + have_devanon = 1; +} + +int __init parse_iomem(char *str, int *add) +{ + struct iomem_region *new; + struct uml_stat buf; + char *file, *driver; + int fd, err, size; + + driver = str; + file = strchr(str,','); + if(file == NULL){ + printf("parse_iomem : failed to parse iomem\n"); + goto out; + } + *file = '\0'; + file++; + fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0); + if(fd < 0){ + os_print_error(fd, "parse_iomem - Couldn't open io file"); + goto out; + } + + err = os_stat_fd(fd, &buf); + if(err < 0){ + os_print_error(err, "parse_iomem - cannot stat_fd file"); + goto out_close; + } + + new = malloc(sizeof(*new)); + if(new == NULL){ + perror("Couldn't allocate iomem_region struct"); + goto out_close; + } + + size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1); + + *new = ((struct iomem_region) { .next = iomem_regions, + .driver = driver, + .fd = fd, + .size = size, + .phys = 0, + .virt = 0 }); + iomem_regions = new; + iomem_size += new->size + UM_KERN_PAGE_SIZE; + + return(0); + out_close: + os_close_file(fd); + out: + return(1); +} + diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c index 5b047ab8416a..a6db8877931a 100644 --- a/arch/um/os-Linux/tt.c +++ b/arch/um/os-Linux/tt.c @@ -36,6 +36,20 @@ #include "mode.h" #include "tempfile.h" +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, + int must_succeed) +{ + int err; + + err = os_protect_memory((void *) addr, len, r, w, x); + if(err < 0){ + if(must_succeed) + panic("protect failed, err = %d", -err); + else return(err); + } + return(0); +} + /* *------------------------- * only for tt mode (will be deleted in future...) -- cgit v1.2.2 From 114069f7384c15a7a9f8d3e333caf4d470dfe520 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:51 -0700 Subject: [PATCH] uml: merge mem_user.c and mem.c The serial UML OS-abstraction layer patch (um/kernel dir). This joins mem_user.c and mem.c files. Signed-off-by: Gennady Sharapov Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/Makefile | 12 ++++---- arch/um/kernel/mem.c | 16 ++++++++++- arch/um/kernel/mem_user.c | 70 ----------------------------------------------- 3 files changed, 21 insertions(+), 77 deletions(-) delete mode 100644 arch/um/kernel/mem_user.c (limited to 'arch/um') diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 7eb52c5a7cab..1a0001b3850c 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -1,4 +1,4 @@ -# +# # Copyright (C) 2002 Jeff Dike (jdike@karaya.com) # Licensed under the GPL # @@ -7,11 +7,11 @@ extra-y := vmlinux.lds clean-files := obj-y = config.o exec_kern.o exitcode.o \ - helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ - physmem.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \ - sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o \ - time.o time_kern.o tlb.o trap_kern.o trap_user.o \ - uaccess_user.o um_arch.o umid.o user_util.o + helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o physmem.o \ + process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ + signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ + time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \ + umid.o user_util.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o obj-$(CONFIG_GPROF) += gprof_syms.o diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 64fa062cc119..ea008b031a8f 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) * Licensed under the GPL */ @@ -19,6 +19,10 @@ #include "mem_user.h" #include "uml_uaccess.h" #include "os.h" +#include "linux/types.h" +#include "linux/string.h" +#include "init.h" +#include "kern_constants.h" extern char __binary_start; @@ -368,6 +372,16 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) return pte; } +struct iomem_region *iomem_regions = NULL; +int iomem_size = 0; + +extern int parse_iomem(char *str, int *add) __init; + +__uml_setup("iomem=", parse_iomem, +"iomem=,\n" +" Configure as an IO memory region named .\n\n" +); + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff --git a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c deleted file mode 100644 index d49640d9923f..000000000000 --- a/arch/um/kernel/mem_user.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * arch/um/kernel/mem_user.c - * - * BRIEF MODULE DESCRIPTION - * user side memory routines for supporting IO memory inside user mode linux - * - * Copyright (C) 2001 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kern_util.h" -#include "user.h" -#include "user_util.h" -#include "mem_user.h" -#include "init.h" -#include "os.h" -#include "tempfile.h" -#include "kern_constants.h" - -struct iomem_region *iomem_regions = NULL; -int iomem_size = 0; - -extern int parse_iomem(char *str, int *add) __init; - -__uml_setup("iomem=", parse_iomem, -"iomem=,\n" -" Configure as an IO memory region named .\n\n" -); - -/* - * 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.2 From 2867ace6751adc20bb37cfb09478510c49110b27 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:51 -0700 Subject: [PATCH] uml: return a real error code do_aio used to return -1 on error instead of errno. Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/um') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index e942beb4e108..298d5632128b 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -117,6 +117,8 @@ static int do_aio(aio_context_t ctx, struct aio_context *aio) err = io_submit(ctx, 1, &iocbp); if(err > 0) err = 0; + else + err = -errno; out: return err; -- cgit v1.2.2 From 1f87b1e6e6050c0afe8b4afc279121f99043dc54 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:27:52 -0700 Subject: [PATCH] uml: remove include of asm/elf.h asm/elf.h is bad on x86_64, and i386 doesn't need it any more after Al's cleanup. Signed-off-by: Jeff Dike Cc: Paolo Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/elf_aux.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 5c02e3395225..e770cb029578 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -9,7 +9,6 @@ */ #include #include -#include #include "init.h" #include "elf_user.h" #include "mem_user.h" -- cgit v1.2.2 From 3013449243adc3421b507696e5d247a3d292ee0c Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 16 Sep 2005 19:28:03 -0700 Subject: [PATCH] uml: UML/i386 cmpxchg fix Using native cmpxchg offers a slight performance improvement in uml/i386. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig.i386 | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/um') diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386 index 8ad156a00499..5d92cacd56c6 100644 --- a/arch/um/Kconfig.i386 +++ b/arch/um/Kconfig.i386 @@ -42,3 +42,7 @@ config ARCH_HAS_SC_SIGNALS config ARCH_REUSE_HOST_VSYSCALL_AREA bool default y + +config X86_CMPXCHG + bool + default y -- cgit v1.2.2 From 76629ac154aacfec8883954c3ff9871905d2fb8e Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:38:33 +0200 Subject: [PATCH] uml: remove verify_area_{tt,skas} When removing verify_area, verify_area_{tt,skas} were forgotten. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/include/uaccess-skas.h | 6 ------ arch/um/kernel/tt/include/uaccess-tt.h | 6 ------ 2 files changed, 12 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h index 6ee3f3902e68..7da0c2def0ef 100644 --- a/arch/um/kernel/skas/include/uaccess-skas.h +++ b/arch/um/kernel/skas/include/uaccess-skas.h @@ -18,12 +18,6 @@ ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) -static inline int verify_area_skas(int type, const void __user * addr, - unsigned long size) -{ - return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); -} - extern int copy_from_user_skas(void *to, const void __user *from, int n); extern int copy_to_user_skas(void __user *to, const void *from, int n); extern int strncpy_from_user_skas(char *dst, const char __user *src, int count); diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h index aa6db384af80..dc2ebfa8c54f 100644 --- a/arch/um/kernel/tt/include/uaccess-tt.h +++ b/arch/um/kernel/tt/include/uaccess-tt.h @@ -33,12 +33,6 @@ extern unsigned long uml_physmem; (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ (under_task_size(addr, size) || is_stack(addr, size)))) -static inline int verify_area_tt(int type, const void __user * addr, - unsigned long size) -{ - return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); -} - extern unsigned long get_fault_addr(void); extern int __do_copy_from_user(void *to, const void *from, int n, -- cgit v1.2.2 From 36decba90b184a25b7f77fb7df1612125cc41ac5 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:38:57 +0200 Subject: [PATCH] uml: fix modify_ldt - missing break in switch I am a lamer :-(. Luckily, Luo Xin performed LTP testing and found this failure. Btw, the fact that the patch in which I introduced this was merged shows that: a) I'm really trusted by people b) sometimes they're wrong about point a). c) lack of time for reviewers. CC: Luo Xin Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/sys-i386/ldt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/um') diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index bd3c34aa52e5..36b5c2c13289 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -83,6 +83,7 @@ int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) goto out; } p = buf; + break; default: res = -ENOSYS; goto out; -- cgit v1.2.2 From 8e5cb35a60c8792ffc3ba89ea66ebdd3c2f01cb1 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:39:14 +0200 Subject: [PATCH] uml: fix uname output on 32-bit binary on 64-bit host Translate uname output taken from the host if needed. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/kernel/user_util.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/um') diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c index a25f3ea11fd7..41d17c71511c 100644 --- a/arch/um/kernel/user_util.c +++ b/arch/um/kernel/user_util.c @@ -128,6 +128,12 @@ void setup_machinename(char *machine_out) struct utsname host; uname(&host); +#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT) + if (!strcmp(host.machine, "x86_64")) { + strcpy(machine_out, "i686"); + return; + } +#endif strcpy(machine_out, host.machine); } -- cgit v1.2.2 From fd7481047882eaa0a692a545d5f8419612ece1b0 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:39:32 +0200 Subject: [PATCH] uml: Fix conflict between libc and ipv6 gcc is now complaining during link on some hosts - fix it as for other things. Reported by Antoine Martin . Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index ce987266dac6..5b5af95721ab 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -53,9 +53,13 @@ SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) # -Dvmap=kernel_vmap affects everything, and prevents anything from # referencing the libpcap.o symbol so named. +# +# Same things for in6addr_loopback - found in libc. CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ - $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap + $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ + -Din6addr_loopback=kernel_in6addr_loopback + AFLAGS += $(ARCH_INCLUDE) USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) -- cgit v1.2.2 From 41c79dc3825545d9aa2d5e5b1a99f8faabf51455 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:39:47 +0200 Subject: [PATCH] uml: fix bogus HOST_ELF_CLASS symbol name Even if with a bit of misunderstanding, Al fixed this in commit 95608261dae863bc43292e6fbd946a3abd3aa49f. Well, the symbol was intended to come from userspace (it exists there on normal host), but since some hosts may miss that, using the kernel one is just as fine. However, rename it to be named consistently with the rest. Actually, he missed converting ELFCLASS32 to coming from kernel headers. For consistence, add ELFCLASS64 too. Cc: Al Viro Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/include/common-offsets.h | 4 +++- arch/um/os-Linux/elf_aux.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h index 0aa620970adb..782ac3a3baf9 100644 --- a/arch/um/include/common-offsets.h +++ b/arch/um/include/common-offsets.h @@ -12,4 +12,6 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING); DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); DEFINE_STR(UM_KERN_INFO, KERN_INFO); DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); -DEFINE(HOST_ELF_CLASS, ELF_CLASS); +DEFINE(UM_ELF_CLASS, ELF_CLASS); +DEFINE(UM_ELFCLASS32, ELFCLASS32); +DEFINE(UM_ELFCLASS64, ELFCLASS64); diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index e770cb029578..ab33cb3c74ec 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -14,7 +14,8 @@ #include "mem_user.h" #include -#if HOST_ELF_CLASS == ELFCLASS32 +/* Use the one from the kernel - the host may miss it, if having old headers. */ +#if UM_ELF_CLASS == UM_ELFCLASS32 typedef Elf32_auxv_t elf_auxv_t; #else typedef Elf64_auxv_t elf_auxv_t; -- cgit v1.2.2 From ae756df8ddd00a30bb3bdf6774b514c096dda4a4 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:40:10 +0200 Subject: [PATCH] uml: readd removed unistd.h inclusion Readd this header (deleted in 60d339f6fe0831060600c62418b71a62ad26c281). A warning is spit out here about undeclared getpgrp(). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/os-Linux/process.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/um') diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index d32413e4b4ce..d9c52387c4a1 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -3,6 +3,7 @@ * Licensed under the GPL */ +#include #include #include #include -- cgit v1.2.2 From a46c9047642d70f5619e4a14129d74dd1f6ea74f Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:40:29 +0200 Subject: [PATCH] uml: comment about cast build fix Explain why the casting we do to silence this warning is indeed safe. It is because the field we're casting from, though being 64-bit wide, was filled with a pointer in first place by ourselves. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/os-Linux/aio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/um') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 298d5632128b..f6e64026f995 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -144,6 +144,7 @@ static int aio_thread(void *arg) "errno = %d\n", errno); } else { + /* This is safe as we've just a pointer here. */ aio = (struct aio_context *) (long) event.data; if(update_aio(aio, event.res)){ do_aio(ctx, aio); -- cgit v1.2.2 From efb0372bbaf5b829ff8c39db372779928af542a7 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 21 Sep 2005 18:40:49 +0200 Subject: [PATCH] uml: fix compile warning after consolidation patch The header declaring this function wasn't included, so the function declaration was totally bogus wrt. the proto - even if this wasn't going to fail at all. It was so bad that the compile warning I got was "control reaches end of non-void function", i.e. missing return. Actually, this has been there for ages, the consolidation patch just added the warning which was needed to clean it up. Nice. Really. Cc: Allan Graves Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/kernel/tt/process_kern.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 0de05a268b22..cfaa373a6e77 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -23,10 +23,11 @@ #include "mem_user.h" #include "tlb.h" #include "mode.h" +#include "mode_kern.h" #include "init.h" #include "tt.h" -int switch_to_tt(void *prev, void *next, void *last) +void switch_to_tt(void *prev, void *next) { struct task_struct *from, *to, *prev_sched; unsigned long flags; -- cgit v1.2.2 From 3a02d6c051cf3c214aab38e4330b4bcec5f6e3f8 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:12 -0700 Subject: [PATCH] uml: don't remove umid files in conflict case Only remove the UML pidfile and management socket if we created them. Currently in case two UMLs are started with the same umid, the second will remove the first's ones. Probably we should also panic() at that point, not sure however. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/umid.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c index 186c28885016..251d277fff2a 100644 --- a/arch/um/kernel/umid.c +++ b/arch/um/kernel/umid.c @@ -31,6 +31,8 @@ static char *uml_dir = UML_DIR; /* Changed by set_umid */ static int umid_is_random = 1; static int umid_inited = 0; +/* Have we created the files? Should we remove them? */ +static int umid_owned = 0; static int make_umid(int (*printer)(const char *fmt, ...)); @@ -82,20 +84,21 @@ int __init umid_file_name(char *name, char *buf, int len) extern int tracing_pid; -static int __init create_pid_file(void) +static void __init create_pid_file(void) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")]; int fd, n; - if(umid_file_name("pid", file, sizeof(file))) return 0; + if(umid_file_name("pid", file, sizeof(file))) + return; fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 0644); if(fd < 0){ printf("Open of machine pid file \"%s\" failed: %s\n", file, strerror(-fd)); - return 0; + return; } sprintf(pid, "%d\n", os_getpid()); @@ -103,7 +106,6 @@ static int __init create_pid_file(void) if(n != strlen(pid)) printf("Write of pid file failed - err = %d\n", -n); os_close_file(fd); - return 0; } static int actually_do_remove(char *dir) @@ -147,7 +149,8 @@ static int actually_do_remove(char *dir) void remove_umid_dir(void) { char dir[strlen(uml_dir) + UMID_LEN + 1]; - if(!umid_inited) return; + if (!umid_owned) + return; sprintf(dir, "%s%s", uml_dir, umid); actually_do_remove(dir); @@ -155,11 +158,12 @@ void remove_umid_dir(void) char *get_umid(int only_if_set) { - if(only_if_set && umid_is_random) return(NULL); - return(umid); + if(only_if_set && umid_is_random) + return NULL; + return umid; } -int not_dead_yet(char *dir) +static int not_dead_yet(char *dir) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")], *end; @@ -193,7 +197,8 @@ int not_dead_yet(char *dir) (p == CHOOSE_MODE(tracing_pid, os_getpid()))) dead = 1; } - if(!dead) return(1); + if(!dead) + return(1); return(actually_do_remove(dir)); } @@ -286,6 +291,7 @@ static int __init make_umid(int (*printer)(const char *fmt, ...)) if(errno == EEXIST){ if(not_dead_yet(tmp)){ (*printer)("umid '%s' is in use\n", umid); + umid_owned = 0; return(-1); } err = mkdir(tmp, 0777); @@ -296,7 +302,8 @@ static int __init make_umid(int (*printer)(const char *fmt, ...)) return(-1); } - return(0); + umid_owned = 1; + return 0; } __uml_setup("uml_dir=", set_uml_dir, @@ -309,7 +316,8 @@ static int __init make_umid_setup(void) /* one function with the ordering we need ... */ make_uml_dir(); make_umid(printf); - return create_pid_file(); + create_pid_file(); + return 0; } __uml_postsetup(make_umid_setup); -- cgit v1.2.2 From a8bfb94c58238666df0d6856861d18f0f52fc752 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:14 -0700 Subject: [PATCH] strlcat: use for uml umid.c Simplify the code by using strlcat() instead of strncat() and manual appending. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user.h | 4 +++- arch/um/kernel/umid.c | 11 ++++------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/user.h b/arch/um/include/user.h index 57ee9e261228..0f865ef46918 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h @@ -14,7 +14,9 @@ extern void *um_kmalloc_atomic(int size); extern void kfree(void *ptr); extern int in_aton(char *str); extern int open_gdb_chan(void); -extern int strlcpy(char *, const char *, int); +/* 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 void *um_vmalloc(int size); extern void vfree(void *ptr); diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c index 251d277fff2a..0b21d59ba0cd 100644 --- a/arch/um/kernel/umid.c +++ b/arch/um/kernel/umid.c @@ -237,16 +237,13 @@ static int __init make_uml_dir(void) strlcpy(dir, home, sizeof(dir)); uml_dir++; } + strlcat(dir, uml_dir, sizeof(dir)); len = strlen(dir); - strncat(dir, uml_dir, sizeof(dir) - len); - len = strlen(dir); - if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){ - dir[len] = '/'; - dir[len + 1] = '\0'; - } + if (len > 0 && dir[len - 1] != '/') + strlcat(dir, "/", sizeof(dir)); uml_dir = malloc(strlen(dir) + 1); - if(uml_dir == NULL){ + if (uml_dir == NULL) { printf("make_uml_dir : malloc failed, errno = %d\n", errno); exit(1); } -- cgit v1.2.2 From 546fe1cbf91d4d62e3849517c31a2327c992e5c5 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:16 -0700 Subject: [PATCH] uml: fix hang in TT mode on fault The current code doesn't handle well general protection faults on the host - it thinks that cr2 is always the address of a page fault. While actually, on general protection faults, that address is not accessible, so we'd better assume we couldn't satisfy the fault. Currently instead we think we've fixed it, so we go back, retry the instruction and fault again endlessly. This leads to the kernel hanging when doing copy_from_user(dest, -1, ...) in TT mode, since reading *(-1) causes a GFP, and we don't support kernel preemption. Thanks to Luo Xin for testing UML with LTP and reporting the failures he got. Cc: Luo Xin Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/trap_kern.c | 11 ++++++++++- arch/um/kernel/tt/uaccess_user.c | 11 +++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 87cc6fd76ced..90690b9b1f30 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c @@ -18,6 +18,7 @@ #include "asm/a.out.h" #include "asm/current.h" #include "asm/irq.h" +#include "sysdep/sigcontext.h" #include "user_util.h" #include "kern_util.h" #include "kern.h" @@ -125,7 +126,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) } else if(current->mm == NULL) panic("Segfault with no mm"); - err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); + + if (SEGV_IS_FIXABLE(&fi)) + err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); + else { + err = -EFAULT; + /* A thread accessed NULL, we get a fault, but CR2 is invalid. + * This code is used in __do_copy_from_user() of TT mode. */ + address = 0; + } catcher = current->thread.fault_catcher; if(!err) diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c index f01475512ecb..8c220f054b61 100644 --- a/arch/um/kernel/tt/uaccess_user.c +++ b/arch/um/kernel/tt/uaccess_user.c @@ -22,8 +22,15 @@ int __do_copy_from_user(void *to, const void *from, int n, __do_copy, &faulted); TASK_REGS(get_current())->tt = save; - if(!faulted) return(0); - else return(n - (fault - (unsigned long) from)); + if(!faulted) + return 0; + else if (fault) + return n - (fault - (unsigned long) from); + else + /* In case of a general protection fault, we don't have the + * fault address, so NULL is used instead. Pretend we didn't + * copy anything. */ + return n; } static void __do_strncpy(void *dst, const void *src, int count) -- cgit v1.2.2 From dc36abf34e13aabbe06cdd060c434b3cdd80e7da Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:18 -0700 Subject: [PATCH] uml: fix condition in tlb flush Avoid setting w = 0 twice. Spotted this (trivial) thing which is needed for another patch. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tlb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 0a562c3c0fd8..f5b0636f9ad7 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -193,12 +193,12 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, r = pte_read(*npte); w = pte_write(*npte); x = pte_exec(*npte); - if(!pte_dirty(*npte)) - w = 0; - if(!pte_young(*npte)){ - r = 0; - w = 0; - } + 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, -- cgit v1.2.2 From 12ebcd73e40e09f0dfddf89e465cc0541e0ff8b1 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:19 -0700 Subject: [PATCH] uml: run mconsole "sysrq" in process context Things are breaking horribly with sysrq called in interrupt context. I want to try to fix it, but probably this is simpler. To tell the truth, sysrq is normally run in interrupt context, so there shouldn't be any problem. There's also a warning from the fault handler because it's run in atomic context (I have a patch for that, only I deferred it). This is why I'm doing this. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/mconsole_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index 310c1f823f26..04383f98f4d5 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -23,7 +23,7 @@ static struct mconsole_command commands[] = { { "reboot", mconsole_reboot, MCONSOLE_PROC }, { "config", mconsole_config, MCONSOLE_PROC }, { "remove", mconsole_remove, MCONSOLE_PROC }, - { "sysrq", mconsole_sysrq, MCONSOLE_INTR }, + { "sysrq", mconsole_sysrq, MCONSOLE_PROC }, { "help", mconsole_help, MCONSOLE_INTR }, { "cad", mconsole_cad, MCONSOLE_INTR }, { "stop", mconsole_stop, MCONSOLE_PROC }, -- cgit v1.2.2 From fea03cb40a15e3c6647c0927300202e062e6792a Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:20 -0700 Subject: [PATCH] uml: avoid fixing faults while atomic Following i386, we should maybe refuse trying to fault in pages when we're doing atomic operations, because to handle the fault we could need to take already taken spinlocks. Also, if we're doing an atomic operation (in the sense of in_atomic()) we're surely in kernel mode and we're surely going to handle adequately the failed fault, so it's safe to behave this way. Currently, on UML SMP is rarely used, and we don't support PREEMPT, so this is unlikely to create problems right now, but it might in the future. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/trap_kern.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/um') diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 90690b9b1f30..d297429ac360 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c @@ -40,6 +40,12 @@ int handle_page_fault(unsigned long address, unsigned long ip, int err = -EFAULT; *code_out = SEGV_MAPERR; + + /* If the fault was during atomic operation, don't take the fault, just + * fail. */ + if (in_atomic()) + goto out_nosemaphore; + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if(!vma) @@ -90,6 +96,7 @@ survive: flush_tlb_page(vma, address); out: up_read(&mm->mmap_sem); +out_nosemaphore: return(err); /* -- cgit v1.2.2 From 46db4a42dd1190a311c2fb45106dfd0842c65a94 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:20 -0700 Subject: [PATCH] uml: Fix GFP_ flags usage GFP_ATOMIC | GFP_KERNEL is meaningless and won't work. Actually it never worked, even in 2.4. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process_kern.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 39cf568ccfaf..ea65db679e9c 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -82,7 +82,8 @@ unsigned long alloc_stack(int order, int atomic) unsigned long page; int flags = GFP_KERNEL; - if(atomic) flags |= GFP_ATOMIC; + if (atomic) + flags = GFP_ATOMIC; page = __get_free_pages(flags, order); if(page == 0) return(0); -- cgit v1.2.2 From 79ae2cb856ed6a8c48f455d52d5ed5960c671e67 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:21 -0700 Subject: [PATCH] uml: use GFP_ATOMIC for allocations under spinlocks. setup_initial_poll is only called with sigio_lock() held, so use appropriate allocation. Also, parse_chan() can also be called when holding a spinlock (see line_open() -> parse_chan_pair()). I have sporadic problems (spinlock taken twice, with spinlock debugging on UP) which could be caused by a sequence like "take spinlock, alloc and go to sleep, take again the spinlock in the other thread". Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 2 +- arch/um/kernel/sigio_user.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 14a12d6b3df6..244e54a2153b 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -465,7 +465,7 @@ static struct chan *parse_chan(char *str, int pri, int device, data = (*ops->init)(str, device, opts); if(data == NULL) return(NULL); - chan = kmalloc(sizeof(*chan), GFP_KERNEL); + chan = kmalloc(sizeof(*chan), GFP_ATOMIC); if(chan == NULL) return(NULL); *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), .primary = 1, diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index e89218958f38..a52751108aa1 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c @@ -340,7 +340,7 @@ static int setup_initial_poll(int fd) { struct pollfd *p; - p = um_kmalloc(sizeof(struct pollfd)); + p = um_kmalloc_atomic(sizeof(struct pollfd)); if(p == NULL){ printk("setup_initial_poll : failed to allocate poll\n"); return(-1); -- cgit v1.2.2 From fac97ae0b1a206e2952baf1f9eb46305d673adc6 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 22 Sep 2005 21:44:22 -0700 Subject: [PATCH] uml: replace printk with "stack-friendly" printf - to report console failure User get *a lot* confused when consoles don't work but we don't report anything. And, as reported in the comment, using printk to report "your console doesn't work" isn't likely to go that far. Fix the problem on the base of this: stack consumption by host printf(). Use kernel sprintf() and os_write_file, using a wild guess that one page will be enough for the message, to preallocate the buffer with kmalloc(). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 58 ++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 244e54a2153b..16e7dc89f61d 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -19,18 +19,44 @@ #include "line.h" #include "os.h" -#ifdef CONFIG_NOCONFIG_CHAN +/* XXX: could well be moved to somewhere else, if needed. */ +static int my_printf(const char * fmt, ...) + __attribute__ ((format (printf, 1, 2))); + +static int my_printf(const char * fmt, ...) +{ + /* Yes, can be called on atomic context.*/ + char *buf = kmalloc(4096, GFP_ATOMIC); + va_list args; + int r; + + if (!buf) { + /* We print directly fmt. + * Yes, yes, yes, feel free to complain. */ + r = strlen(fmt); + } else { + va_start(args, fmt); + r = vsprintf(buf, fmt, args); + va_end(args); + fmt = buf; + } -/* The printk's here are wrong because we are complaining that there is no - * output device, but printk is printing to that output device. The user will - * never see the error. printf would be better, except it can't run on a - * kernel stack because it will overflow it. - * Use printk for now since that will avoid crashing. - */ + if (r) + r = os_write_file(1, fmt, r); + return r; + +} + +#ifdef CONFIG_NOCONFIG_CHAN +/* Despite its name, there's no added trailing newline. */ +static int my_puts(const char * buf) +{ + return os_write_file(1, buf, strlen(buf)); +} static void *not_configged_init(char *str, int device, struct chan_opts *opts) { - printk(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); return(NULL); } @@ -38,27 +64,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts) static int not_configged_open(int input, int output, int primary, void *data, char **dev_out) { - printk(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); return(-ENODEV); } static void not_configged_close(int fd, void *data) { - printk(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); } static int not_configged_read(int fd, char *c_out, void *data) { - printk(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); return(-EIO); } static int not_configged_write(int fd, const char *buf, int len, void *data) { - printk(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); return(-EIO); } @@ -66,7 +92,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data) static int not_configged_console_write(int fd, const char *buf, int len, void *data) { - printk(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); return(-EIO); } @@ -74,14 +100,14 @@ static int not_configged_console_write(int fd, const char *buf, int len, static int not_configged_window_size(int fd, void *data, unsigned short *rows, unsigned short *cols) { - printk(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); return(-ENODEV); } static void not_configged_free(void *data) { - printf(KERN_ERR "Using a channel type which is configured out of " + my_puts("Using a channel type which is configured out of " "UML\n"); } @@ -457,7 +483,7 @@ static struct chan *parse_chan(char *str, int pri, int device, } } if(ops == NULL){ - printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", + my_printf("parse_chan couldn't parse \"%s\"\n", str); return(NULL); } -- cgit v1.2.2 From ecba97d4aacf4e80c56eb73e39af0369cb8539a4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 28 Sep 2005 22:27:23 +0100 Subject: [PATCH] uml makefiles sanitized UML makefiles sanitized: - number of generated headers reduced to 2 (from user-offsets.c and kernel-offsets.c resp.). The rest is made constant and simply includes those two. - mk_... helpers are gone now that we don't need to generate these headers - arch/um/include2 removed since everything under arch/um/include/sysdep is constant now and symlink can point straight to source tree. - dependencies seriously simplified. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/um/Makefile | 68 +++------------- arch/um/Makefile-i386 | 22 ------ arch/um/Makefile-skas | 2 - arch/um/Makefile-x86_64 | 21 ----- arch/um/include/common-offsets.h | 4 +- arch/um/include/skas_ptregs.h | 6 ++ arch/um/include/sysdep-i386/sc.h | 44 +++++++++++ arch/um/include/sysdep-i386/thread.h | 11 +++ arch/um/include/sysdep-x86_64/sc.h | 45 +++++++++++ arch/um/include/sysdep-x86_64/thread.h | 10 +++ arch/um/include/task.h | 9 +++ arch/um/kernel/skas/Makefile | 2 - arch/um/kernel/skas/util/Makefile | 5 -- arch/um/kernel/skas/util/mk_ptregs-i386.c | 49 ------------ arch/um/kernel/skas/util/mk_ptregs-x86_64.c | 66 ---------------- arch/um/os-Linux/elf_aux.c | 2 +- arch/um/os-Linux/util/Makefile | 4 - arch/um/os-Linux/util/mk_user_constants.c | 23 ------ arch/um/sys-i386/Makefile | 2 - arch/um/sys-i386/kernel-offsets.c | 4 +- arch/um/sys-i386/user-offsets.c | 73 ++++++++--------- arch/um/sys-i386/util/Makefile | 5 -- arch/um/sys-i386/util/mk_sc.c | 51 ------------ arch/um/sys-i386/util/mk_thread.c | 22 ------ arch/um/sys-x86_64/Makefile | 2 - arch/um/sys-x86_64/kernel-offsets.c | 2 +- arch/um/sys-x86_64/user-offsets.c | 117 +++++++++++++++------------- arch/um/sys-x86_64/util/Makefile | 8 -- arch/um/sys-x86_64/util/mk_sc.c | 47 ----------- arch/um/sys-x86_64/util/mk_thread.c | 20 ----- arch/um/util/Makefile | 5 -- arch/um/util/mk_constants.c | 32 -------- arch/um/util/mk_task.c | 30 ------- 33 files changed, 240 insertions(+), 573 deletions(-) create mode 100644 arch/um/include/skas_ptregs.h create mode 100644 arch/um/include/sysdep-i386/sc.h create mode 100644 arch/um/include/sysdep-i386/thread.h create mode 100644 arch/um/include/sysdep-x86_64/sc.h create mode 100644 arch/um/include/sysdep-x86_64/thread.h create mode 100644 arch/um/include/task.h delete mode 100644 arch/um/kernel/skas/util/Makefile delete mode 100644 arch/um/kernel/skas/util/mk_ptregs-i386.c delete mode 100644 arch/um/kernel/skas/util/mk_ptregs-x86_64.c delete mode 100644 arch/um/os-Linux/util/Makefile delete mode 100644 arch/um/os-Linux/util/mk_user_constants.c delete mode 100644 arch/um/sys-i386/util/Makefile delete mode 100644 arch/um/sys-i386/util/mk_sc.c delete mode 100644 arch/um/sys-i386/util/mk_thread.c delete mode 100644 arch/um/sys-x86_64/util/Makefile delete mode 100644 arch/um/sys-x86_64/util/mk_sc.c delete mode 100644 arch/um/sys-x86_64/util/mk_thread.c delete mode 100644 arch/um/util/Makefile delete mode 100644 arch/um/util/mk_constants.c delete mode 100644 arch/um/util/mk_task.c (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index 5b5af95721ab..7af37e342e33 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -28,8 +28,6 @@ SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \ $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h -GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h - um-modes-$(CONFIG_MODE_TT) += tt um-modes-$(CONFIG_MODE_SKAS) += skas @@ -45,9 +43,7 @@ endif ARCH_INCLUDE := -I$(ARCH_DIR)/include ifneq ($(KBUILD_SRC),) -ARCH_INCLUDE += -I$(ARCH_DIR)/include2 ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include -MRPROPER_DIRS += $(ARCH_DIR)/include2 endif SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) @@ -87,10 +83,6 @@ CONFIG_KERNEL_HALF_GIGS ?= 0 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) -ifeq ($(CONFIG_MODE_SKAS), y) -$(SYS_HEADERS) : $(ARCH_DIR)/include/skas_ptregs.h -endif - .PHONY: linux all: linux @@ -111,7 +103,8 @@ else $(shell cd $(ARCH_DIR) && ln -sf Kconfig.$(SUBARCH) Kconfig.arch) endif -archprepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) +archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR)/include/user_constants.h +prepare: $(ARCH_DIR)/include/kern_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib @@ -146,15 +139,13 @@ endef #When cleaning we don't include .config, so we don't include #TT or skas makefiles and don't clean skas_ptregs.h. CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \ - $(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \ - $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/Kconfig.arch + $(ARCH_DIR)/include/user_constants.h \ + $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \ $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os archclean: - $(Q)$(MAKE) $(clean)=$(ARCH_DIR)/util - $(Q)$(MAKE) $(clean)=$(ARCH_DIR)/os-$(OS)/util @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ -o -name '*.gcov' \) -type f -print | xargs rm -f @@ -180,9 +171,7 @@ $(ARCH_DIR)/include/sysdep: @echo ' SYMLINK $@' ifneq ($(KBUILD_SRC),) $(Q)mkdir -p $(ARCH_DIR)/include - $(Q)mkdir -p $(ARCH_DIR)/include2 - $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep - $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep + $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep else $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep endif @@ -202,8 +191,6 @@ endef define filechk_gen-asm-offsets (set -e; \ - echo "#ifndef __ASM_OFFSETS_H__"; \ - echo "#define __ASM_OFFSETS_H__"; \ echo "/*"; \ echo " * DO NOT MODIFY."; \ echo " *"; \ @@ -212,8 +199,7 @@ define filechk_gen-asm-offsets echo " */"; \ echo ""; \ sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"; \ - echo ""; \ - echo "#endif" ) + echo ""; ) endef $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h @@ -222,50 +208,18 @@ $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h $(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c $(CC) $(USER_CFLAGS) -S -o $@ $< -$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s +$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/user-offsets.s $(call filechk,gen-asm-offsets) -CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h +CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \ - $(ARCH_SYMLINKS) \ - $(SYS_DIR)/sc.h \ - include/asm include/linux/version.h \ - include/config/MARKER \ - $(ARCH_DIR)/include/user_constants.h + archprepare $(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $< -$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s +$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/kernel-offsets.s $(call filechk,gen-asm-offsets) -CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h - -$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task - $(call filechk,gen_header) - -$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants - $(call filechk,gen_header) - -$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants - $(call filechk,gen_header) - -$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs - $(call filechk,gen_header) - -$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ; - -$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \ - FORCE ; - -$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ; - -$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE - $(Q)$(MAKE) $(build)=$@ - -$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE - $(Q)$(MAKE) $(build)=$@ - -$(ARCH_DIR)/os-$(OS)/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE - $(Q)$(MAKE) $(build)=$@ +CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s export SUBARCH USER_CFLAGS OS diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index 1ab431a53ac3..2ee8a2858117 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -32,25 +32,3 @@ CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) ifneq ($(CONFIG_GPROF),y) ARCH_CFLAGS += -DUM_FASTCALL endif - -SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util -SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h - -prepare: $(SYS_HEADERS) - -$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc - $(call filechk,gen_header) - -$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread - $(call filechk,gen_header) - -$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE - $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ - -$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE - $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ - -$(SYS_UTIL_DIR): scripts_basic include/asm FORCE - $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) - -CLEAN_FILES += $(SYS_HEADERS) diff --git a/arch/um/Makefile-skas b/arch/um/Makefile-skas index fd18ec572271..ac35de5316a6 100644 --- a/arch/um/Makefile-skas +++ b/arch/um/Makefile-skas @@ -10,5 +10,3 @@ CFLAGS-$(CONFIG_GCOV) += $(GCOV_OPT) CFLAGS-$(CONFIG_GPROF) += $(GPROF_OPT) LINK-$(CONFIG_GCOV) += $(GCOV_OPT) LINK-$(CONFIG_GPROF) += $(GPROF_OPT) - -GEN_HEADERS += $(ARCH_DIR)/include/skas_ptregs.h diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index 436abbba409b..4f118d5cc2ee 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 @@ -12,24 +12,3 @@ CHECKFLAGS += -m64 ELF_ARCH := i386:x86-64 ELF_FORMAT := elf64-x86-64 - -SYS_UTIL_DIR := $(ARCH_DIR)/sys-x86_64/util -SYS_DIR := $(ARCH_DIR)/include/sysdep-x86_64 - -SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h - -prepare: $(SYS_HEADERS) - -$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc - $(call filechk,gen_header) - -$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread - $(call filechk,gen_header) - -$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE - $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ - -$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE - $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ - -CLEAN_FILES += $(SYS_HEADERS) diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h index 782ac3a3baf9..356390d1f8b9 100644 --- a/arch/um/include/common-offsets.h +++ b/arch/um/include/common-offsets.h @@ -1,7 +1,7 @@ /* for use by sys-$SUBARCH/kernel-offsets.c */ -OFFSET(TASK_REGS, task_struct, thread.regs); -OFFSET(TASK_PID, task_struct, pid); +OFFSET(HOST_TASK_REGS, task_struct, thread.regs); +OFFSET(HOST_TASK_PID, task_struct, pid); DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); diff --git a/arch/um/include/skas_ptregs.h b/arch/um/include/skas_ptregs.h new file mode 100644 index 000000000000..73db19e9c077 --- /dev/null +++ b/arch/um/include/skas_ptregs.h @@ -0,0 +1,6 @@ +#ifndef __SKAS_PT_REGS_ +#define __SKAS_PT_REGS_ + +#include + +#endif diff --git a/arch/um/include/sysdep-i386/sc.h b/arch/um/include/sysdep-i386/sc.h new file mode 100644 index 000000000000..c57d1780ad37 --- /dev/null +++ b/arch/um/include/sysdep-i386/sc.h @@ -0,0 +1,44 @@ +#ifndef __SYSDEP_I386_SC_H +#define __SYSDEP_I386_SC_H + +#include + +#define SC_OFFSET(sc, field) \ + *((unsigned long *) &(((char *) (sc))[HOST_##field])) +#define SC_FP_OFFSET(sc, field) \ + *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) +#define SC_FP_OFFSET_PTR(sc, field, type) \ + ((type *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) + +#define SC_IP(sc) SC_OFFSET(sc, SC_IP) +#define SC_SP(sc) SC_OFFSET(sc, SC_SP) +#define SC_FS(sc) SC_OFFSET(sc, SC_FS) +#define SC_GS(sc) SC_OFFSET(sc, SC_GS) +#define SC_DS(sc) SC_OFFSET(sc, SC_DS) +#define SC_ES(sc) SC_OFFSET(sc, SC_ES) +#define SC_SS(sc) SC_OFFSET(sc, SC_SS) +#define SC_CS(sc) SC_OFFSET(sc, SC_CS) +#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) +#define SC_EAX(sc) SC_OFFSET(sc, SC_EAX) +#define SC_EBX(sc) SC_OFFSET(sc, SC_EBX) +#define SC_ECX(sc) SC_OFFSET(sc, SC_ECX) +#define SC_EDX(sc) SC_OFFSET(sc, SC_EDX) +#define SC_EDI(sc) SC_OFFSET(sc, SC_EDI) +#define SC_ESI(sc) SC_OFFSET(sc, SC_ESI) +#define SC_EBP(sc) SC_OFFSET(sc, SC_EBP) +#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) +#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) +#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) +#define SC_FPSTATE(sc) SC_OFFSET(sc, SC_FPSTATE) +#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) +#define SC_FP_CW(sc) SC_FP_OFFSET(sc, SC_FP_CW) +#define SC_FP_SW(sc) SC_FP_OFFSET(sc, SC_FP_SW) +#define SC_FP_TAG(sc) SC_FP_OFFSET(sc, SC_FP_TAG) +#define SC_FP_IPOFF(sc) SC_FP_OFFSET(sc, SC_FP_IPOFF) +#define SC_FP_CSSEL(sc) SC_FP_OFFSET(sc, SC_FP_CSSEL) +#define SC_FP_DATAOFF(sc) SC_FP_OFFSET(sc, SC_FP_DATAOFF) +#define SC_FP_DATASEL(sc) SC_FP_OFFSET(sc, SC_FP_DATASEL) +#define SC_FP_ST(sc) SC_FP_OFFSET_PTR(sc, SC_FP_ST, struct _fpstate) +#define SC_FXSR_ENV(sc) SC_FP_OFFSET_PTR(sc, SC_FXSR_ENV, void) + +#endif diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h new file mode 100644 index 000000000000..e2bd6bae8b8a --- /dev/null +++ b/arch/um/include/sysdep-i386/thread.h @@ -0,0 +1,11 @@ +#ifndef __UM_THREAD_H +#define __UM_THREAD_H + +#include + +#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS])) +#ifdef CONFIG_MODE_TT +#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID])) +#endif + +#endif diff --git a/arch/um/include/sysdep-x86_64/sc.h b/arch/um/include/sysdep-x86_64/sc.h new file mode 100644 index 000000000000..a160d9fcc596 --- /dev/null +++ b/arch/um/include/sysdep-x86_64/sc.h @@ -0,0 +1,45 @@ +#ifndef __SYSDEP_X86_64_SC_H +#define __SYSDEP_X86_64_SC_H + +/* Copyright (C) 2003 - 2004 PathScale, Inc + * Released under the GPL + */ + +#include + +#define SC_OFFSET(sc, field) \ + *((unsigned long *) &(((char *) (sc))[HOST_##field])) + +#define SC_RBX(sc) SC_OFFSET(sc, SC_RBX) +#define SC_RCX(sc) SC_OFFSET(sc, SC_RCX) +#define SC_RDX(sc) SC_OFFSET(sc, SC_RDX) +#define SC_RSI(sc) SC_OFFSET(sc, SC_RSI) +#define SC_RDI(sc) SC_OFFSET(sc, SC_RDI) +#define SC_RBP(sc) SC_OFFSET(sc, SC_RBP) +#define SC_RAX(sc) SC_OFFSET(sc, SC_RAX) +#define SC_R8(sc) SC_OFFSET(sc, SC_R8) +#define SC_R9(sc) SC_OFFSET(sc, SC_R9) +#define SC_R10(sc) SC_OFFSET(sc, SC_R10) +#define SC_R11(sc) SC_OFFSET(sc, SC_R11) +#define SC_R12(sc) SC_OFFSET(sc, SC_R12) +#define SC_R13(sc) SC_OFFSET(sc, SC_R13) +#define SC_R14(sc) SC_OFFSET(sc, SC_R14) +#define SC_R15(sc) SC_OFFSET(sc, SC_R15) +#define SC_IP(sc) SC_OFFSET(sc, SC_IP) +#define SC_SP(sc) SC_OFFSET(sc, SC_SP) +#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) +#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) +#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) +#define SC_CS(sc) SC_OFFSET(sc, SC_CS) +#define SC_FS(sc) SC_OFFSET(sc, SC_FS) +#define SC_GS(sc) SC_OFFSET(sc, SC_GS) +#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) +#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) +#if 0 +#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX) +#define SC_DS(sc) SC_OFFSET(sc, SC_DS) +#define SC_ES(sc) SC_OFFSET(sc, SC_ES) +#define SC_SS(sc) SC_OFFSET(sc, SC_SS) +#endif + +#endif diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h new file mode 100644 index 000000000000..6a76a7f3683f --- /dev/null +++ b/arch/um/include/sysdep-x86_64/thread.h @@ -0,0 +1,10 @@ +#ifndef __UM_THREAD_H +#define __UM_THREAD_H + +#include + +#ifdef CONFIG_MODE_TT +#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID])) +#endif + +#endif diff --git a/arch/um/include/task.h b/arch/um/include/task.h new file mode 100644 index 000000000000..6375ba7203c9 --- /dev/null +++ b/arch/um/include/task.h @@ -0,0 +1,9 @@ +#ifndef __TASK_H +#define __TASK_H + +#include + +#define TASK_REGS(task) ((union uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) +#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) + +#endif diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index db36c7c95940..8de471b59c1c 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile @@ -6,8 +6,6 @@ obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ syscall.o tlb.o trap_user.o uaccess.o -subdir- := util - USER_OBJS := process.o clone.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile deleted file mode 100644 index f7b7eba83340..000000000000 --- a/arch/um/kernel/skas/util/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -hostprogs-y := mk_ptregs -always := $(hostprogs-y) - -mk_ptregs-objs := mk_ptregs-$(SUBARCH).o -HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c deleted file mode 100644 index 1f96e1eeb8a7..000000000000 --- a/arch/um/kernel/skas/util/mk_ptregs-i386.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#define SHOW(name) printf("#define %s %d\n", #name, name) - -int main(int argc, char **argv) -{ - printf("/* Automatically generated by " - "arch/um/kernel/skas/util/mk_ptregs */\n"); - printf("\n"); - printf("#ifndef __SKAS_PT_REGS_\n"); - printf("#define __SKAS_PT_REGS_\n"); - printf("\n"); - SHOW(HOST_FRAME_SIZE); - SHOW(HOST_FP_SIZE); - SHOW(HOST_XFP_SIZE); - - SHOW(HOST_IP); - SHOW(HOST_SP); - SHOW(HOST_EFLAGS); - SHOW(HOST_EAX); - SHOW(HOST_EBX); - SHOW(HOST_ECX); - SHOW(HOST_EDX); - SHOW(HOST_ESI); - SHOW(HOST_EDI); - SHOW(HOST_EBP); - SHOW(HOST_CS); - SHOW(HOST_SS); - SHOW(HOST_DS); - SHOW(HOST_FS); - SHOW(HOST_ES); - SHOW(HOST_GS); - - printf("\n"); - printf("#endif\n"); - 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/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c deleted file mode 100644 index 5fccbfe35f78..000000000000 --- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include -#include - -#define SHOW(name) \ - printf("#define %s (%d / sizeof(unsigned long))\n", #name, name) - -int main(int argc, char **argv) -{ - printf("/* Automatically generated by " - "arch/um/kernel/skas/util/mk_ptregs */\n"); - printf("\n"); - printf("#ifndef __SKAS_PT_REGS_\n"); - printf("#define __SKAS_PT_REGS_\n"); - SHOW(HOST_FRAME_SIZE); - SHOW(HOST_RBX); - SHOW(HOST_RCX); - SHOW(HOST_RDI); - SHOW(HOST_RSI); - SHOW(HOST_RDX); - SHOW(HOST_RBP); - SHOW(HOST_RAX); - SHOW(HOST_R8); - SHOW(HOST_R9); - SHOW(HOST_R10); - SHOW(HOST_R11); - SHOW(HOST_R12); - SHOW(HOST_R13); - SHOW(HOST_R14); - SHOW(HOST_R15); - SHOW(HOST_ORIG_RAX); - SHOW(HOST_CS); - SHOW(HOST_SS); - SHOW(HOST_EFLAGS); -#if 0 - SHOW(HOST_FS); - SHOW(HOST_GS); - SHOW(HOST_DS); - SHOW(HOST_ES); -#endif - - SHOW(HOST_IP); - SHOW(HOST_SP); - printf("#define HOST_FP_SIZE 0\n"); - printf("#define HOST_XFP_SIZE 0\n"); - printf("\n"); - printf("\n"); - printf("#endif\n"); - 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/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index ab33cb3c74ec..5a99dd3fbed0 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -12,7 +12,7 @@ #include "init.h" #include "elf_user.h" #include "mem_user.h" -#include +#include /* Use the one from the kernel - the host may miss it, if having old headers. */ #if UM_ELF_CLASS == UM_ELFCLASS32 diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile deleted file mode 100644 index 9778aed0c314..000000000000 --- a/arch/um/os-Linux/util/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -hostprogs-y := mk_user_constants -always := $(hostprogs-y) - -HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c deleted file mode 100644 index 4838f30eecf0..000000000000 --- a/arch/um/os-Linux/util/mk_user_constants.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include - -int main(int argc, char **argv) -{ - printf("/*\n"); - printf(" * Generated by mk_user_constants\n"); - printf(" */\n"); - printf("\n"); - printf("#ifndef __UM_USER_CONSTANTS_H\n"); - printf("#define __UM_USER_CONSTANTS_H\n"); - printf("\n"); - /* I'd like to use FRAME_SIZE from ptrace.h here, but that's wrong on - * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on - * both x86_64 and i386. - */ - printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE); - - printf("\n"); - printf("#endif\n"); - - return(0); -} diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 4ca2a229da49..6dfeb70f6957 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -18,6 +18,4 @@ module.c-dir = kernel $(obj)/stub_segv.o : _c_flags = $(call unprofile,$(CFLAGS)) -subdir- := util - include arch/um/scripts/Makefile.unmap diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c index a1070af2bcd8..35db85057506 100644 --- a/arch/um/sys-i386/kernel-offsets.c +++ b/arch/um/sys-i386/kernel-offsets.c @@ -18,9 +18,9 @@ void foo(void) { - OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs); + OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); #ifdef CONFIG_MODE_TT - OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); + OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); #endif #include } diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index 3ceaabceb3d7..677fc26a9bbe 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -7,47 +7,48 @@ #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) +#define DEFINE_LONGS(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) + #define OFFSET(sym, str, mem) \ DEFINE(sym, offsetof(struct str, mem)); void foo(void) { - OFFSET(SC_IP, sigcontext, eip); - OFFSET(SC_SP, sigcontext, esp); - OFFSET(SC_FS, sigcontext, fs); - OFFSET(SC_GS, sigcontext, gs); - OFFSET(SC_DS, sigcontext, ds); - OFFSET(SC_ES, sigcontext, es); - OFFSET(SC_SS, sigcontext, ss); - OFFSET(SC_CS, sigcontext, cs); - OFFSET(SC_EFLAGS, sigcontext, eflags); - OFFSET(SC_EAX, sigcontext, eax); - OFFSET(SC_EBX, sigcontext, ebx); - OFFSET(SC_ECX, sigcontext, ecx); - OFFSET(SC_EDX, sigcontext, edx); - OFFSET(SC_EDI, sigcontext, edi); - OFFSET(SC_ESI, sigcontext, esi); - OFFSET(SC_EBP, sigcontext, ebp); - OFFSET(SC_TRAPNO, sigcontext, trapno); - OFFSET(SC_ERR, sigcontext, err); - OFFSET(SC_CR2, sigcontext, cr2); - OFFSET(SC_FPSTATE, sigcontext, fpstate); - OFFSET(SC_SIGMASK, sigcontext, oldmask); - OFFSET(SC_FP_CW, _fpstate, cw); - OFFSET(SC_FP_SW, _fpstate, sw); - OFFSET(SC_FP_TAG, _fpstate, tag); - OFFSET(SC_FP_IPOFF, _fpstate, ipoff); - OFFSET(SC_FP_CSSEL, _fpstate, cssel); - OFFSET(SC_FP_DATAOFF, _fpstate, dataoff); - OFFSET(SC_FP_DATASEL, _fpstate, datasel); - OFFSET(SC_FP_ST, _fpstate, _st); - OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env); + OFFSET(HOST_SC_IP, sigcontext, eip); + OFFSET(HOST_SC_SP, sigcontext, esp); + OFFSET(HOST_SC_FS, sigcontext, fs); + OFFSET(HOST_SC_GS, sigcontext, gs); + OFFSET(HOST_SC_DS, sigcontext, ds); + OFFSET(HOST_SC_ES, sigcontext, es); + OFFSET(HOST_SC_SS, sigcontext, ss); + OFFSET(HOST_SC_CS, sigcontext, cs); + OFFSET(HOST_SC_EFLAGS, sigcontext, eflags); + OFFSET(HOST_SC_EAX, sigcontext, eax); + OFFSET(HOST_SC_EBX, sigcontext, ebx); + OFFSET(HOST_SC_ECX, sigcontext, ecx); + OFFSET(HOST_SC_EDX, sigcontext, edx); + OFFSET(HOST_SC_EDI, sigcontext, edi); + OFFSET(HOST_SC_ESI, sigcontext, esi); + OFFSET(HOST_SC_EBP, sigcontext, ebp); + OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); + OFFSET(HOST_SC_ERR, sigcontext, err); + OFFSET(HOST_SC_CR2, sigcontext, cr2); + OFFSET(HOST_SC_FPSTATE, sigcontext, fpstate); + OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask); + OFFSET(HOST_SC_FP_CW, _fpstate, cw); + OFFSET(HOST_SC_FP_SW, _fpstate, sw); + OFFSET(HOST_SC_FP_TAG, _fpstate, tag); + OFFSET(HOST_SC_FP_IPOFF, _fpstate, ipoff); + OFFSET(HOST_SC_FP_CSSEL, _fpstate, cssel); + OFFSET(HOST_SC_FP_DATAOFF, _fpstate, dataoff); + OFFSET(HOST_SC_FP_DATASEL, _fpstate, datasel); + OFFSET(HOST_SC_FP_ST, _fpstate, _st); + OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env); - DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); - DEFINE(HOST_FP_SIZE, - sizeof(struct user_i387_struct) / sizeof(unsigned long)); - DEFINE(HOST_XFP_SIZE, - sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); + DEFINE_LONGS(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)); DEFINE(HOST_IP, EIP); DEFINE(HOST_SP, UESP); @@ -65,5 +66,5 @@ void foo(void) DEFINE(HOST_FS, FS); DEFINE(HOST_ES, ES); DEFINE(HOST_GS, GS); - DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct)); + DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); } diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile deleted file mode 100644 index bf61afd0b045..000000000000 --- a/arch/um/sys-i386/util/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -hostprogs-y := mk_sc mk_thread -always := $(hostprogs-y) - -HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um -HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c deleted file mode 100644 index 04c0d73433aa..000000000000 --- a/arch/um/sys-i386/util/mk_sc.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -#define SC_OFFSET(name, field) \ - printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ - name) - -#define SC_FP_OFFSET(name, field) \ - printf("#define " #name \ - "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ - name) - -#define SC_FP_OFFSET_PTR(name, field, type) \ - printf("#define " #name \ - "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ - name) - -int main(int argc, char **argv) -{ - SC_OFFSET(SC_IP, eip); - SC_OFFSET(SC_SP, esp); - SC_OFFSET(SC_FS, fs); - SC_OFFSET(SC_GS, gs); - SC_OFFSET(SC_DS, ds); - SC_OFFSET(SC_ES, es); - SC_OFFSET(SC_SS, ss); - SC_OFFSET(SC_CS, cs); - SC_OFFSET(SC_EFLAGS, eflags); - SC_OFFSET(SC_EAX, eax); - SC_OFFSET(SC_EBX, ebx); - SC_OFFSET(SC_ECX, ecx); - SC_OFFSET(SC_EDX, edx); - SC_OFFSET(SC_EDI, edi); - SC_OFFSET(SC_ESI, esi); - SC_OFFSET(SC_EBP, ebp); - SC_OFFSET(SC_TRAPNO, trapno); - SC_OFFSET(SC_ERR, err); - SC_OFFSET(SC_CR2, cr2); - SC_OFFSET(SC_FPSTATE, fpstate); - SC_OFFSET(SC_SIGMASK, oldmask); - SC_FP_OFFSET(SC_FP_CW, cw); - SC_FP_OFFSET(SC_FP_SW, sw); - SC_FP_OFFSET(SC_FP_TAG, tag); - SC_FP_OFFSET(SC_FP_IPOFF, ipoff); - SC_FP_OFFSET(SC_FP_CSSEL, cssel); - SC_FP_OFFSET(SC_FP_DATAOFF, dataoff); - SC_FP_OFFSET(SC_FP_DATASEL, datasel); - SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate"); - SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void"); - return(0); -} diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c deleted file mode 100644 index 7470d0dda67e..000000000000 --- a/arch/um/sys-i386/util/mk_thread.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -int main(int argc, char **argv) -{ - printf("/*\n"); - printf(" * Generated by mk_thread\n"); - printf(" */\n"); - printf("\n"); - printf("#ifndef __UM_THREAD_H\n"); - printf("#define __UM_THREAD_H\n"); - printf("\n"); - printf("#define TASK_DEBUGREGS(task) ((unsigned long *) " - "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS); -#ifdef TASK_EXTERN_PID - printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n", - TASK_EXTERN_PID); -#endif - printf("\n"); - printf("#endif\n"); - return(0); -} diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index f0ab574d1e95..06c3633457a2 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -29,6 +29,4 @@ module.c-dir = kernel $(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS)) -subdir- := util - include arch/um/scripts/Makefile.unmap diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c index 998541eade41..bfcb104b846e 100644 --- a/arch/um/sys-x86_64/kernel-offsets.c +++ b/arch/um/sys-x86_64/kernel-offsets.c @@ -19,7 +19,7 @@ void foo(void) { #ifdef CONFIG_MODE_TT - OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); + OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); #endif #include } diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 513d17ceafd4..5a585bfbb8c2 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -16,71 +16,76 @@ typedef __u32 u32; #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) +#define DEFINE_LONGS(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) + #define OFFSET(sym, str, mem) \ DEFINE(sym, offsetof(struct str, mem)); void foo(void) { - OFFSET(SC_RBX, sigcontext, rbx); - OFFSET(SC_RCX, sigcontext, rcx); - OFFSET(SC_RDX, sigcontext, rdx); - OFFSET(SC_RSI, sigcontext, rsi); - OFFSET(SC_RDI, sigcontext, rdi); - OFFSET(SC_RBP, sigcontext, rbp); - OFFSET(SC_RAX, sigcontext, rax); - OFFSET(SC_R8, sigcontext, r8); - OFFSET(SC_R9, sigcontext, r9); - OFFSET(SC_R10, sigcontext, r10); - OFFSET(SC_R11, sigcontext, r11); - OFFSET(SC_R12, sigcontext, r12); - OFFSET(SC_R13, sigcontext, r13); - OFFSET(SC_R14, sigcontext, r14); - OFFSET(SC_R15, sigcontext, r15); - OFFSET(SC_IP, sigcontext, rip); - OFFSET(SC_SP, sigcontext, rsp); - OFFSET(SC_CR2, sigcontext, cr2); - OFFSET(SC_ERR, sigcontext, err); - OFFSET(SC_TRAPNO, sigcontext, trapno); - OFFSET(SC_CS, sigcontext, cs); - OFFSET(SC_FS, sigcontext, fs); - OFFSET(SC_GS, sigcontext, gs); - OFFSET(SC_EFLAGS, sigcontext, eflags); - OFFSET(SC_SIGMASK, sigcontext, oldmask); + OFFSET(HOST_SC_RBX, sigcontext, rbx); + OFFSET(HOST_SC_RCX, sigcontext, rcx); + OFFSET(HOST_SC_RDX, sigcontext, rdx); + OFFSET(HOST_SC_RSI, sigcontext, rsi); + OFFSET(HOST_SC_RDI, sigcontext, rdi); + OFFSET(HOST_SC_RBP, sigcontext, rbp); + OFFSET(HOST_SC_RAX, sigcontext, rax); + OFFSET(HOST_SC_R8, sigcontext, r8); + OFFSET(HOST_SC_R9, sigcontext, r9); + OFFSET(HOST_SC_R10, sigcontext, r10); + OFFSET(HOST_SC_R11, sigcontext, r11); + OFFSET(HOST_SC_R12, sigcontext, r12); + OFFSET(HOST_SC_R13, sigcontext, r13); + OFFSET(HOST_SC_R14, sigcontext, r14); + OFFSET(HOST_SC_R15, sigcontext, r15); + OFFSET(HOST_SC_IP, sigcontext, rip); + OFFSET(HOST_SC_SP, sigcontext, rsp); + OFFSET(HOST_SC_CR2, sigcontext, cr2); + OFFSET(HOST_SC_ERR, sigcontext, err); + OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); + OFFSET(HOST_SC_CS, sigcontext, cs); + OFFSET(HOST_SC_FS, sigcontext, fs); + OFFSET(HOST_SC_GS, sigcontext, gs); + OFFSET(HOST_SC_EFLAGS, sigcontext, eflags); + OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask); #if 0 - OFFSET(SC_ORIG_RAX, sigcontext, orig_rax); - OFFSET(SC_DS, sigcontext, ds); - OFFSET(SC_ES, sigcontext, es); - OFFSET(SC_SS, sigcontext, ss); + OFFSET(HOST_SC_ORIG_RAX, sigcontext, orig_rax); + OFFSET(HOST_SC_DS, sigcontext, ds); + OFFSET(HOST_SC_ES, sigcontext, es); + OFFSET(HOST_SC_SS, sigcontext, ss); #endif - DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); - DEFINE(HOST_RBX, RBX); - DEFINE(HOST_RCX, RCX); - DEFINE(HOST_RDI, RDI); - DEFINE(HOST_RSI, RSI); - DEFINE(HOST_RDX, RDX); - DEFINE(HOST_RBP, RBP); - DEFINE(HOST_RAX, RAX); - DEFINE(HOST_R8, R8); - DEFINE(HOST_R9, R9); - DEFINE(HOST_R10, R10); - DEFINE(HOST_R11, R11); - DEFINE(HOST_R12, R12); - DEFINE(HOST_R13, R13); - DEFINE(HOST_R14, R14); - DEFINE(HOST_R15, R15); - DEFINE(HOST_ORIG_RAX, ORIG_RAX); - DEFINE(HOST_CS, CS); - DEFINE(HOST_SS, SS); - DEFINE(HOST_EFLAGS, EFLAGS); + DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); + DEFINE(HOST_FP_SIZE, 0); + DEFINE(HOST_XFP_SIZE, 0); + DEFINE_LONGS(HOST_RBX, RBX); + DEFINE_LONGS(HOST_RCX, RCX); + DEFINE_LONGS(HOST_RDI, RDI); + DEFINE_LONGS(HOST_RSI, RSI); + DEFINE_LONGS(HOST_RDX, RDX); + DEFINE_LONGS(HOST_RBP, RBP); + DEFINE_LONGS(HOST_RAX, RAX); + DEFINE_LONGS(HOST_R8, R8); + DEFINE_LONGS(HOST_R9, R9); + DEFINE_LONGS(HOST_R10, R10); + DEFINE_LONGS(HOST_R11, R11); + DEFINE_LONGS(HOST_R12, R12); + DEFINE_LONGS(HOST_R13, R13); + DEFINE_LONGS(HOST_R14, R14); + DEFINE_LONGS(HOST_R15, R15); + DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX); + DEFINE_LONGS(HOST_CS, CS); + DEFINE_LONGS(HOST_SS, SS); + DEFINE_LONGS(HOST_EFLAGS, EFLAGS); #if 0 - DEFINE(HOST_FS, FS); - DEFINE(HOST_GS, GS); - DEFINE(HOST_DS, DS); - DEFINE(HOST_ES, ES); + DEFINE_LONGS(HOST_FS, FS); + DEFINE_LONGS(HOST_GS, GS); + DEFINE_LONGS(HOST_DS, DS); + DEFINE_LONGS(HOST_ES, ES); #endif - DEFINE(HOST_IP, RIP); - DEFINE(HOST_SP, RSP); - DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct)); + DEFINE_LONGS(HOST_IP, RIP); + DEFINE_LONGS(HOST_SP, RSP); + DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); } diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile deleted file mode 100644 index 75b052cfc206..000000000000 --- a/arch/um/sys-x86_64/util/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2003 - 2004 Pathscale, Inc -# Released under the GPL - -hostprogs-y := mk_sc mk_thread -always := $(hostprogs-y) - -HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um -HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c deleted file mode 100644 index 7619bc377c1f..000000000000 --- a/arch/um/sys-x86_64/util/mk_sc.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2003 - 2004 PathScale, Inc - * Released under the GPL - */ - -#include -#include - -#define SC_OFFSET(name) \ - printf("#define " #name \ - "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ - name) - -int main(int argc, char **argv) -{ - SC_OFFSET(SC_RBX); - SC_OFFSET(SC_RCX); - SC_OFFSET(SC_RDX); - SC_OFFSET(SC_RSI); - SC_OFFSET(SC_RDI); - SC_OFFSET(SC_RBP); - SC_OFFSET(SC_RAX); - SC_OFFSET(SC_R8); - SC_OFFSET(SC_R9); - SC_OFFSET(SC_R10); - SC_OFFSET(SC_R11); - SC_OFFSET(SC_R12); - SC_OFFSET(SC_R13); - SC_OFFSET(SC_R14); - SC_OFFSET(SC_R15); - SC_OFFSET(SC_IP); - SC_OFFSET(SC_SP); - SC_OFFSET(SC_CR2); - SC_OFFSET(SC_ERR); - SC_OFFSET(SC_TRAPNO); - SC_OFFSET(SC_CS); - SC_OFFSET(SC_FS); - SC_OFFSET(SC_GS); - SC_OFFSET(SC_EFLAGS); - SC_OFFSET(SC_SIGMASK); -#if 0 - SC_OFFSET(SC_ORIG_RAX); - SC_OFFSET(SC_DS); - SC_OFFSET(SC_ES); - SC_OFFSET(SC_SS); -#endif - return(0); -} diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c deleted file mode 100644 index 15517396e9cf..000000000000 --- a/arch/um/sys-x86_64/util/mk_thread.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -int main(int argc, char **argv) -{ - printf("/*\n"); - printf(" * Generated by mk_thread\n"); - printf(" */\n"); - printf("\n"); - printf("#ifndef __UM_THREAD_H\n"); - printf("#define __UM_THREAD_H\n"); - printf("\n"); -#ifdef TASK_EXTERN_PID - printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n", - TASK_EXTERN_PID); -#endif - printf("\n"); - printf("#endif\n"); - return(0); -} diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile deleted file mode 100644 index 4c7551c28033..000000000000 --- a/arch/um/util/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -hostprogs-y := mk_task mk_constants -always := $(hostprogs-y) - -HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um -HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c deleted file mode 100644 index ab217becc36a..000000000000 --- a/arch/um/util/mk_constants.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym) -#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym) - -int main(int argc, char **argv) -{ - printf("/*\n"); - printf(" * Generated by mk_constants\n"); - printf(" */\n"); - printf("\n"); - printf("#ifndef __UM_CONSTANTS_H\n"); - printf("#define __UM_CONSTANTS_H\n"); - printf("\n"); - - SHOW_INT(UM_KERN_PAGE_SIZE); - - SHOW_STR(UM_KERN_EMERG); - SHOW_STR(UM_KERN_ALERT); - SHOW_STR(UM_KERN_CRIT); - SHOW_STR(UM_KERN_ERR); - SHOW_STR(UM_KERN_WARNING); - SHOW_STR(UM_KERN_NOTICE); - SHOW_STR(UM_KERN_INFO); - SHOW_STR(UM_KERN_DEBUG); - - SHOW_INT(UM_NSEC_PER_SEC); - printf("\n"); - printf("#endif\n"); - return(0); -} diff --git a/arch/um/util/mk_task.c b/arch/um/util/mk_task.c deleted file mode 100644 index 36c9606505e2..000000000000 --- a/arch/um/util/mk_task.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -void print_ptr(char *name, char *type, int offset) -{ - printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, - offset); -} - -void print(char *name, char *type, int offset) -{ - printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, - offset); -} - -int main(int argc, char **argv) -{ - printf("/*\n"); - printf(" * Generated by mk_task\n"); - printf(" */\n"); - printf("\n"); - printf("#ifndef __TASK_H\n"); - printf("#define __TASK_H\n"); - printf("\n"); - print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS); - print("TASK_PID", "int", TASK_PID); - printf("\n"); - printf("#endif\n"); - return(0); -} -- cgit v1.2.2 From 74ba1fd96666170338dc732480b35b7a83cd164b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 30 Sep 2005 03:16:43 +0100 Subject: [PATCH] useless linux/irq.h includes (arch/um) Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/um/drivers/port_kern.c | 1 - arch/um/kernel/irq.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index c41efd207fcc..189839e4f1d4 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -7,7 +7,6 @@ #include "linux/sched.h" #include "linux/slab.h" #include "linux/interrupt.h" -#include "linux/irq.h" #include "linux/spinlock.h" #include "linux/errno.h" #include "asm/atomic.h" diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index dcd814971995..bbf94bf2921e 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -9,7 +9,6 @@ #include "linux/kernel.h" #include "linux/module.h" #include "linux/smp.h" -#include "linux/irq.h" #include "linux/kernel_stat.h" #include "linux/interrupt.h" #include "linux/random.h" -- cgit v1.2.2 From be662a18b7763496a052d489206af9ca2c2e1ac2 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Fri, 30 Sep 2005 11:58:59 -0700 Subject: [PATCH] uml: fix page faults in SKAS3 mode. I hadn't been running a SKAS3 host when testing the "uml: fix hang in TT mode on fault" patch (commit 546fe1cbf91d4d62e3849517c31a2327c992e5c5), and I didn't think enough to the missing trap_no in SKAS3 mode. In fact, the resulting kernel doesn't work at all in SKAS3 mode. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/sysdep-i386/sigcontext.h | 10 +++++++++- arch/um/include/sysdep-x86_64/sigcontext.h | 5 ++++- arch/um/kernel/trap_kern.c | 5 ++++- 3 files changed, 17 insertions(+), 3 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index 1fe729265167..23fd2644d7ed 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h @@ -6,6 +6,7 @@ #ifndef __SYS_SIGCONTEXT_I386_H #define __SYS_SIGCONTEXT_I386_H +#include "uml-config.h" #include #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) @@ -26,7 +27,14 @@ #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) /* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ +#ifdef UML_CONFIG_MODE_SKAS +#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) +#else +#define SEGV_MAYBE_FIXABLE(fi) 0 +#endif extern unsigned long *sc_sigmask(void *sc_ptr); extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h index 2a78260d15a0..41073235e7ad 100644 --- a/arch/um/include/sysdep-x86_64/sigcontext.h +++ b/arch/um/include/sysdep-x86_64/sigcontext.h @@ -31,7 +31,10 @@ #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) /* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* No broken SKAS API, which doesn't pass trap_no, here. */ +#define SEGV_MAYBE_FIXABLE(fi) 0 extern unsigned long *sc_sigmask(void *sc_ptr); diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index d297429ac360..95c8f8733baf 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c @@ -26,6 +26,9 @@ #include "mconsole_kern.h" #include "mem.h" #include "mem_kern.h" +#ifdef CONFIG_MODE_SKAS +#include "skas.h" +#endif /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ int handle_page_fault(unsigned long address, unsigned long ip, @@ -134,7 +137,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) else if(current->mm == NULL) panic("Segfault with no mm"); - if (SEGV_IS_FIXABLE(&fi)) + if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); else { err = -EFAULT; -- cgit v1.2.2 From 8923648c125421b0fcb240cde607e2748d099ab8 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Fri, 30 Sep 2005 11:59:00 -0700 Subject: [PATCH] uml: clear SKAS0/3 flags when running in TT mode SEGV_MAYBE_FIXABLE tests ptrace_faultinfo, and depends on it being 1 only in SKAS3 mode, while currently when running with mode=tt it will be 1 anyway. Fix this, and do the same for proc_mm. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 4 ++++ arch/um/kernel/um_arch.c | 2 ++ 2 files changed, 6 insertions(+) (limited to 'arch/um') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 583329d0a539..6f766e1faecc 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -157,6 +157,10 @@ extern int os_lock_file(int fd, int excl); extern void os_early_checks(void); extern int can_do_skas(void); +/* Make sure they are clear when running in TT mode. Required by + * SEGV_MAYBE_FIXABLE */ +#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0) + /* mem.c */ extern int create_mem_file(unsigned long len); diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index f0a275947d34..93dc782dc1cc 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -334,6 +334,8 @@ int linux_main(int argc, char **argv) add_arg(DEFAULT_COMMAND_LINE); os_early_checks(); + if (force_tt) + clear_can_do_skas(); mode_tt = force_tt ? 1 : !can_do_skas(); #ifndef CONFIG_MODE_TT if (mode_tt) { -- cgit v1.2.2 From bd948057357db5febfe64cf7a9ef11d7e347ffec Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Fri, 30 Sep 2005 11:59:00 -0700 Subject: [PATCH] uml: revert "run mconsole "sysrq" in process context" Revert commit 12ebcd73e40e09f0dfddf89e465cc0541e0ff8b1, i.e. [PATCH] uml: run mconsole "sysrq" in process context on request from Jeff Dike. a) sysrq may be run when the scheduler is non-functioning b) the warning I wanted to fix actually came from the fault handler run in atomic context. But I fixed that not to take the semaphore in a separate patch. c) the fault handler is run because of a fault, and that fault was unaffected by this patch. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/mconsole_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index 04383f98f4d5..310c1f823f26 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -23,7 +23,7 @@ static struct mconsole_command commands[] = { { "reboot", mconsole_reboot, MCONSOLE_PROC }, { "config", mconsole_config, MCONSOLE_PROC }, { "remove", mconsole_remove, MCONSOLE_PROC }, - { "sysrq", mconsole_sysrq, MCONSOLE_PROC }, + { "sysrq", mconsole_sysrq, MCONSOLE_INTR }, { "help", mconsole_help, MCONSOLE_INTR }, { "cad", mconsole_cad, MCONSOLE_INTR }, { "stop", mconsole_stop, MCONSOLE_PROC }, -- cgit v1.2.2