diff options
author | Chris Larson <clarson@kergoth.com> | 2004-12-09 09:47:41 +0000 |
---|---|---|
committer | Chris Larson <clarson@kergoth.com> | 2004-12-09 09:47:41 +0000 |
commit | 2c5b8ec6d95cf68650265941530e5ce38c8dd6d9 (patch) | |
tree | bf879bea7ef8517ba8c3d1286ef300401d3d484c /linux-uml/linux-uml-2.6.7 | |
parent | 101e2f1623def0a355d20aacb8bd93810703e834 (diff) |
Merge oe-devel@oe-devel.bkbits.net:openembedded
into hyperion.kergoth.com:/home/kergoth/code/openembedded
2004/12/09 03:39:39-06:00 kergoth.com!kergoth
Break people's builds again.. this time moving the packages into a packages/ subdir to clean things up a bit.
BKrev: 41b81f3dvlp3rU7_8MUXLcI8LDdDoA
Diffstat (limited to 'linux-uml/linux-uml-2.6.7')
22 files changed, 0 insertions, 22855 deletions
diff --git a/linux-uml/linux-uml-2.6.7/Add_os_make_pty_raw.patch b/linux-uml/linux-uml-2.6.7/Add_os_make_pty_raw.patch deleted file mode 100644 index 0cb2518722..0000000000 --- a/linux-uml/linux-uml-2.6.7/Add_os_make_pty_raw.patch +++ /dev/null @@ -1,114 +0,0 @@ - -Fixes raw() and uses it in check_one_sigio; also fixes a silly panic (EINTR returned by call). - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/include/user_util.h | 4 ++- - uml-linux-2.6.7-paolo/arch/um/kernel/sigio_user.c | 11 +++----- - uml-linux-2.6.7-paolo/arch/um/kernel/user_util.c | 29 ++++++++++++++++++---- - 3 files changed, 31 insertions(+), 13 deletions(-) - -diff -puN arch/um/kernel/sigio_user.c~Add_os_make_pty_raw arch/um/kernel/sigio_user.c ---- uml-linux-2.6.7/arch/um/kernel/sigio_user.c~Add_os_make_pty_raw 2004-06-29 21:03:03.157157408 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/sigio_user.c 2004-06-29 21:03:03.161156800 +0200 -@@ -16,6 +16,7 @@ - #include "init.h" - #include "user.h" - #include "kern_util.h" -+#include "user_util.h" - #include "sigio.h" - #include "helper.h" - #include "os.h" -@@ -50,7 +51,6 @@ static void openpty_cb(void *arg) - void __init check_one_sigio(void (*proc)(int, int)) - { - struct sigaction old, new; -- struct termios tt; - struct openpty_arg pty = { .master = -1, .slave = -1 }; - int master, slave, err; - -@@ -68,12 +68,9 @@ void __init check_one_sigio(void (*proc) - return; - } - -- /* XXX These can fail with EINTR */ -- if(tcgetattr(master, &tt) < 0) -- panic("check_sigio : tcgetattr failed, errno = %d\n", errno); -- cfmakeraw(&tt); -- if(tcsetattr(master, TCSADRAIN, &tt) < 0) -- panic("check_sigio : tcsetattr failed, errno = %d\n", errno); -+ err = __raw(master, 1, 0); //Not now, but complain so we now where we failed. -+ if (err < 0) -+ panic("check_sigio : __raw failed, errno = %d\n", -err); - - err = os_sigio_async(master, slave); - if(err < 0) -diff -puN arch/um/kernel/user_util.c~Add_os_make_pty_raw arch/um/kernel/user_util.c ---- uml-linux-2.6.7/arch/um/kernel/user_util.c~Add_os_make_pty_raw 2004-06-29 21:03:03.158157256 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/user_util.c 2004-06-29 21:03:03.162156648 +0200 -@@ -119,18 +119,37 @@ int wait_for_stop(int pid, int sig, int - } - } - --int raw(int fd, int complain) -+int __raw(int fd, int complain, int now) - { - struct termios tt; - int err; -+ int when; -+ -+ while (((err = tcgetattr(fd, &tt)) < 0) && errno == EINTR) -+ ; -+ -+ if (err < 0) { -+ if (complain) -+ printk("tcgetattr failed, errno = %d\n", errno); -+ return(-errno); -+ } - -- tcgetattr(fd, &tt); - cfmakeraw(&tt); -- err = tcsetattr(fd, TCSANOW, &tt); -- if((err < 0) && complain){ -- printk("tcsetattr failed, errno = %d\n", errno); -+ -+ if (now) -+ when = TCSANOW; -+ else -+ when = TCSADRAIN; -+ -+ while (((err = tcsetattr(fd, when, &tt)) < 0) && errno == EINTR) -+ ; -+ if (err < 0) { -+ if (complain) -+ printk("tcsetattr failed, errno = %d\n", errno); - return(-errno); - } -+ /*XXX: tcsetattr could have applied only some changes -+ * (and cfmakeraw() is a set of changes) */ - return(0); - } - -diff -puN arch/um/include/user_util.h~Add_os_make_pty_raw arch/um/include/user_util.h ---- uml-linux-2.6.7/arch/um/include/user_util.h~Add_os_make_pty_raw 2004-06-29 21:03:03.159157104 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/user_util.h 2004-06-29 21:03:03.162156648 +0200 -@@ -62,7 +62,6 @@ extern void set_cmdline(char *cmd); - extern void input_cb(void (*proc)(void *), void *arg, int arg_len); - extern int get_pty(void); - extern void *um_kmalloc(int size); --extern int raw(int fd, int complain); - extern int switcheroo(int fd, int prot, void *from, void *to, int size); - extern void setup_machinename(char *machine_out); - extern void setup_hostinfo(void); -@@ -90,6 +89,9 @@ extern void forward_pending_sigio(int ta - extern int can_do_skas(void); - extern void arch_init_thread(void); - -+extern int __raw(int fd, int complain, int now); -+#define raw(fd, complain) __raw((fd), (complain), 1) -+ - #endif - - /* -_ diff --git a/linux-uml/linux-uml-2.6.7/EINTR_safety.patch b/linux-uml/linux-uml-2.6.7/EINTR_safety.patch deleted file mode 100644 index 8dd49b8690..0000000000 --- a/linux-uml/linux-uml-2.6.7/EINTR_safety.patch +++ /dev/null @@ -1,456 +0,0 @@ - - -On various places (mostly waitpid() calls) this patch makes sure -that if errno == EINTR on return, then the syscall is endlessly retried. -It also defines a simple generic way to do this. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/drivers/net_user.c | 3 +- - uml-linux-2.6.7-paolo/arch/um/drivers/slip_user.c | 6 +++-- - uml-linux-2.6.7-paolo/arch/um/drivers/slirp_user.c | 8 +++---- - uml-linux-2.6.7-paolo/arch/um/include/user_util.h | 1 - uml-linux-2.6.7-paolo/arch/um/kernel/frame.c | 8 ++++--- - uml-linux-2.6.7-paolo/arch/um/kernel/helper.c | 3 +- - uml-linux-2.6.7-paolo/arch/um/kernel/process.c | 11 +++++----- - uml-linux-2.6.7-paolo/arch/um/kernel/skas/exec_user.c | 6 +++-- - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c | 6 ++--- - uml-linux-2.6.7-paolo/arch/um/kernel/trap_user.c | 9 +++++++- - uml-linux-2.6.7-paolo/arch/um/kernel/tt/exec_user.c | 9 ++++++-- - uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/proxy.c | 4 +-- - uml-linux-2.6.7-paolo/arch/um/kernel/tt/tracer.c | 4 +-- - uml-linux-2.6.7-paolo/arch/um/kernel/user_util.c | 10 +++------ - uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/ethertap_user.c | 4 ++- - uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/tuntap_user.c | 3 +- - uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c | 3 +- - 17 files changed, 61 insertions(+), 37 deletions(-) - -diff -puN arch/um/kernel/skas/process.c~EINTR_safety arch/um/kernel/skas/process.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process.c~EINTR_safety 2004-06-29 21:03:04.749915272 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c 2004-06-29 21:03:04.785909800 +0200 -@@ -81,7 +81,7 @@ static void handle_trap(int pid, union u - panic("handle_trap - continuing to end of syscall failed, " - "errno = %d\n", errno); - -- err = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); - if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) - panic("handle_trap - failed to wait at end of syscall, " - "errno = %d, status = %d\n", errno, status); -@@ -121,7 +121,7 @@ void start_userspace(int cpu) - panic("start_userspace : clone failed, errno = %d", errno); - - do { -- n = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) - panic("start_userspace : wait failed, errno = %d", - errno); -@@ -154,7 +154,7 @@ void userspace(union uml_pt_regs *regs) - panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", - errno); - while(1){ -- err = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); - if(err < 0) - panic("userspace - waitpid failed, errno = %d\n", - errno); -diff -puN arch/um/include/user_util.h~EINTR_safety arch/um/include/user_util.h ---- uml-linux-2.6.7/arch/um/include/user_util.h~EINTR_safety 2004-06-29 21:03:04.750915120 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/user_util.h 2004-06-29 21:03:04.786909648 +0200 -@@ -92,6 +92,7 @@ extern void arch_init_thread(void); - extern int __raw(int fd, int complain, int now); - #define raw(fd, complain) __raw((fd), (complain), 1) - -+#define CATCH_EINTR(expr) while ( ((expr) < 0) && errno == EINTR) - #endif - - /* -diff -puN arch/um/kernel/user_util.c~EINTR_safety arch/um/kernel/user_util.c ---- uml-linux-2.6.7/arch/um/kernel/user_util.c~EINTR_safety 2004-06-29 21:03:04.751914968 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/user_util.c 2004-06-29 21:03:04.786909648 +0200 -@@ -81,11 +81,10 @@ int wait_for_stop(int pid, int sig, int - int status, ret; - - while(1){ -- ret = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED)); - if((ret < 0) || - !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){ - if(ret < 0){ -- if(errno == EINTR) continue; - printk("wait failed, errno = %d\n", - errno); - } -@@ -125,8 +124,7 @@ int __raw(int fd, int complain, int now) - int err; - int when; - -- while (((err = tcgetattr(fd, &tt)) < 0) && errno == EINTR) -- ; -+ CATCH_EINTR(err = tcgetattr(fd, &tt)); - - if (err < 0) { - if (complain) -@@ -141,8 +139,8 @@ int __raw(int fd, int complain, int now) - else - when = TCSADRAIN; - -- while (((err = tcsetattr(fd, when, &tt)) < 0) && errno == EINTR) -- ; -+ CATCH_EINTR(err = tcsetattr(fd, when, &tt)); -+ - if (err < 0) { - if (complain) - printk("tcsetattr failed, errno = %d\n", errno); -diff -puN arch/um/kernel/process.c~EINTR_safety arch/um/kernel/process.c ---- uml-linux-2.6.7/arch/um/kernel/process.c~EINTR_safety 2004-06-29 21:03:04.752914816 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/process.c 2004-06-29 21:03:04.786909648 +0200 -@@ -125,7 +125,7 @@ int start_fork_tramp(void *thread_arg, u - /* Start the process and wait for it to kill itself */ - new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg); - if(new_pid < 0) return(-errno); -- while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ; -+ CATCH_EINTR(err = waitpid(new_pid, &status, 0)); - if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", - errno); - if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL)) -@@ -171,7 +171,7 @@ static int start_ptraced_child(void **st - pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); - if(pid < 0) - panic("check_ptrace : clone failed, errno = %d", errno); -- n = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) - panic("check_ptrace : wait failed, errno = %d", errno); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) -@@ -188,7 +188,7 @@ static void stop_ptraced_child(int pid, - - if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) - panic("check_ptrace : ptrace failed, errno = %d", errno); -- n = waitpid(pid, &status, 0); -+ CATCH_EINTR(n = waitpid(pid, &status, 0)); - if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) - panic("check_ptrace : child exited with status 0x%x", status); - -@@ -224,7 +224,7 @@ void __init check_ptrace(void) - if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) - panic("check_ptrace : ptrace failed, errno = %d", - errno); -- n = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) - panic("check_ptrace : wait failed, errno = %d", errno); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) -@@ -251,7 +251,8 @@ void __init check_ptrace(void) - if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { - struct user_regs_struct regs; - -- if (waitpid(pid, &status, WUNTRACED) < 0) -+ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); -+ if (n < 0) - panic("check_ptrace : wait failed, errno = %d", errno); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) - panic("check_ptrace : expected SIGTRAP, " -diff -puN arch/um/kernel/frame.c~EINTR_safety arch/um/kernel/frame.c ---- uml-linux-2.6.7/arch/um/kernel/frame.c~EINTR_safety 2004-06-29 21:03:04.754914512 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/frame.c 2004-06-29 21:03:04.787909496 +0200 -@@ -21,6 +21,7 @@ - #include "sysdep/sigcontext.h" - #include "frame_user.h" - #include "kern_util.h" -+#include "user_util.h" - #include "ptrace_user.h" - #include "os.h" - -@@ -40,7 +41,7 @@ static int capture_stack(int (*child)(vo - /* Wait for it to stop itself and continue it with a SIGUSR1 to force - * it into the signal handler. - */ -- n = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0){ - printf("capture_stack : waitpid failed - errno = %d\n", errno); - exit(1); -@@ -60,7 +61,7 @@ static int capture_stack(int (*child)(vo - * At this point, the handler has stuffed the addresses of - * sig, sc, and SA_RESTORER in raw. - */ -- n = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0){ - printf("capture_stack : waitpid failed - errno = %d\n", errno); - exit(1); -@@ -82,7 +83,8 @@ static int capture_stack(int (*child)(vo - errno); - exit(1); - } -- if(waitpid(pid, &status, 0) < 0){ -+ CATCH_EINTR(n = waitpid(pid, &status, 0)); -+ if(n < 0){ - printf("capture_stack : waitpid failed - errno = %d\n", errno); - exit(1); - } -diff -puN arch/um/drivers/net_user.c~EINTR_safety arch/um/drivers/net_user.c ---- uml-linux-2.6.7/arch/um/drivers/net_user.c~EINTR_safety 2004-06-29 21:03:04.755914360 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/net_user.c 2004-06-29 21:03:04.787909496 +0200 -@@ -175,7 +175,8 @@ static int change_tramp(char **argv, cha - - os_close_file(fds[1]); - read_output(fds[0], output, output_len); -- waitpid(pid, NULL, 0); -+ -+ CATCH_EINTR(err = waitpid(pid, NULL, 0)); - return(pid); - } - -diff -puN arch/um/drivers/slip_user.c~EINTR_safety arch/um/drivers/slip_user.c ---- uml-linux-2.6.7/arch/um/drivers/slip_user.c~EINTR_safety 2004-06-29 21:03:04.756914208 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/slip_user.c 2004-06-29 21:03:04.787909496 +0200 -@@ -4,7 +4,7 @@ - #include <stddef.h> - #include <sched.h> - #include <string.h> --#include <sys/errno.h> -+#include <errno.h> - #include <sys/termios.h> - #include <sys/wait.h> - #include <sys/signal.h> -@@ -100,7 +100,9 @@ static int slip_tramp(char **argv, int f - printk("%s", output); - kfree(output); - } -- if(waitpid(pid, &status, 0) < 0) err = errno; -+ CATCH_EINTR(err = waitpid(pid, &status, 0)); -+ if(err < 0) -+ err = errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ - printk("'%s' didn't exit with status 0\n", argv[0]); - err = -EINVAL; -diff -puN arch/um/drivers/slirp_user.c~EINTR_safety arch/um/drivers/slirp_user.c ---- uml-linux-2.6.7/arch/um/drivers/slirp_user.c~EINTR_safety 2004-06-29 21:03:04.772911776 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/slirp_user.c 2004-06-29 21:03:04.787909496 +0200 -@@ -4,7 +4,7 @@ - #include <stddef.h> - #include <sched.h> - #include <string.h> --#include <sys/errno.h> -+#include <errno.h> - #include <sys/wait.h> - #include <sys/signal.h> - #include "user_util.h" -@@ -113,13 +113,13 @@ static void slirp_close(int fd, void *da - } - #endif - -- err = waitpid(pri->pid, &status, WNOHANG); -- if(err<0) { -+ CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG)); -+ if(err < 0) { - printk("slirp_close: waitpid returned %d\n", errno); - return; - } - -- if(err==0) { -+ if(err == 0) { - printk("slirp_close: process %d has not exited\n"); - return; - } -diff -puN arch/um/kernel/helper.c~EINTR_safety arch/um/kernel/helper.c ---- uml-linux-2.6.7/arch/um/kernel/helper.c~EINTR_safety 2004-06-29 21:03:04.774911472 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/helper.c 2004-06-29 21:03:04.788909344 +0200 -@@ -12,6 +12,7 @@ - #include <sys/wait.h> - #include "user.h" - #include "kern_util.h" -+#include "user_util.h" - #include "os.h" - - struct helper_data { -@@ -96,7 +97,7 @@ int run_helper(void (*pre_exec)(void *), - goto out_kill; - } - else if(n != 0){ -- waitpid(pid, NULL, 0); -+ CATCH_EINTR(n = waitpid(pid, NULL, 0)); - pid = -errno; - } - -diff -puN arch/um/kernel/skas/exec_user.c~EINTR_safety arch/um/kernel/skas/exec_user.c ---- uml-linux-2.6.7/arch/um/kernel/skas/exec_user.c~EINTR_safety 2004-06-29 21:03:04.775911320 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/exec_user.c 2004-06-29 21:03:04.788909344 +0200 -@@ -11,6 +11,7 @@ - #include <sys/ptrace.h> - #include "user.h" - #include "kern_util.h" -+#include "user_util.h" - #include "os.h" - #include "time_user.h" - -@@ -26,7 +27,7 @@ static int user_thread_tramp(void *arg) - - int user_thread(unsigned long stack, int flags) - { -- int pid, status; -+ int pid, status, err; - - pid = clone(user_thread_tramp, (void *) stack_sp(stack), - flags | CLONE_FILES | SIGCHLD, NULL); -@@ -35,7 +36,8 @@ int user_thread(unsigned long stack, int - return(pid); - } - -- if(waitpid(pid, &status, WUNTRACED) < 0){ -+ CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); -+ if(err < 0){ - printk("user_thread - waitpid failed, errno = %d\n", errno); - return(-errno); - } -diff -puN arch/um/kernel/trap_user.c~EINTR_safety arch/um/kernel/trap_user.c ---- uml-linux-2.6.7/arch/um/kernel/trap_user.c~EINTR_safety 2004-06-29 21:03:04.776911168 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/trap_user.c 2004-06-29 21:03:04.788909344 +0200 -@@ -32,7 +32,14 @@ void kill_child_dead(int pid) - { - kill(pid, SIGKILL); - kill(pid, SIGCONT); -- while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT); -+ do { -+ int n; -+ CATCH_EINTR(n = waitpid(pid, NULL, 0)); -+ if (n > 0) -+ kill(pid, SIGCONT); -+ else -+ break; -+ } while(1); - } - - /* Unlocked - don't care if this is a bit off */ -diff -puN arch/um/kernel/tt/exec_user.c~EINTR_safety arch/um/kernel/tt/exec_user.c ---- uml-linux-2.6.7/arch/um/kernel/tt/exec_user.c~EINTR_safety 2004-06-29 21:03:04.777911016 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/exec_user.c 2004-06-29 21:03:04.788909344 +0200 -@@ -19,13 +19,18 @@ - void do_exec(int old_pid, int new_pid) - { - unsigned long regs[FRAME_SIZE]; -+ int err; - - if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) || -- (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) || -- (waitpid(new_pid, 0, WUNTRACED) < 0)) -+ (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0)) - tracer_panic("do_exec failed to attach proc - errno = %d", - errno); - -+ CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED)); -+ if (err < 0) -+ tracer_panic("do_exec failed to attach proc in waitpid - errno = %d", -+ errno); -+ - if(ptrace_getregs(old_pid, regs) < 0) - tracer_panic("do_exec failed to get registers - errno = %d", - errno); -diff -puN arch/um/kernel/tt/ptproxy/proxy.c~EINTR_safety arch/um/kernel/tt/ptproxy/proxy.c ---- uml-linux-2.6.7/arch/um/kernel/tt/ptproxy/proxy.c~EINTR_safety 2004-06-29 21:03:04.778910864 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/proxy.c 2004-06-29 21:03:04.789909192 +0200 -@@ -272,7 +272,7 @@ void fake_child_exit(void) - - child_proxy(1, W_EXITCODE(0, 0)); - while(debugger.waiting == 1){ -- pid = waitpid(debugger.pid, &status, WUNTRACED); -+ CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED)); - if(pid != debugger.pid){ - printk("fake_child_exit - waitpid failed, " - "errno = %d\n", errno); -@@ -280,7 +280,7 @@ void fake_child_exit(void) - } - debugger_proxy(status, debugger.pid); - } -- pid = waitpid(debugger.pid, &status, WUNTRACED); -+ CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED)); - if(pid != debugger.pid){ - printk("fake_child_exit - waitpid failed, " - "errno = %d\n", errno); -diff -puN arch/um/kernel/tt/tracer.c~EINTR_safety arch/um/kernel/tt/tracer.c ---- uml-linux-2.6.7/arch/um/kernel/tt/tracer.c~EINTR_safety 2004-06-29 21:03:04.779910712 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/tracer.c 2004-06-29 21:03:04.789909192 +0200 -@@ -192,7 +192,7 @@ int tracer(int (*init_proc)(void *), voi - printf("tracing thread pid = %d\n", tracing_pid); - - pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc); -- n = waitpid(pid, &status, WUNTRACED); -+ CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0){ - printf("waitpid on idle thread failed, errno = %d\n", errno); - exit(1); -@@ -233,7 +233,7 @@ int tracer(int (*init_proc)(void *), voi - } - set_cmdline("(tracing thread)"); - while(1){ -- pid = waitpid(-1, &status, WUNTRACED); -+ CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED)); - if(pid <= 0){ - if(errno != ECHILD){ - printf("wait failed - errno = %d\n", errno); -diff -puN arch/um/os-Linux/drivers/ethertap_user.c~EINTR_safety arch/um/os-Linux/drivers/ethertap_user.c ---- uml-linux-2.6.7/arch/um/os-Linux/drivers/ethertap_user.c~EINTR_safety 2004-06-29 21:03:04.780910560 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/ethertap_user.c 2004-06-29 21:03:04.789909192 +0200 -@@ -16,6 +16,7 @@ - #include <net/if.h> - #include "user.h" - #include "kern_util.h" -+#include "user_util.h" - #include "net_user.h" - #include "etap.h" - #include "helper.h" -@@ -125,7 +126,8 @@ static int etap_tramp(char *dev, char *g - if(c != 1){ - printk("etap_tramp : uml_net failed\n"); - err = -EINVAL; -- if(waitpid(pid, &status, 0) < 0) -+ CATCH_EINTR(n = waitpid(pid, &status, 0)); -+ if(n < 0) - err = -errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) - printk("uml_net didn't exit with status 1\n"); -diff -puN arch/um/os-Linux/drivers/tuntap_user.c~EINTR_safety arch/um/os-Linux/drivers/tuntap_user.c ---- uml-linux-2.6.7/arch/um/os-Linux/drivers/tuntap_user.c~EINTR_safety 2004-06-29 21:03:04.782910256 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/tuntap_user.c 2004-06-29 21:03:04.789909192 +0200 -@@ -18,6 +18,7 @@ - #include "net_user.h" - #include "tuntap.h" - #include "kern_util.h" -+#include "user_util.h" - #include "user.h" - #include "helper.h" - #include "os.h" -@@ -108,7 +109,7 @@ static int tuntap_open_tramp(char *gate, - errno); - return(-errno); - } -- waitpid(pid, NULL, 0); -+ CATCH_EINTR(waitpid(pid, NULL, 0)); - - cmsg = CMSG_FIRSTHDR(&msg); - if(cmsg == NULL){ -diff -puN arch/um/os-Linux/process.c~EINTR_safety arch/um/os-Linux/process.c ---- uml-linux-2.6.7/arch/um/os-Linux/process.c~EINTR_safety 2004-06-29 21:03:04.783910104 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c 2004-06-29 21:03:04.790909040 +0200 -@@ -12,6 +12,7 @@ - #include <sys/wait.h> - #include "os.h" - #include "user.h" -+#include "user_util.h" - - #define ARBITRARY_ADDR -1 - #define FAILURE_PID -1 -@@ -87,7 +88,7 @@ void os_kill_process(int pid, int reap_c - { - kill(pid, SIGKILL); - if(reap_child) -- waitpid(pid, NULL, 0); -+ CATCH_EINTR(waitpid(pid, NULL, 0)); - - } - -_ diff --git a/linux-uml/linux-uml-2.6.7/Export_strncpy.patch b/linux-uml/linux-uml-2.6.7/Export_strncpy.patch deleted file mode 100644 index 3a15f0f15d..0000000000 --- a/linux-uml/linux-uml-2.6.7/Export_strncpy.patch +++ /dev/null @@ -1,27 +0,0 @@ - -Adds some exports - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/kernel/ksyms.c | 2 ++ - 1 files changed, 2 insertions(+) - -diff -puN arch/um/kernel/ksyms.c~Export_strncpy arch/um/kernel/ksyms.c ---- uml-linux-2.6.7/arch/um/kernel/ksyms.c~Export_strncpy 2004-06-29 21:03:06.788605344 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/ksyms.c 2004-06-29 21:03:06.790605040 +0200 -@@ -50,11 +50,13 @@ EXPORT_SYMBOL(handle_page_fault); - EXPORT_SYMBOL(find_iomem); - - #ifdef CONFIG_MODE_TT -+EXPORT_SYMBOL(strncpy_from_user_tt); - EXPORT_SYMBOL(copy_from_user_tt); - EXPORT_SYMBOL(copy_to_user_tt); - #endif - - #ifdef CONFIG_MODE_SKAS -+EXPORT_SYMBOL(strncpy_from_user_skas); - EXPORT_SYMBOL(copy_to_user_skas); - EXPORT_SYMBOL(copy_from_user_skas); - #endif -_ diff --git a/linux-uml/linux-uml-2.6.7/Fix_os_process_pc.patch b/linux-uml/linux-uml-2.6.7/Fix_os_process_pc.patch deleted file mode 100644 index 74e8c89c51..0000000000 --- a/linux-uml/linux-uml-2.6.7/Fix_os_process_pc.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- - - uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c | 14 ++++++++------ - 1 files changed, 8 insertions(+), 6 deletions(-) - -diff -puN arch/um/os-Linux/process.c~Fix_os_process_pc arch/um/os-Linux/process.c ---- uml-linux-2.6.7/arch/um/os-Linux/process.c~Fix_os_process_pc 2004-06-21 17:51:56.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c 2004-06-21 18:08:59.000000000 +0200 -@@ -16,9 +16,12 @@ - #define ARBITRARY_ADDR -1 - #define FAILURE_PID -1 - -+#define STAT_PATH_LEN sizeof("/proc/#######/stat\0") -+#define COMM_SCANF "%*[^)])" -+ - unsigned long os_process_pc(int pid) - { -- char proc_stat[sizeof("/proc/#####/stat\0")], buf[256]; -+ char proc_stat[STAT_PATH_LEN], buf[256]; - unsigned long pc; - int fd, err; - -@@ -38,9 +41,9 @@ unsigned long os_process_pc(int pid) - } - os_close_file(fd); - pc = ARBITRARY_ADDR; -- if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d " -+ if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " -- "%*d %*d %*d %*d %ld", &pc) != 1){ -+ "%*d %*d %*d %*d %lu", &pc) != 1){ - printk("os_process_pc - couldn't find pc in '%s'\n", buf); - } - return(pc); -@@ -48,7 +51,7 @@ unsigned long os_process_pc(int pid) - - int os_process_parent(int pid) - { -- char stat[sizeof("/proc/nnnnn/stat\0")]; -+ char stat[STAT_PATH_LEN]; - char data[256]; - int parent, n, fd; - -@@ -70,8 +73,7 @@ int os_process_parent(int pid) - } - - parent = FAILURE_PID; -- /* XXX This will break if there is a space in the command */ -- n = sscanf(data, "%*d %*s %*c %d", &parent); -+ n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent); - if(n != 1) - printk("Failed to scan '%s'\n", data); - - -_ diff --git a/linux-uml/linux-uml-2.6.7/Ghash.patch b/linux-uml/linux-uml-2.6.7/Ghash.patch deleted file mode 100644 index 3b376806c2..0000000000 --- a/linux-uml/linux-uml-2.6.7/Ghash.patch +++ /dev/null @@ -1,250 +0,0 @@ - -Just for now and just for UML; it will go away. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/include/linux/ghash.h | 236 ++++++++++++++++++++++++++++ - 1 files changed, 236 insertions(+) - -diff -puN /dev/null include/linux/ghash.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/include/linux/ghash.h 2004-06-29 21:03:00.575549872 +0200 -@@ -0,0 +1,236 @@ -+/* -+ * include/linux/ghash.h -- generic hashing with fuzzy retrieval -+ * -+ * (C) 1997 Thomas Schoebel-Theuer -+ * -+ * The algorithms implemented here seem to be a completely new invention, -+ * and I'll publish the fundamentals in a paper. -+ */ -+ -+#ifndef _GHASH_H -+#define _GHASH_H -+/* HASHSIZE _must_ be a power of two!!! */ -+ -+ -+#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \ -+\ -+struct NAME##_table {\ -+ TYPE * hashtable[HASHSIZE];\ -+ TYPE * sorted_list;\ -+ int nr_entries;\ -+};\ -+\ -+struct NAME##_ptrs {\ -+ TYPE * next_hash;\ -+ TYPE * prev_hash;\ -+ TYPE * next_sorted;\ -+ TYPE * prev_sorted;\ -+}; -+ -+#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\ -+\ -+LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -+{\ -+ int ix = HASHFN(elem->KEY);\ -+ TYPE ** base = &tbl->hashtable[ix];\ -+ TYPE * ptr = *base;\ -+ TYPE * prev = NULL;\ -+\ -+ tbl->nr_entries++;\ -+ while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\ -+ base = &ptr->PTRS.next_hash;\ -+ prev = ptr;\ -+ ptr = *base;\ -+ }\ -+ elem->PTRS.next_hash = ptr;\ -+ elem->PTRS.prev_hash = prev;\ -+ if(ptr) {\ -+ ptr->PTRS.prev_hash = elem;\ -+ }\ -+ *base = elem;\ -+\ -+ ptr = prev;\ -+ if(!ptr) {\ -+ ptr = tbl->sorted_list;\ -+ prev = NULL;\ -+ } else {\ -+ prev = ptr->PTRS.prev_sorted;\ -+ }\ -+ while(ptr) {\ -+ TYPE * next = ptr->PTRS.next_hash;\ -+ if(next && KEYCMP(next->KEY, elem->KEY)) {\ -+ prev = ptr;\ -+ ptr = next;\ -+ } else if(KEYCMP(ptr->KEY, elem->KEY)) {\ -+ prev = ptr;\ -+ ptr = ptr->PTRS.next_sorted;\ -+ } else\ -+ break;\ -+ }\ -+ elem->PTRS.next_sorted = ptr;\ -+ elem->PTRS.prev_sorted = prev;\ -+ if(ptr) {\ -+ ptr->PTRS.prev_sorted = elem;\ -+ }\ -+ if(prev) {\ -+ prev->PTRS.next_sorted = elem;\ -+ } else {\ -+ tbl->sorted_list = elem;\ -+ }\ -+}\ -+\ -+LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -+{\ -+ TYPE * next = elem->PTRS.next_hash;\ -+ TYPE * prev = elem->PTRS.prev_hash;\ -+\ -+ tbl->nr_entries--;\ -+ if(next)\ -+ next->PTRS.prev_hash = prev;\ -+ if(prev)\ -+ prev->PTRS.next_hash = next;\ -+ else {\ -+ int ix = HASHFN(elem->KEY);\ -+ tbl->hashtable[ix] = next;\ -+ }\ -+\ -+ next = elem->PTRS.next_sorted;\ -+ prev = elem->PTRS.prev_sorted;\ -+ if(next)\ -+ next->PTRS.prev_sorted = prev;\ -+ if(prev)\ -+ prev->PTRS.next_sorted = next;\ -+ else\ -+ tbl->sorted_list = next;\ -+}\ -+\ -+LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\ -+{\ -+ int ix = hashfn(pos);\ -+ TYPE * ptr = tbl->hashtable[ix];\ -+ while(ptr && KEYCMP(ptr->KEY, pos))\ -+ ptr = ptr->PTRS.next_hash;\ -+ if(ptr && !KEYEQ(ptr->KEY, pos))\ -+ ptr = NULL;\ -+ return ptr;\ -+}\ -+\ -+LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\ -+{\ -+ int ix;\ -+ int offset;\ -+ TYPE * ptr;\ -+ TYPE * next;\ -+\ -+ ptr = tbl->sorted_list;\ -+ if(!ptr || KEYCMP(pos, ptr->KEY))\ -+ return NULL;\ -+ ix = HASHFN(pos);\ -+ offset = HASHSIZE;\ -+ do {\ -+ offset >>= 1;\ -+ next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\ -+ if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\ -+ && KEYCMP(ptr->KEY, next->KEY))\ -+ ptr = next;\ -+ } while(offset);\ -+\ -+ for(;;) {\ -+ next = ptr->PTRS.next_hash;\ -+ if(next) {\ -+ if(KEYCMP(next->KEY, pos)) {\ -+ ptr = next;\ -+ continue;\ -+ }\ -+ }\ -+ next = ptr->PTRS.next_sorted;\ -+ if(next && KEYCMP(next->KEY, pos)) {\ -+ ptr = next;\ -+ continue;\ -+ }\ -+ return ptr;\ -+ }\ -+ return NULL;\ -+} -+ -+/* LINKAGE - empty or "static", depending on whether you want the definitions to -+ * be public or not -+ * NAME - a string to stick in names to make this hash table type distinct from -+ * any others -+ * HASHSIZE - number of buckets -+ * TYPE - type of data contained in the buckets - must be a structure, one -+ * field is of type NAME_ptrs, another is the hash key -+ * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that -+ * field -+ * KEYTYPE - type of the key field within TYPE -+ * KEY - name of the key field within TYPE -+ * KEYCMP - pointer to function that compares KEYTYPEs to each other - the -+ * prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, -+ * non-zero for not equal -+ * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE), -+ * it returns a number in the range 0 ... HASHSIZE - 1 -+ * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call -+ * DEF_HASH. -+ */ -+ -+#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \ -+\ -+struct NAME##_table {\ -+ TYPE * hashtable[HASHSIZE];\ -+ int nr_entries;\ -+};\ -+\ -+struct NAME##_ptrs {\ -+ TYPE * next_hash;\ -+ TYPE * prev_hash;\ -+}; -+ -+#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\ -+\ -+LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -+{\ -+ int ix = HASHFN(elem->KEY);\ -+ TYPE ** base = &tbl->hashtable[ix];\ -+ TYPE * ptr = *base;\ -+ TYPE * prev = NULL;\ -+\ -+ tbl->nr_entries++;\ -+ while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\ -+ base = &ptr->PTRS.next_hash;\ -+ prev = ptr;\ -+ ptr = *base;\ -+ }\ -+ elem->PTRS.next_hash = ptr;\ -+ elem->PTRS.prev_hash = prev;\ -+ if(ptr) {\ -+ ptr->PTRS.prev_hash = elem;\ -+ }\ -+ *base = elem;\ -+}\ -+\ -+LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -+{\ -+ TYPE * next = elem->PTRS.next_hash;\ -+ TYPE * prev = elem->PTRS.prev_hash;\ -+\ -+ tbl->nr_entries--;\ -+ if(next)\ -+ next->PTRS.prev_hash = prev;\ -+ if(prev)\ -+ prev->PTRS.next_hash = next;\ -+ else {\ -+ int ix = HASHFN(elem->KEY);\ -+ tbl->hashtable[ix] = next;\ -+ }\ -+}\ -+\ -+LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\ -+{\ -+ int ix = HASHFN(pos);\ -+ TYPE * ptr = tbl->hashtable[ix];\ -+ while(ptr && KEYCMP(ptr->KEY, pos))\ -+ ptr = ptr->PTRS.next_hash;\ -+ return ptr;\ -+} -+ -+#endif -_ diff --git a/linux-uml/linux-uml-2.6.7/H-02-Fixdep-improve.patch b/linux-uml/linux-uml-2.6.7/H-02-Fixdep-improve.patch deleted file mode 100644 index b523c7187b..0000000000 --- a/linux-uml/linux-uml-2.6.7/H-02-Fixdep-improve.patch +++ /dev/null @@ -1,48 +0,0 @@ - -You probably saw that if you change one config option, even if -linux/autoconf.h (which is included by everything) changes, the kernel is -smart enough not to recompile everything. But with UML this no more holds. -Why? Because, as you see in this patch, fixdep avoids making anything depend -onto linux/autoconf.h *explicitly*, but nobody taught him to do the same for -arch/um/include/uml-config.h. So apply this patch. Do not say "I don't want -to change the generic Kbuild for one arch": this cannot hurt. It's a bugfix -for us, a no-op for others. - -Note: with this patch, fixdep will still add a dependency from a file -containing UML_CONFIG_BYE onto CONFIG_BYE. Since someone could think that -fixdep should grep for [^A-Z_]CONFIG_ rather than simply for CONFIG_, I've -added a comment that ask *not to fix* this "bug". - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/scripts/basic/fixdep.c | 9 +++++++++ - 1 files changed, 9 insertions(+) - -diff -puN scripts/basic/fixdep.c~H-02-Fixdep-improve scripts/basic/fixdep.c ---- uml-linux-2.6.7/scripts/basic/fixdep.c~H-02-Fixdep-improve 2004-06-29 21:03:01.984335704 +0200 -+++ uml-linux-2.6.7-paolo/scripts/basic/fixdep.c 2004-06-29 21:03:01.986335400 +0200 -@@ -93,6 +93,14 @@ - * (Note: it'd be easy to port over the complete mkdep state machine, - * but I don't think the added complexity is worth it) - */ -+/* -+ * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto -+ * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not -+ * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as -+ * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h, -+ * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that -+ * those files will have correct dependencies. -+ */ - - #include <sys/types.h> - #include <sys/stat.h> -@@ -310,6 +318,7 @@ void parse_dep_file(void *map, size_t le - } - memcpy(s, m, p-m); s[p-m] = 0; - if (strrcmp(s, "include/linux/autoconf.h") && -+ strrcmp(s, "arch/um/include/uml-config.h") && - strrcmp(s, ".ver")) { - printf(" %s \\\n", s); - do_config_file(s); -_ diff --git a/linux-uml/linux-uml-2.6.7/HostFs-2.6-fd_leak.patch b/linux-uml/linux-uml-2.6.7/HostFs-2.6-fd_leak.patch deleted file mode 100644 index 8b6d6bf790..0000000000 --- a/linux-uml/linux-uml-2.6.7/HostFs-2.6-fd_leak.patch +++ /dev/null @@ -1,53 +0,0 @@ - -In detail, on 2.4 we used force_delete() to make sure inode were not cached, -and we then close the host file when the inode is cleared; when porting to 2.6 -the "force_delete" thing was dropped, and this patch adds a fix for this -(by setting drop_inode = generic_delete_inode). -Search for drop_inode in the 2.6 Documentation/filesystems/vfs.txt for info about this. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/fs/hostfs/hostfs_kern.c | 16 +++++++++++++++- - 1 files changed, 15 insertions(+), 1 deletion(-) - -diff -puN fs/hostfs/hostfs_kern.c~HostFs-2.6-fd_leak fs/hostfs/hostfs_kern.c ---- uml-linux-2.6.7/fs/hostfs/hostfs_kern.c~HostFs-2.6-fd_leak 2004-06-29 21:03:01.138464296 +0200 -+++ uml-linux-2.6.7-paolo/fs/hostfs/hostfs_kern.c 2004-06-29 21:03:01.141463840 +0200 -@@ -284,13 +284,25 @@ static struct inode *hostfs_alloc_inode( - return(&hi->vfs_inode); - } - -+static void hostfs_delete_inode(struct inode *inode) -+{ -+ if(HOSTFS_I(inode)->fd != -1) { -+ close_file(&HOSTFS_I(inode)->fd); -+ printk("Closing host fd in .delete_inode\n"); -+ HOSTFS_I(inode)->fd = -1; -+ } -+ clear_inode(inode); -+} -+ - static void hostfs_destroy_inode(struct inode *inode) - { - if(HOSTFS_I(inode)->host_filename) - kfree(HOSTFS_I(inode)->host_filename); - -- if(HOSTFS_I(inode)->fd != -1) -+ if(HOSTFS_I(inode)->fd != -1) { - close_file(&HOSTFS_I(inode)->fd); -+ printk("Closing host fd in .destroy_inode\n"); -+ } - - kfree(HOSTFS_I(inode)); - } -@@ -302,6 +314,8 @@ static void hostfs_read_inode(struct ino - - static struct super_operations hostfs_sbops = { - .alloc_inode = hostfs_alloc_inode, -+ .drop_inode = generic_delete_inode, -+ .delete_inode = hostfs_delete_inode, - .destroy_inode = hostfs_destroy_inode, - .read_inode = hostfs_read_inode, - .statfs = hostfs_statfs, -_ diff --git a/linux-uml/linux-uml-2.6.7/Hostaudio_clean.patch b/linux-uml/linux-uml-2.6.7/Hostaudio_clean.patch deleted file mode 100644 index 86e10662a6..0000000000 --- a/linux-uml/linux-uml-2.6.7/Hostaudio_clean.patch +++ /dev/null @@ -1,417 +0,0 @@ - -Folds hostaudio_user.c into hostaudio_kern.c. A lot of code less. -Also note that I no more update ppos(as I used to do in the 2.4 patch): -I checked that OSS never changes ppos, so hostaudio did the right thing. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/drivers/Makefile | 2 - uml-linux-2.6.7-paolo/arch/um/drivers/hostaudio_kern.c | 73 ++++++--- - uml-linux-2.6.7/arch/um/drivers/hostaudio_user.c | 130 ----------------- - uml-linux-2.6.7/arch/um/include/hostaudio.h | 48 ------ - 4 files changed, 50 insertions(+), 203 deletions(-) - -diff -puN arch/um/drivers/hostaudio_kern.c~Hostaudio_clean arch/um/drivers/hostaudio_kern.c ---- uml-linux-2.6.7/arch/um/drivers/hostaudio_kern.c~Hostaudio_clean 2004-06-29 21:03:03.471109680 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/hostaudio_kern.c 2004-06-29 21:03:03.477108768 +0200 -@@ -13,7 +13,18 @@ - #include "asm/uaccess.h" - #include "kern_util.h" - #include "init.h" --#include "hostaudio.h" -+#include "os.h" -+ -+struct hostaudio_state { -+ int fd; -+}; -+ -+struct hostmixer_state { -+ int fd; -+}; -+ -+#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp" -+#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer" - - /* Only changed from linux_main at boot time */ - char *dsp = HOSTAUDIO_DEV_DSP; -@@ -61,7 +72,7 @@ static ssize_t hostaudio_read(struct fil - { - struct hostaudio_state *state = file->private_data; - void *kbuf; -- int err; -+ int ret; - - #ifdef DEBUG - printk("hostaudio: read called, count = %d\n", count); -@@ -71,16 +82,16 @@ static ssize_t hostaudio_read(struct fil - if(kbuf == NULL) - return(-ENOMEM); - -- err = hostaudio_read_user(state, kbuf, count, ppos); -- if(err < 0) -+ ret = os_read_file(state->fd, kbuf, count); -+ if(ret < 0) - goto out; - -- if(copy_to_user(buffer, kbuf, err)) -- err = -EFAULT; -+ if(copy_to_user(buffer, kbuf, ret)) -+ ret = -EFAULT; - - out: - kfree(kbuf); -- return(err); -+ return(ret); - } - - static ssize_t hostaudio_write(struct file *file, const char *buffer, -@@ -88,7 +99,7 @@ static ssize_t hostaudio_write(struct fi - { - struct hostaudio_state *state = file->private_data; - void *kbuf; -- int err; -+ int ret; - - #ifdef DEBUG - printk("hostaudio: write called, count = %d\n", count); -@@ -98,17 +109,17 @@ static ssize_t hostaudio_write(struct fi - if(kbuf == NULL) - return(-ENOMEM); - -- err = -EFAULT; -+ ret = -EFAULT; - if(copy_from_user(kbuf, buffer, count)) - goto out; - -- err = hostaudio_write_user(state, kbuf, count, ppos); -- if(err < 0) -+ ret = os_write_file(state->fd, kbuf, count); -+ if(ret < 0) - goto out; - - out: - kfree(kbuf); -- return(err); -+ return(ret); - } - - static unsigned int hostaudio_poll(struct file *file, -@@ -128,7 +139,7 @@ static int hostaudio_ioctl(struct inode - { - struct hostaudio_state *state = file->private_data; - unsigned long data = 0; -- int err; -+ int ret; - - #ifdef DEBUG - printk("hostaudio: ioctl called, cmd = %u\n", cmd); -@@ -147,7 +158,7 @@ static int hostaudio_ioctl(struct inode - break; - } - -- err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data); -+ ret = os_ioctl_generic(state->fd, cmd, (unsigned long) &data); - - switch(cmd){ - case SNDCTL_DSP_SPEED: -@@ -163,7 +174,7 @@ static int hostaudio_ioctl(struct inode - break; - } - -- return(err); -+ return(ret); - } - - static int hostaudio_open(struct inode *inode, struct file *file) -@@ -182,12 +193,17 @@ static int hostaudio_open(struct inode * - if(file->f_mode & FMODE_READ) r = 1; - if(file->f_mode & FMODE_WRITE) w = 1; - -- ret = hostaudio_open_user(state, r, w, dsp); -+ ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); -+ - if(ret < 0){ -+ printk("hostaudio_open failed to open '%s', err = %d\n", -+ dsp, -ret); - kfree(state); - return(ret); - } - -+ state->fd = ret; -+ - file->private_data = state; - return(0); - } -@@ -195,16 +211,19 @@ static int hostaudio_open(struct inode * - static int hostaudio_release(struct inode *inode, struct file *file) - { - struct hostaudio_state *state = file->private_data; -- int ret; - - #ifdef DEBUG - printk("hostaudio: release called\n"); - #endif - -- ret = hostaudio_release_user(state); -+ if(state->fd >= 0){ -+ os_close_file(state->fd); -+ state->fd = -1; -+ } -+ - kfree(state); - -- return(ret); -+ return(0); - } - - /* /dev/mixer file operations */ -@@ -218,7 +237,7 @@ static int hostmixer_ioctl_mixdev(struct - printk("hostmixer: ioctl called\n"); - #endif - -- return(hostmixer_ioctl_mixdev_user(state, cmd, arg)); -+ return(os_ioctl_generic(state->fd, cmd, arg)); - } - - static int hostmixer_open_mixdev(struct inode *inode, struct file *file) -@@ -237,13 +256,17 @@ static int hostmixer_open_mixdev(struct - if(file->f_mode & FMODE_READ) r = 1; - if(file->f_mode & FMODE_WRITE) w = 1; - -- ret = hostmixer_open_mixdev_user(state, r, w, mixer); -+ ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); - - if(ret < 0){ -+ printk("hostaudio_open_mixdev failed to open '%s', err = %d\n", -+ dsp, -ret); - kfree(state); - return(ret); - } - -+ state->fd = ret; -+ - file->private_data = state; - return(0); - } -@@ -251,16 +274,18 @@ static int hostmixer_open_mixdev(struct - static int hostmixer_release(struct inode *inode, struct file *file) - { - struct hostmixer_state *state = file->private_data; -- int ret; - - #ifdef DEBUG - printk("hostmixer: release called\n"); - #endif - -- ret = hostmixer_release_mixdev_user(state); -+ if(state->fd >= 0){ -+ os_close_file(state->fd); -+ state->fd = -1; -+ } - kfree(state); - -- return(ret); -+ return(0); - } - - -diff -L arch/um/drivers/hostaudio_user.c -puN arch/um/drivers/hostaudio_user.c~Hostaudio_clean /dev/null ---- uml-linux-2.6.7/arch/um/drivers/hostaudio_user.c -+++ /dev/null 1970-01-01 01:00:00.000000000 +0100 -@@ -1,130 +0,0 @@ --/* -- * Copyright (C) 2002 Steve Schmidtke -- * Licensed under the GPL -- */ -- --#include <sys/types.h> --#include <unistd.h> --#include <errno.h> --#include "hostaudio.h" --#include "user_util.h" --#include "kern_util.h" --#include "user.h" --#include "os.h" -- --/* /dev/dsp file operations */ -- --ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, -- size_t count, loff_t *ppos) --{ --#ifdef DEBUG -- printk("hostaudio: read_user called, count = %d\n", count); --#endif -- -- return(os_read_file(state->fd, buffer, count)); --} -- --ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer, -- size_t count, loff_t *ppos) --{ --#ifdef DEBUG -- printk("hostaudio: write_user called, count = %d\n", count); --#endif -- -- return(os_write_file(state->fd, buffer, count)); --} -- --int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, -- unsigned long arg) --{ --#ifdef DEBUG -- printk("hostaudio: ioctl_user called, cmd = %u\n", cmd); --#endif -- -- return(os_ioctl_generic(state->fd, cmd, arg)); --} -- --int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp) --{ --#ifdef DEBUG -- printk("hostaudio: open_user called\n"); --#endif -- -- state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); -- -- if(state->fd < 0) { -- printk("hostaudio_open_user failed to open '%s', err = %d\n", -- dsp, -state->fd); -- return(state->fd); -- } -- -- return(0); --} -- --int hostaudio_release_user(struct hostaudio_state *state) --{ --#ifdef DEBUG -- printk("hostaudio: release called\n"); --#endif -- if(state->fd >= 0){ -- os_close_file(state->fd); -- state->fd = -1; -- } -- -- return(0); --} -- --/* /dev/mixer file operations */ -- --int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, -- unsigned int cmd, unsigned long arg) --{ --#ifdef DEBUG -- printk("hostmixer: ioctl_user called cmd = %u\n",cmd); --#endif -- -- return(os_ioctl_generic(state->fd, cmd, arg)); --} -- --int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w, -- char *mixer) --{ --#ifdef DEBUG -- printk("hostmixer: open_user called\n"); --#endif -- -- state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); -- -- if(state->fd < 0) { -- printk("hostaudio_open_mixdev_user failed to open '%s', " -- "err = %d\n", mixer, state->fd); -- return(state->fd); -- } -- -- return(0); --} -- --int hostmixer_release_mixdev_user(struct hostmixer_state *state) --{ --#ifdef DEBUG -- printk("hostmixer: release_user called\n"); --#endif -- -- if(state->fd >= 0){ -- os_close_file(state->fd); -- state->fd = -1; -- } -- -- return 0; --} -- --/* -- * Overrides for Emacs so that we follow Linus's tabbing style. -- * Emacs will notice this stuff at the end of the file and automatically -- * adjust the settings for this buffer only. This must remain at the end -- * of the file. -- * --------------------------------------------------------------------------- -- * Local variables: -- * c-file-style: "linux" -- * End: -- */ -diff -puN arch/um/drivers/Makefile~Hostaudio_clean arch/um/drivers/Makefile ---- uml-linux-2.6.7/arch/um/drivers/Makefile~Hostaudio_clean 2004-06-29 21:03:03.474109224 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/Makefile 2004-06-29 21:03:03.478108616 +0200 -@@ -15,7 +15,7 @@ mcast-objs := mcast_kern.o mcast_user.o - #pcap-objs := pcap_kern.o pcap_user.o $(PCAP) - net-objs := net_kern.o net_user.o - mconsole-objs := mconsole_kern.o mconsole_user.o --hostaudio-objs := hostaudio_kern.o hostaudio_user.o -+hostaudio-objs := hostaudio_kern.o - ubd-objs := ubd_kern.o ubd_user.o - port-objs := port_kern.o port_user.o - harddog-objs := harddog_kern.o harddog_user.o -diff -L arch/um/include/hostaudio.h -puN arch/um/include/hostaudio.h~Hostaudio_clean /dev/null ---- uml-linux-2.6.7/arch/um/include/hostaudio.h -+++ /dev/null 1970-01-01 01:00:00.000000000 +0100 -@@ -1,48 +0,0 @@ --/* -- * Copyright (C) 2002 Steve Schmidtke -- * Licensed under the GPL -- */ -- --#ifndef HOSTAUDIO_H --#define HOSTAUDIO_H -- --#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp" --#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer" -- --struct hostaudio_state { -- int fd; --}; -- --struct hostmixer_state { -- int fd; --}; -- --/* UML user-side protoypes */ --extern ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, -- size_t count, loff_t *ppos); --extern ssize_t hostaudio_write_user(struct hostaudio_state *state, -- const char *buffer, size_t count, -- loff_t *ppos); --extern int hostaudio_ioctl_user(struct hostaudio_state *state, -- unsigned int cmd, unsigned long arg); --extern int hostaudio_open_user(struct hostaudio_state *state, int r, int w, -- char *dsp); --extern int hostaudio_release_user(struct hostaudio_state *state); --extern int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, -- unsigned int cmd, unsigned long arg); --extern int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, -- int w, char *mixer); --extern int hostmixer_release_mixdev_user(struct hostmixer_state *state); -- --#endif /* HOSTAUDIO_H */ -- --/* -- * 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/linux-uml/linux-uml-2.6.7/LegacyTerminalSupport.patch b/linux-uml/linux-uml-2.6.7/LegacyTerminalSupport.patch deleted file mode 100644 index cf3e84987b..0000000000 --- a/linux-uml/linux-uml-2.6.7/LegacyTerminalSupport.patch +++ /dev/null @@ -1,81 +0,0 @@ - -The second adds the LEGACY_PTY config option. Without it, with late 2.6 kernels -/dev/ptyxx won't work. In fact, with those kernels, root_fs_toms does not -work, because it's "unable to allocate TTY pair". And removes the dead option -"UNIX98_PTY_COUNT" (just commented out for now). - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/Kconfig_char | 57 ++++++++++++++++++++++++++--- - 1 files changed, 53 insertions(+), 4 deletions(-) - -diff -puN arch/um/Kconfig_char~LegacyTerminalSupport arch/um/Kconfig_char ---- uml-linux-2.6.7/arch/um/Kconfig_char~LegacyTerminalSupport 2004-06-29 21:03:01.420421432 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Kconfig_char 2004-06-29 21:03:01.423420976 +0200 -@@ -108,11 +108,60 @@ config SSL_CHAN - - config UNIX98_PTYS - bool "Unix98 PTY support" -- --config UNIX98_PTY_COUNT -- int "Maximum number of Unix98 PTYs in use (0-2048)" -- depends on UNIX98_PTYS -+ ---help--- -+ A pseudo terminal (PTY) is a software device consisting of two -+ halves: a master and a slave. The slave device behaves identical to -+ a physical terminal; the master device is used by a process to -+ read data from and write data to the slave, thereby emulating a -+ terminal. Typical programs for the master side are telnet servers -+ and xterms. -+ -+ Linux has traditionally used the BSD-like names /dev/ptyxx for -+ masters and /dev/ttyxx for slaves of pseudo terminals. This scheme -+ has a number of problems. The GNU C library glibc 2.1 and later, -+ however, supports the Unix98 naming standard: in order to acquire a -+ pseudo terminal, a process opens /dev/ptmx; the number of the pseudo -+ terminal is then made available to the process and the pseudo -+ terminal slave can be accessed as /dev/pts/<number>. What was -+ traditionally /dev/ttyp2 will then be /dev/pts/2, for example. -+ -+ All modern Linux systems use the Unix98 ptys. Say Y unless -+ you're on an embedded system and want to conserve memory. -+ -+config LEGACY_PTYS -+ bool "Legacy (BSD) PTY support" -+ default y -+ ---help--- -+ A pseudo terminal (PTY) is a software device consisting of two -+ halves: a master and a slave. The slave device behaves identical to -+ a physical terminal; the master device is used by a process to -+ read data from and write data to the slave, thereby emulating a -+ terminal. Typical programs for the master side are telnet servers -+ and xterms. -+ -+ Linux has traditionally used the BSD-like names /dev/ptyxx -+ for masters and /dev/ttyxx for slaves of pseudo -+ terminals. This scheme has a number of problems, including -+ security. This option enables these legacy devices; on most -+ systems, it is safe to say N. -+ -+ -+config LEGACY_PTY_COUNT -+ int "Maximum number of legacy PTY in use" -+ depends on LEGACY_PTYS - default "256" -+ ---help--- -+ The maximum number of legacy PTYs that can be used at any one time. -+ The default is 256, and should be more than enough. Embedded -+ systems may want to reduce this to save memory. -+ -+ When not in use, each legacy PTY occupies 12 bytes on 32-bit -+ architectures and 24 bytes on 64-bit architectures. -+ -+#config UNIX98_PTY_COUNT -+# int "Maximum number of Unix98 PTYs in use (0-2048)" -+# depends on UNIX98_PTYS -+# default "256" - - config WATCHDOG - bool "Watchdog Timer Support" -_ diff --git a/linux-uml/linux-uml-2.6.7/Main-uml-patch-no-skas.patch b/linux-uml/linux-uml-2.6.7/Main-uml-patch-no-skas.patch deleted file mode 100644 index 1a7ab95d4c..0000000000 --- a/linux-uml/linux-uml-2.6.7/Main-uml-patch-no-skas.patch +++ /dev/null @@ -1,19521 +0,0 @@ - -The main part of UML; it is the last distributed patch for 2.6.7 -Removes skas support from the main UML patch; apply or get conflicts. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/Kconfig | 52 - uml-linux-2.6.7-paolo/arch/um/Kconfig_block | 14 - uml-linux-2.6.7-paolo/arch/um/Kconfig_net | 70 - uml-linux-2.6.7-paolo/arch/um/Makefile | 110 - - uml-linux-2.6.7-paolo/arch/um/Makefile-i386 | 23 - uml-linux-2.6.7-paolo/arch/um/Makefile-skas | 6 - uml-linux-2.6.7-paolo/arch/um/config.release | 1 - uml-linux-2.6.7-paolo/arch/um/defconfig | 230 +- - uml-linux-2.6.7-paolo/arch/um/drivers/Makefile | 17 - uml-linux-2.6.7-paolo/arch/um/drivers/chan_kern.c | 16 - uml-linux-2.6.7-paolo/arch/um/drivers/chan_user.c | 100 - uml-linux-2.6.7-paolo/arch/um/drivers/cow.h | 41 - uml-linux-2.6.7-paolo/arch/um/drivers/cow_kern.c | 630 ++++++ - uml-linux-2.6.7-paolo/arch/um/drivers/cow_sys.h | 48 - uml-linux-2.6.7-paolo/arch/um/drivers/cow_user.c | 375 +++ - uml-linux-2.6.7-paolo/arch/um/drivers/daemon_user.c | 26 - uml-linux-2.6.7-paolo/arch/um/drivers/fd.c | 3 - uml-linux-2.6.7-paolo/arch/um/drivers/harddog_user.c | 62 - uml-linux-2.6.7-paolo/arch/um/drivers/hostaudio_kern.c | 107 - - uml-linux-2.6.7-paolo/arch/um/drivers/hostaudio_user.c | 63 - uml-linux-2.6.7-paolo/arch/um/drivers/line.c | 152 - - uml-linux-2.6.7-paolo/arch/um/drivers/mcast_user.c | 16 - uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_kern.c | 140 + - uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_user.c | 25 - uml-linux-2.6.7-paolo/arch/um/drivers/mmapper_kern.c | 5 - uml-linux-2.6.7-paolo/arch/um/drivers/net_kern.c | 89 - uml-linux-2.6.7-paolo/arch/um/drivers/net_user.c | 46 - uml-linux-2.6.7-paolo/arch/um/drivers/null.c | 1 - uml-linux-2.6.7-paolo/arch/um/drivers/port_kern.c | 17 - uml-linux-2.6.7-paolo/arch/um/drivers/port_user.c | 31 - uml-linux-2.6.7-paolo/arch/um/drivers/pty.c | 22 - uml-linux-2.6.7-paolo/arch/um/drivers/slip_user.c | 69 - uml-linux-2.6.7-paolo/arch/um/drivers/slirp_user.c | 15 - uml-linux-2.6.7-paolo/arch/um/drivers/ssl.c | 49 - uml-linux-2.6.7-paolo/arch/um/drivers/stdio_console.c | 54 - uml-linux-2.6.7-paolo/arch/um/drivers/tty.c | 4 - uml-linux-2.6.7-paolo/arch/um/drivers/ubd_kern.c | 600 ++++- - uml-linux-2.6.7-paolo/arch/um/drivers/ubd_user.c | 497 +--- - uml-linux-2.6.7-paolo/arch/um/drivers/xterm.c | 21 - uml-linux-2.6.7-paolo/arch/um/drivers/xterm_kern.c | 12 - uml-linux-2.6.7-paolo/arch/um/dyn.lds.S | 15 - uml-linux-2.6.7-paolo/arch/um/include/2_5compat.h | 14 - uml-linux-2.6.7-paolo/arch/um/include/irq_kern.h | 28 - uml-linux-2.6.7-paolo/arch/um/include/kern_util.h | 11 - uml-linux-2.6.7-paolo/arch/um/include/line.h | 4 - uml-linux-2.6.7-paolo/arch/um/include/mconsole.h | 6 - uml-linux-2.6.7-paolo/arch/um/include/mem.h | 15 - uml-linux-2.6.7-paolo/arch/um/include/mem_kern.h | 30 - uml-linux-2.6.7-paolo/arch/um/include/mem_user.h | 31 - uml-linux-2.6.7-paolo/arch/um/include/os.h | 53 - uml-linux-2.6.7-paolo/arch/um/include/signal_user.h | 2 - uml-linux-2.6.7-paolo/arch/um/include/skas_ptrace.h | 2 - uml-linux-2.6.7-paolo/arch/um/include/sysdep-i386/frame_user.h | 28 - uml-linux-2.6.7-paolo/arch/um/include/sysdep-i386/sigcontext.h | 4 - uml-linux-2.6.7-paolo/arch/um/include/sysdep-i386/syscalls.h | 59 - uml-linux-2.6.7-paolo/arch/um/include/ubd_user.h | 9 - uml-linux-2.6.7-paolo/arch/um/include/um_uaccess.h | 51 - uml-linux-2.6.7-paolo/arch/um/include/user.h | 1 - uml-linux-2.6.7-paolo/arch/um/include/user_util.h | 7 - uml-linux-2.6.7-paolo/arch/um/kernel/Makefile | 44 - uml-linux-2.6.7-paolo/arch/um/kernel/config.c.in | 4 - uml-linux-2.6.7-paolo/arch/um/kernel/exec_kern.c | 5 - uml-linux-2.6.7-paolo/arch/um/kernel/frame.c | 3 - uml-linux-2.6.7-paolo/arch/um/kernel/frame_kern.c | 6 - uml-linux-2.6.7-paolo/arch/um/kernel/helper.c | 55 - uml-linux-2.6.7-paolo/arch/um/kernel/init_task.c | 17 - uml-linux-2.6.7-paolo/arch/um/kernel/initrd_user.c | 13 - uml-linux-2.6.7-paolo/arch/um/kernel/irq.c | 105 - - uml-linux-2.6.7-paolo/arch/um/kernel/irq_user.c | 37 - uml-linux-2.6.7-paolo/arch/um/kernel/ksyms.c | 53 - uml-linux-2.6.7-paolo/arch/um/kernel/mem.c | 657 ------ - uml-linux-2.6.7-paolo/arch/um/kernel/mem_user.c | 230 +- - uml-linux-2.6.7-paolo/arch/um/kernel/physmem.c | 468 ++++ - uml-linux-2.6.7-paolo/arch/um/kernel/process.c | 20 - uml-linux-2.6.7-paolo/arch/um/kernel/process_kern.c | 45 - uml-linux-2.6.7-paolo/arch/um/kernel/ptrace.c | 23 - uml-linux-2.6.7-paolo/arch/um/kernel/reboot.c | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/sigio_kern.c | 7 - uml-linux-2.6.7-paolo/arch/um/kernel/sigio_user.c | 96 - uml-linux-2.6.7-paolo/arch/um/kernel/signal_kern.c | 60 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/Makefile | 24 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/mode.h | 6 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/skas.h | 4 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/uaccess.h | 207 -- - uml-linux-2.6.7-paolo/arch/um/kernel/skas/mem_user.c | 32 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/mmu.c | 8 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c | 107 - - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c | 26 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/sys-i386/Makefile | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/sys-i386/sigcontext.c | 15 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/syscall_kern.c | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/syscall_user.c | 4 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/trap_user.c | 6 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/uaccess.c | 219 ++ - uml-linux-2.6.7-paolo/arch/um/kernel/skas/util/Makefile | 7 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/util/mk_ptregs.c | 1 - uml-linux-2.6.7-paolo/arch/um/kernel/smp.c | 63 - uml-linux-2.6.7-paolo/arch/um/kernel/sys_call_table.c | 686 ++---- - uml-linux-2.6.7-paolo/arch/um/kernel/syscall_kern.c | 64 - uml-linux-2.6.7-paolo/arch/um/kernel/sysrq.c | 5 - uml-linux-2.6.7-paolo/arch/um/kernel/tempfile.c | 7 - uml-linux-2.6.7-paolo/arch/um/kernel/time.c | 69 - uml-linux-2.6.7-paolo/arch/um/kernel/time_kern.c | 77 - uml-linux-2.6.7-paolo/arch/um/kernel/trap_kern.c | 58 - uml-linux-2.6.7-paolo/arch/um/kernel/trap_user.c | 9 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/Makefile | 6 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/exec_kern.c | 7 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/include/mode.h | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/include/uaccess.h | 60 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/mem_user.c | 7 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/process_kern.c | 82 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/Makefile | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/proxy.c | 25 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/sysdep.c | 1 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/wait.c | 12 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/sys-i386/Makefile | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/syscall_kern.c | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/syscall_user.c | 4 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/tlb.c | 1 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/tracer.c | 27 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/uaccess.c | 73 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/uaccess_user.c | 22 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/unmap.c | 3 - uml-linux-2.6.7-paolo/arch/um/kernel/tty_log.c | 136 + - uml-linux-2.6.7-paolo/arch/um/kernel/uaccess_user.c | 2 - uml-linux-2.6.7-paolo/arch/um/kernel/um_arch.c | 76 - uml-linux-2.6.7-paolo/arch/um/kernel/umid.c | 80 - uml-linux-2.6.7-paolo/arch/um/kernel/user_util.c | 15 - uml-linux-2.6.7-paolo/arch/um/main.c | 7 - uml-linux-2.6.7-paolo/arch/um/os-Linux/Makefile | 6 - uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/ethertap_kern.c | 1 - uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/ethertap_user.c | 56 - uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/tuntap_user.c | 57 - uml-linux-2.6.7-paolo/arch/um/os-Linux/file.c | 450 +++- - uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c | 58 - uml-linux-2.6.7-paolo/arch/um/os-Linux/tty.c | 10 - uml-linux-2.6.7-paolo/arch/um/os-Linux/user_syms.c | 88 - uml-linux-2.6.7-paolo/arch/um/sys-i386/Makefile | 24 - uml-linux-2.6.7-paolo/arch/um/sys-i386/bugs.c | 140 + - uml-linux-2.6.7-paolo/arch/um/sys-i386/fault.c | 16 - uml-linux-2.6.7-paolo/arch/um/sys-i386/ptrace_user.c | 8 - uml-linux-2.6.7-paolo/arch/um/sys-i386/time.c | 24 - uml-linux-2.6.7-paolo/arch/um/sys-i386/util/Makefile | 15 - uml-linux-2.6.7-paolo/arch/um/sys-i386/util/mk_sc.c | 1 - uml-linux-2.6.7-paolo/arch/um/sys-ia64/Makefile | 15 - uml-linux-2.6.7-paolo/arch/um/sys-ppc/Makefile | 11 - uml-linux-2.6.7-paolo/arch/um/uml.lds.S | 10 - uml-linux-2.6.7-paolo/arch/um/util/Makefile | 27 - uml-linux-2.6.7-paolo/arch/um/util/mk_constants_kern.c | 4 - uml-linux-2.6.7-paolo/fs/Makefile | 2 - uml-linux-2.6.7-paolo/fs/hostfs/Makefile | 26 - uml-linux-2.6.7-paolo/fs/hostfs/hostfs.h | 79 - uml-linux-2.6.7-paolo/fs/hostfs/hostfs_kern.c | 1008 ++++++++++ - uml-linux-2.6.7-paolo/fs/hostfs/hostfs_user.c | 361 +++ - uml-linux-2.6.7-paolo/fs/hppfs/Makefile | 19 - uml-linux-2.6.7-paolo/fs/hppfs/hppfs_kern.c | 811 ++++++++ - uml-linux-2.6.7-paolo/include/asm-um/archparam-i386.h | 89 - uml-linux-2.6.7-paolo/include/asm-um/common.lds.S | 48 - uml-linux-2.6.7-paolo/include/asm-um/cpufeature.h | 6 - uml-linux-2.6.7-paolo/include/asm-um/current.h | 6 - uml-linux-2.6.7-paolo/include/asm-um/dma-mapping.h | 120 + - uml-linux-2.6.7-paolo/include/asm-um/elf.h | 13 - uml-linux-2.6.7-paolo/include/asm-um/fixmap.h | 8 - uml-linux-2.6.7-paolo/include/asm-um/irq.h | 18 - uml-linux-2.6.7-paolo/include/asm-um/local.h | 6 - uml-linux-2.6.7-paolo/include/asm-um/module-generic.h | 6 - uml-linux-2.6.7-paolo/include/asm-um/module-i386.h | 13 - uml-linux-2.6.7-paolo/include/asm-um/page.h | 43 - uml-linux-2.6.7-paolo/include/asm-um/pgtable.h | 111 - - uml-linux-2.6.7-paolo/include/asm-um/processor-generic.h | 43 - uml-linux-2.6.7-paolo/include/asm-um/processor-i386.h | 4 - uml-linux-2.6.7-paolo/include/asm-um/sections.h | 7 - uml-linux-2.6.7-paolo/include/asm-um/smp.h | 2 - uml-linux-2.6.7-paolo/include/asm-um/system-generic.h | 9 - uml-linux-2.6.7-paolo/include/asm-um/system-i386.h | 31 - uml-linux-2.6.7-paolo/include/asm-um/thread_info.h | 16 - uml-linux-2.6.7-paolo/include/asm-um/timex.h | 2 - uml-linux-2.6.7-paolo/include/asm-um/uaccess.h | 2 - uml-linux-2.6.7-paolo/include/asm-um/unistd.h | 5 - uml-linux-2.6.7-paolo/include/linux/gfp.h | 5 - uml-linux-2.6.7-paolo/include/linux/time.h | 2 - uml-linux-2.6.7-paolo/mm/page_alloc.c | 4 - uml-linux-2.6.7/arch/um/kernel/user_syms.c | 113 - - uml-linux-2.6.7/arch/um/sys-i386/extable.c | 30 - uml-linux-2.6.7/include/asm-um/smplock.h | 6 - uml-linux-2.6.7/include/asm-um/spinlock.h | 10 - 186 files changed, 8707 insertions(+), 3939 deletions(-) - -diff -puN arch/um/config.release~Main-uml-patch-no-skas arch/um/config.release ---- uml-linux-2.6.7/arch/um/config.release~Main-uml-patch-no-skas 2004-06-29 21:02:55.437331000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/config.release 2004-06-29 21:02:55.704290416 +0200 -@@ -228,7 +228,6 @@ CONFIG_ROMFS_FS=m - CONFIG_EXT2_FS=y - CONFIG_SYSV_FS=m - CONFIG_UDF_FS=m --# CONFIG_UDF_RW is not set - CONFIG_UFS_FS=m - # CONFIG_UFS_FS_WRITE is not set - -diff -puN arch/um/defconfig~Main-uml-patch-no-skas arch/um/defconfig ---- uml-linux-2.6.7/arch/um/defconfig~Main-uml-patch-no-skas 2004-06-29 21:02:55.438330848 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/defconfig 2004-06-29 21:02:55.705290264 +0200 -@@ -3,29 +3,19 @@ - # - CONFIG_USERMODE=y - CONFIG_MMU=y --CONFIG_SWAP=y - CONFIG_UID16=y - CONFIG_RWSEM_GENERIC_SPINLOCK=y --CONFIG_CONFIG_LOG_BUF_SHIFT=14 - - # --# Code maturity level options --# --CONFIG_EXPERIMENTAL=y -- --# --# General Setup -+# UML-specific options - # - CONFIG_MODE_TT=y - CONFIG_MODE_SKAS=y - CONFIG_NET=y --CONFIG_SYSVIPC=y --CONFIG_BSD_PROCESS_ACCT=y --CONFIG_SYSCTL=y --CONFIG_BINFMT_AOUT=y - CONFIG_BINFMT_ELF=y - CONFIG_BINFMT_MISC=y - CONFIG_HOSTFS=y -+CONFIG_HPPFS=y - CONFIG_MCONSOLE=y - CONFIG_MAGIC_SYSRQ=y - # CONFIG_HOST_2G_2G is not set -@@ -36,12 +26,43 @@ CONFIG_KERNEL_HALF_GIGS=1 - # CONFIG_HIGHMEM is not set - CONFIG_PROC_MM=y - CONFIG_KERNEL_STACK_ORDER=2 -+CONFIG_UML_REAL_TIME_CLOCK=y -+ -+# -+# Code maturity level options -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_CLEAN_COMPILE=y -+CONFIG_STANDALONE=y -+CONFIG_BROKEN_ON_SMP=y -+ -+# -+# General setup -+# -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_SYSCTL=y -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_HOTPLUG is not set -+# CONFIG_IKCONFIG is not set -+# CONFIG_EMBEDDED is not set -+CONFIG_KALLSYMS=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set - - # - # Loadable module support - # --CONFIG_MODULES=y --# CONFIG_KMOD is not set -+# CONFIG_MODULES is not set -+ -+# -+# Generic Driver Options -+# - - # - # Character Devices -@@ -69,6 +90,7 @@ CONFIG_HOSTAUDIO=y - # - CONFIG_BLK_DEV_UBD=y - # CONFIG_BLK_DEV_UBD_SYNC is not set -+CONFIG_BLK_DEV_COW_COMMON=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_NBD=y - CONFIG_BLK_DEV_RAM=y -@@ -78,7 +100,7 @@ CONFIG_BLK_DEV_INITRD=y - CONFIG_NETDEVICES=y - - # --# Network Devices -+# UML Network Devices - # - CONFIG_UML_NET=y - CONFIG_UML_NET_ETHERTAP=y -@@ -88,22 +110,6 @@ CONFIG_UML_NET_DAEMON=y - CONFIG_UML_NET_MCAST=y - # CONFIG_UML_NET_PCAP is not set - CONFIG_UML_NET_SLIRP=y --CONFIG_DUMMY=y --# CONFIG_BONDING is not set --# CONFIG_EQUALIZER is not set --CONFIG_TUN=y --# CONFIG_ETHERTAP is not set --CONFIG_PPP=y --# CONFIG_PPP_MULTILINK is not set --# CONFIG_PPP_ASYNC is not set --# CONFIG_PPP_SYNC_TTY is not set --# CONFIG_PPP_DEFLATE is not set --# CONFIG_PPP_BSDCOMP is not set --# CONFIG_PPPOE is not set --CONFIG_SLIP=y --# CONFIG_SLIP_COMPRESSED is not set --# CONFIG_SLIP_SMART is not set --# CONFIG_SLIP_MODE_SLIP6 is not set - - # - # Networking support -@@ -115,8 +121,6 @@ CONFIG_SLIP=y - CONFIG_PACKET=y - CONFIG_PACKET_MMAP=y - # CONFIG_NETLINK_DEV is not set --# CONFIG_NETFILTER is not set --# CONFIG_FILTER is not set - CONFIG_UNIX=y - # CONFIG_NET_KEY is not set - CONFIG_INET=y -@@ -130,8 +134,11 @@ CONFIG_INET=y - # CONFIG_SYN_COOKIES is not set - # CONFIG_INET_AH is not set - # CONFIG_INET_ESP is not set --# CONFIG_XFRM_USER is not set -+# CONFIG_INET_IPCOMP is not set - # CONFIG_IPV6 is not set -+# CONFIG_DECNET is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_NETFILTER is not set - - # - # SCTP Configuration (EXPERIMENTAL) -@@ -140,9 +147,9 @@ CONFIG_IPV6_SCTP__=y - # CONFIG_IP_SCTP is not set - # CONFIG_ATM is not set - # CONFIG_VLAN_8021Q is not set --# CONFIG_LLC is not set --# CONFIG_DECNET is not set --# CONFIG_BRIDGE is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set - # CONFIG_X25 is not set - # CONFIG_LAPB is not set - # CONFIG_NET_DIVERT is not set -@@ -160,6 +167,10 @@ CONFIG_IPV6_SCTP__=y - # Network testing - # - # CONFIG_NET_PKTGEN is not set -+CONFIG_DUMMY=y -+# CONFIG_BONDING is not set -+# CONFIG_EQUALIZER is not set -+CONFIG_TUN=y - - # - # Ethernet (10 or 100Mbit) -@@ -171,12 +182,28 @@ CONFIG_IPV6_SCTP__=y - # - - # -+# Ethernet (10000 Mbit) -+# -+CONFIG_PPP=y -+# CONFIG_PPP_MULTILINK is not set -+# CONFIG_PPP_FILTER is not set -+# CONFIG_PPP_ASYNC is not set -+# CONFIG_PPP_SYNC_TTY is not set -+# CONFIG_PPP_DEFLATE is not set -+# CONFIG_PPP_BSDCOMP is not set -+# CONFIG_PPPOE is not set -+CONFIG_SLIP=y -+# CONFIG_SLIP_COMPRESSED is not set -+# CONFIG_SLIP_SMART is not set -+# CONFIG_SLIP_MODE_SLIP6 is not set -+ -+# - # Wireless LAN (non-hamradio) - # - # CONFIG_NET_RADIO is not set - - # --# Token Ring devices (depends on LLC=y) -+# Token Ring devices - # - # CONFIG_SHAPER is not set - -@@ -186,68 +213,100 @@ CONFIG_IPV6_SCTP__=y - # CONFIG_WAN is not set - - # -+# Amateur Radio support -+# -+# CONFIG_HAMRADIO is not set -+ -+# -+# IrDA (infrared) support -+# -+# CONFIG_IRDA is not set -+ -+# -+# Bluetooth support -+# -+# CONFIG_BT is not set -+ -+# - # File systems - # -+CONFIG_EXT2_FS=y -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_JBD is not set -+CONFIG_REISERFS_FS=y -+# CONFIG_REISERFS_CHECK is not set -+# CONFIG_REISERFS_PROC_INFO is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+CONFIG_MINIX_FS=y -+# CONFIG_ROMFS_FS is not set - CONFIG_QUOTA=y - # CONFIG_QFMT_V1 is not set - # CONFIG_QFMT_V2 is not set - CONFIG_QUOTACTL=y --CONFIG_AUTOFS_FS=m --CONFIG_AUTOFS4_FS=m --CONFIG_REISERFS_FS=m --# CONFIG_REISERFS_CHECK is not set --# CONFIG_REISERFS_PROC_INFO is not set -+CONFIG_AUTOFS_FS=y -+CONFIG_AUTOFS4_FS=y -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_DEVFS_FS=y -+CONFIG_DEVFS_MOUNT=y -+# CONFIG_DEVFS_DEBUG is not set -+# CONFIG_DEVPTS_FS_XATTR is not set -+CONFIG_TMPFS=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_RAMFS=y -+ -+# -+# Miscellaneous filesystems -+# - # CONFIG_ADFS_FS is not set - # CONFIG_AFFS_FS is not set - # CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set - # CONFIG_BEFS_FS is not set - # CONFIG_BFS_FS is not set --# CONFIG_EXT3_FS is not set --# CONFIG_JBD is not set --CONFIG_FAT_FS=m --CONFIG_MSDOS_FS=m --CONFIG_VFAT_FS=m - # CONFIG_EFS_FS is not set - CONFIG_JFFS_FS=y - CONFIG_JFFS_FS_VERBOSE=0 --CONFIG_JFFS_PROC_FS=y - # CONFIG_JFFS2_FS is not set - # CONFIG_CRAMFS is not set --# CONFIG_TMPFS is not set --CONFIG_RAMFS=y --CONFIG_ISO9660_FS=m --# CONFIG_JOLIET is not set --# CONFIG_ZISOFS is not set --# CONFIG_JFS_FS is not set --CONFIG_MINIX_FS=m - # CONFIG_VXFS_FS is not set --# CONFIG_NTFS_FS is not set - # CONFIG_HPFS_FS is not set --CONFIG_PROC_FS=y --CONFIG_DEVFS_FS=y --CONFIG_DEVFS_MOUNT=y --# CONFIG_DEVFS_DEBUG is not set --CONFIG_DEVPTS_FS=y - # CONFIG_QNX4FS_FS is not set --# CONFIG_ROMFS_FS is not set --CONFIG_EXT2_FS=y --# CONFIG_EXT2_FS_XATTR is not set - # CONFIG_SYSV_FS is not set --# CONFIG_UDF_FS is not set - # CONFIG_UFS_FS is not set --# CONFIG_XFS_FS is not set - - # - # Network File Systems - # --# CONFIG_CODA_FS is not set --# CONFIG_INTERMEZZO_FS is not set - # CONFIG_NFS_FS is not set - # CONFIG_NFSD is not set - # CONFIG_EXPORTFS is not set --# CONFIG_CIFS is not set - # CONFIG_SMB_FS is not set -+# CONFIG_CIFS is not set - # CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set - # CONFIG_AFS_FS is not set - - # -@@ -255,11 +314,11 @@ CONFIG_EXT2_FS=y - # - # CONFIG_PARTITION_ADVANCED is not set - CONFIG_MSDOS_PARTITION=y --CONFIG_NLS=y - - # - # Native Language Support - # -+CONFIG_NLS=y - CONFIG_NLS_DEFAULT="iso8859-1" - # CONFIG_NLS_CODEPAGE_437 is not set - # CONFIG_NLS_CODEPAGE_737 is not set -@@ -317,28 +376,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" - # - # SCSI support - # --CONFIG_SCSI=y --CONFIG_GENERIC_ISA_DMA=y -- --# --# SCSI support type (disk, tape, CD-ROM) --# --CONFIG_BLK_DEV_SD=y --CONFIG_SD_EXTRA_DEVS=40 --CONFIG_CHR_DEV_ST=y --CONFIG_BLK_DEV_SR=y --CONFIG_BLK_DEV_SR_VENDOR=y --CONFIG_SR_EXTRA_DEVS=2 --CONFIG_CHR_DEV_SG=y -- --# --# Some SCSI devices (e.g. CD jukebox) support multiple LUNs --# --CONFIG_SCSI_DEBUG_QUEUES=y --CONFIG_SCSI_MULTI_LUN=y --CONFIG_SCSI_CONSTANTS=y --CONFIG_SCSI_LOGGING=y --CONFIG_SCSI_DEBUG=y -+# CONFIG_SCSI is not set - - # - # Multi-device support (RAID and LVM) -@@ -360,6 +398,7 @@ CONFIG_MTD_CHAR=y - CONFIG_MTD_BLOCK=y - # CONFIG_FTL is not set - # CONFIG_NFTL is not set -+# CONFIG_INFTL is not set - - # - # RAM/ROM/Flash chip drivers -@@ -374,20 +413,21 @@ CONFIG_MTD_BLOCK=y - # - # Mapping drivers for chip access - # -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set - - # - # Self-contained MTD device drivers - # - # CONFIG_MTD_SLRAM is not set - # CONFIG_MTD_MTDRAM is not set --CONFIG_MTD_BLKMTD=m -+CONFIG_MTD_BLKMTD=y - - # - # Disk-On-Chip Device Drivers - # --# CONFIG_MTD_DOC1000 is not set - # CONFIG_MTD_DOC2000 is not set - # CONFIG_MTD_DOC2001 is not set -+# CONFIG_MTD_DOC2001PLUS is not set - - # - # NAND Flash Device Drivers -diff -puN arch/um/drivers/chan_kern.c~Main-uml-patch-no-skas arch/um/drivers/chan_kern.c ---- uml-linux-2.6.7/arch/um/drivers/chan_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.440330544 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/chan_kern.c 2004-06-29 21:02:55.705290264 +0200 -@@ -8,6 +8,7 @@ - #include <linux/list.h> - #include <linux/slab.h> - #include <linux/tty.h> -+#include <linux/string.h> - #include <linux/tty_flip.h> - #include <asm/irq.h> - #include "chan_kern.h" -@@ -265,6 +266,11 @@ static int one_chan_config_string(struct - { - int n = 0; - -+ if(chan == NULL){ -+ CONFIG_CHUNK(str, size, n, "none", 1); -+ return(n); -+ } -+ - CONFIG_CHUNK(str, size, n, chan->ops->type, 0); - - if(chan->dev == NULL){ -@@ -420,7 +426,8 @@ int parse_chan_pair(char *str, struct li - INIT_LIST_HEAD(chans); - } - -- if((out = strchr(str, ',')) != NULL){ -+ out = strchr(str, ','); -+ if(out != NULL){ - in = str; - *out = '\0'; - out++; -@@ -475,12 +482,15 @@ void chan_interrupt(struct list_head *ch - goto out; - } - err = chan->ops->read(chan->fd, &c, chan->data); -- if(err > 0) tty_receive_char(tty, c); -+ if(err > 0) -+ tty_receive_char(tty, c); - } while(err > 0); -+ - if(err == 0) reactivate_fd(chan->fd, irq); - if(err == -EIO){ - if(chan->primary){ -- if(tty != NULL) tty_hangup(tty); -+ if(tty != NULL) -+ tty_hangup(tty); - line_disable(dev, irq); - close_chan(chans); - free_chan(chans); -diff -puN arch/um/drivers/chan_user.c~Main-uml-patch-no-skas arch/um/drivers/chan_user.c ---- uml-linux-2.6.7/arch/um/drivers/chan_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.441330392 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/chan_user.c 2004-06-29 21:02:55.706290112 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -7,7 +7,6 @@ - #include <stdlib.h> - #include <errno.h> - #include <termios.h> --#include <fcntl.h> - #include <string.h> - #include <signal.h> - #include <sys/stat.h> -@@ -24,29 +23,27 @@ - - void generic_close(int fd, void *unused) - { -- close(fd); -+ os_close_file(fd); - } - - int generic_read(int fd, char *c_out, void *unused) - { - int n; - -- n = read(fd, c_out, sizeof(*c_out)); -- if(n < 0){ -- if(errno == EAGAIN) return(0); -- return(-errno); -- } -- else if(n == 0) return(-EIO); -- return(1); -+ n = os_read_file(fd, c_out, sizeof(*c_out)); -+ -+ if(n == -EAGAIN) -+ return(0); -+ else if(n == 0) -+ return(-EIO); -+ return(n); - } - -+/* XXX Trivial wrapper around os_write_file */ -+ - int generic_write(int fd, const char *buf, int n, void *unused) - { -- int count; -- -- count = write(fd, buf, n); -- if(count < 0) return(-errno); -- return(count); -+ return(os_write_file(fd, buf, n)); - } - - int generic_console_write(int fd, const char *buf, int n, void *unused) -@@ -68,15 +65,18 @@ int generic_console_write(int fd, const - int generic_window_size(int fd, void *unused, unsigned short *rows_out, - unsigned short *cols_out) - { -- struct winsize size; -- int ret = 0; -+ int rows, cols; -+ int ret; -+ -+ ret = os_window_size(fd, &rows, &cols); -+ if(ret < 0) -+ return(ret); -+ -+ ret = ((*rows_out != rows) || (*cols_out != cols)); -+ -+ *rows_out = rows; -+ *cols_out = cols; - -- if(ioctl(fd, TIOCGWINSZ, &size) == 0){ -- ret = ((*rows_out != size.ws_row) || -- (*cols_out != size.ws_col)); -- *rows_out = size.ws_row; -- *cols_out = size.ws_col; -- } - return(ret); - } - -@@ -100,14 +100,16 @@ static int winch_thread(void *arg) - struct winch_data *data = arg; - sigset_t sigs; - int pty_fd, pipe_fd; -+ int count, err; - char c = 1; - -- close(data->close_me); -+ os_close_file(data->close_me); - pty_fd = data->pty_fd; - pipe_fd = data->pipe_fd; -- if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)) -+ count = os_write_file(pipe_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) - printk("winch_thread : failed to write synchronization " -- "byte, errno = %d\n", errno); -+ "byte, err = %d\n", -count); - - signal(SIGWINCH, winch_handler); - sigfillset(&sigs); -@@ -123,26 +125,24 @@ static int winch_thread(void *arg) - exit(1); - } - -- if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){ -- printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno); -- exit(1); -- } -- if(tcsetpgrp(pty_fd, os_getpid()) < 0){ -- printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno); -+ err = os_new_tty_pgrp(pty_fd, os_getpid()); -+ if(err < 0){ -+ printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err); - exit(1); - } - -- if(read(pipe_fd, &c, sizeof(c)) != sizeof(c)) -+ count = os_read_file(pipe_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) - printk("winch_thread : failed to read synchronization byte, " -- "errno = %d\n", errno); -+ "err = %d\n", -count); - - while(1){ - pause(); - -- if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){ -- printk("winch_thread : write failed, errno = %d\n", -- errno); -- } -+ count = os_write_file(pipe_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) -+ printk("winch_thread : write failed, err = %d\n", -+ -count); - } - } - -@@ -154,8 +154,8 @@ static int winch_tramp(int fd, void *dev - char c; - - err = os_pipe(fds, 1, 1); -- if(err){ -- printk("winch_tramp : os_pipe failed, errno = %d\n", -err); -+ if(err < 0){ -+ printk("winch_tramp : os_pipe failed, err = %d\n", -err); - return(err); - } - -@@ -168,12 +168,12 @@ static int winch_tramp(int fd, void *dev - return(pid); - } - -- close(fds[1]); -+ os_close_file(fds[1]); - *fd_out = fds[0]; -- n = read(fds[0], &c, sizeof(c)); -+ n = os_read_file(fds[0], &c, sizeof(c)); - if(n != sizeof(c)){ - printk("winch_tramp : failed to read synchronization byte\n"); -- printk("read returned %d, errno = %d\n", n, errno); -+ printk("read failed, err = %d\n", -n); - printk("fd %d will not support SIGWINCH\n", fd); - *fd_out = -1; - } -@@ -183,20 +183,24 @@ static int winch_tramp(int fd, void *dev - void register_winch(int fd, void *device_data) - { - int pid, thread, thread_fd; -+ int count; - char c = 1; - -- if(!isatty(fd)) return; -+ if(!isatty(fd)) -+ return; - - pid = tcgetpgrp(fd); -- if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && -- (pid == -1)){ -+ if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, -+ device_data) && (pid == -1)){ - thread = winch_tramp(fd, device_data, &thread_fd); - if(fd != -1){ - register_winch_irq(thread_fd, fd, thread, device_data); - -- if(write(thread_fd, &c, sizeof(c)) != sizeof(c)) -+ count = os_write_file(thread_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) - printk("register_winch : failed to write " -- "synchronization byte\n"); -+ "synchronization byte, err = %d\n", -+ -count); - } - } - } -diff -puN /dev/null arch/um/drivers/cow.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/cow.h 2004-06-29 21:02:55.706290112 +0200 -@@ -0,0 +1,41 @@ -+#ifndef __COW_H__ -+#define __COW_H__ -+ -+#include <asm/types.h> -+ -+#if __BYTE_ORDER == __BIG_ENDIAN -+# define ntohll(x) (x) -+# define htonll(x) (x) -+#elif __BYTE_ORDER == __LITTLE_ENDIAN -+# define ntohll(x) bswap_64(x) -+# define htonll(x) bswap_64(x) -+#else -+#error "__BYTE_ORDER not defined" -+#endif -+ -+extern int init_cow_file(int fd, char *cow_file, char *backing_file, -+ int sectorsize, int alignment, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, int *data_offset_out); -+ -+extern int file_reader(__u64 offset, char *buf, int len, void *arg); -+extern int read_cow_header(int (*reader)(__u64, char *, int, void *), -+ void *arg, __u32 *version_out, -+ char **backing_file_out, time_t *mtime_out, -+ __u64 *size_out, int *sectorsize_out, -+ __u32 *align_out, int *bitmap_offset_out); -+ -+extern int write_cow_header(char *cow_file, int fd, char *backing_file, -+ int sectorsize, int alignment, long long *size); -+ -+extern void cow_sizes(int version, __u64 size, int sectorsize, int align, -+ int bitmap_offset, unsigned long *bitmap_len_out, -+ int *data_offset_out); -+ -+#endif -+ -+/* -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -puN /dev/null arch/um/drivers/cow_kern.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/cow_kern.c 2004-06-29 21:02:55.707289960 +0200 -@@ -0,0 +1,630 @@ -+#define COW_MAJOR 60 -+#define MAJOR_NR COW_MAJOR -+ -+#include <linux/stddef.h> -+#include <linux/kernel.h> -+#include <linux/ctype.h> -+#include <linux/stat.h> -+#include <linux/vmalloc.h> -+#include <linux/blkdev.h> -+#include <linux/blk.h> -+#include <linux/fs.h> -+#include <linux/genhd.h> -+#include <linux/devfs_fs.h> -+#include <asm/uaccess.h> -+#include "2_5compat.h" -+#include "cow.h" -+#include "ubd_user.h" -+ -+#define COW_SHIFT 4 -+ -+struct cow { -+ int count; -+ char *cow_path; -+ dev_t cow_dev; -+ struct block_device *cow_bdev; -+ char *backing_path; -+ dev_t backing_dev; -+ struct block_device *backing_bdev; -+ int sectorsize; -+ unsigned long *bitmap; -+ unsigned long bitmap_len; -+ int bitmap_offset; -+ int data_offset; -+ devfs_handle_t devfs; -+ struct semaphore sem; -+ struct semaphore io_sem; -+ atomic_t working; -+ spinlock_t io_lock; -+ struct buffer_head *bh; -+ struct buffer_head *bhtail; -+ void *end_io; -+}; -+ -+#define DEFAULT_COW { \ -+ .count = 0, \ -+ .cow_path = NULL, \ -+ .cow_dev = 0, \ -+ .backing_path = NULL, \ -+ .backing_dev = 0, \ -+ .bitmap = NULL, \ -+ .bitmap_len = 0, \ -+ .bitmap_offset = 0, \ -+ .data_offset = 0, \ -+ .devfs = NULL, \ -+ .working = ATOMIC_INIT(0), \ -+ .io_lock = SPIN_LOCK_UNLOCKED, \ -+} -+ -+#define MAX_DEV (8) -+#define MAX_MINOR (MAX_DEV << COW_SHIFT) -+ -+struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW }; -+ -+/* Not modified by this driver */ -+static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE }; -+static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 }; -+ -+/* Protected by cow_lock */ -+static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 }; -+ -+static struct hd_struct cow_part[MAX_MINOR] = -+ { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } }; -+ -+/* Protected by io_request_lock */ -+static request_queue_t *cow_queue; -+ -+static int cow_open(struct inode *inode, struct file *filp); -+static int cow_release(struct inode * inode, struct file * file); -+static int cow_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg); -+static int cow_revalidate(kdev_t rdev); -+ -+static struct block_device_operations cow_blops = { -+ .open = cow_open, -+ .release = cow_release, -+ .ioctl = cow_ioctl, -+ .revalidate = cow_revalidate, -+}; -+ -+/* Initialized in an initcall, and unchanged thereafter */ -+devfs_handle_t cow_dir_handle; -+ -+#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \ -+{ \ -+ .major = maj, \ -+ .major_name = name, \ -+ .minor_shift = shift, \ -+ .max_p = 1 << shift, \ -+ .part = parts, \ -+ .sizes = bsizes, \ -+ .nr_real = max, \ -+ .real_devices = NULL, \ -+ .next = NULL, \ -+ .fops = blops, \ -+ .de_arr = NULL, \ -+ .flags = 0 \ -+} -+ -+static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED; -+ -+static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part, -+ COW_SHIFT, sizes, MAX_DEV, -+ &cow_blops); -+ -+static int cow_add(int n) -+{ -+ struct cow *dev = &cow_dev[n]; -+ char name[sizeof("nnnnnn\0")]; -+ int err = -ENODEV; -+ -+ if(dev->cow_path == NULL) -+ goto out; -+ -+ sprintf(name, "%d", n); -+ dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE, -+ MAJOR_NR, n << COW_SHIFT, S_IFBLK | -+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, -+ &cow_blops, NULL); -+ -+ init_MUTEX_LOCKED(&dev->sem); -+ init_MUTEX(&dev->io_sem); -+ -+ return(0); -+ -+ out: -+ return(err); -+} -+ -+/* -+ * Add buffer_head to back of pending list -+ */ -+static void cow_add_bh(struct cow *cow, struct buffer_head *bh) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&cow->io_lock, flags); -+ if(cow->bhtail != NULL){ -+ cow->bhtail->b_reqnext = bh; -+ cow->bhtail = bh; -+ } -+ else { -+ cow->bh = bh; -+ cow->bhtail = bh; -+ } -+ spin_unlock_irqrestore(&cow->io_lock, flags); -+} -+ -+/* -+* Grab first pending buffer -+*/ -+static struct buffer_head *cow_get_bh(struct cow *cow) -+{ -+ struct buffer_head *bh; -+ -+ spin_lock_irq(&cow->io_lock); -+ bh = cow->bh; -+ if(bh != NULL){ -+ if(bh == cow->bhtail) -+ cow->bhtail = NULL; -+ cow->bh = bh->b_reqnext; -+ bh->b_reqnext = NULL; -+ } -+ spin_unlock_irq(&cow->io_lock); -+ -+ return(bh); -+} -+ -+static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, -+ struct buffer_head **cow_bh, int ncow_bh) -+{ -+ int i; -+ -+ if(ncow_bh > 0) -+ ll_rw_block(WRITE, ncow_bh, cow_bh); -+ -+ for(i = 0; i < ncow_bh ; i++){ -+ wait_on_buffer(cow_bh[i]); -+ brelse(cow_bh[i]); -+ } -+ -+ ll_rw_block(WRITE, 1, &bh); -+ brelse(bh); -+} -+ -+static struct buffer_head *cow_new_bh(struct cow *dev, int sector) -+{ -+ struct buffer_head *bh; -+ -+ sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize; -+ bh = getblk(dev->cow_dev, sector, dev->sectorsize); -+ memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])), -+ dev->sectorsize); -+ return(bh); -+} -+ -+/* Copied from loop.c, needed to avoid deadlocking in make_request. */ -+ -+static int cow_thread(void *data) -+{ -+ struct cow *dev = data; -+ struct buffer_head *bh; -+ -+ daemonize(); -+ exit_files(current); -+ -+ sprintf(current->comm, "cow%d", dev - cow_dev); -+ -+ spin_lock_irq(¤t->sigmask_lock); -+ sigfillset(¤t->blocked); -+ flush_signals(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ -+ atomic_inc(&dev->working); -+ -+ current->policy = SCHED_OTHER; -+ current->nice = -20; -+ -+ current->flags |= PF_NOIO; -+ -+ /* -+ * up sem, we are running -+ */ -+ up(&dev->sem); -+ -+ for(;;){ -+ int start, len, nbh, i, update_bitmap = 0; -+ struct buffer_head *cow_bh[2]; -+ -+ down_interruptible(&dev->io_sem); -+ /* -+ * could be upped because of tear-down, not because of -+ * pending work -+ */ -+ if(!atomic_read(&dev->working)) -+ break; -+ -+ bh = cow_get_bh(dev); -+ if(bh == NULL){ -+ printk(KERN_ERR "cow: missing bh\n"); -+ continue; -+ } -+ -+ start = bh->b_blocknr * bh->b_size / dev->sectorsize; -+ len = bh->b_size / dev->sectorsize; -+ for(i = 0; i < len ; i++){ -+ if(ubd_test_bit(start + i, -+ (unsigned char *) dev->bitmap)) -+ continue; -+ -+ update_bitmap = 1; -+ ubd_set_bit(start + i, (unsigned char *) dev->bitmap); -+ } -+ -+ cow_bh[0] = NULL; -+ cow_bh[1] = NULL; -+ nbh = 0; -+ if(update_bitmap){ -+ cow_bh[0] = cow_new_bh(dev, start); -+ nbh++; -+ if(start / dev->sectorsize != -+ (start + len) / dev->sectorsize){ -+ cow_bh[1] = cow_new_bh(dev, start + len); -+ nbh++; -+ } -+ } -+ -+ bh->b_dev = dev->cow_dev; -+ bh->b_blocknr += dev->data_offset / dev->sectorsize; -+ -+ cow_handle_bh(dev, bh, cow_bh, nbh); -+ -+ /* -+ * upped both for pending work and tear-down, lo_pending -+ * will hit zero then -+ */ -+ if(atomic_dec_and_test(&dev->working)) -+ break; -+ } -+ -+ up(&dev->sem); -+ return(0); -+} -+ -+static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh) -+{ -+ struct cow *dev; -+ int n, minor; -+ -+ minor = MINOR(bh->b_rdev); -+ n = minor >> COW_SHIFT; -+ dev = &cow_dev[n]; -+ -+ dev->end_io = NULL; -+ if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){ -+ bh->b_rdev = dev->cow_dev; -+ bh->b_rsector += dev->data_offset / dev->sectorsize; -+ } -+ else if(rw == WRITE){ -+ bh->b_dev = dev->cow_dev; -+ bh->b_blocknr += dev->data_offset / dev->sectorsize; -+ -+ cow_add_bh(dev, bh); -+ up(&dev->io_sem); -+ return(0); -+ } -+ else { -+ bh->b_rdev = dev->backing_dev; -+ } -+ -+ return(1); -+} -+ -+int cow_init(void) -+{ -+ int i; -+ -+ cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL); -+ if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) { -+ printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR); -+ return -1; -+ } -+ read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */ -+ blksize_size[MAJOR_NR] = blk_sizes; -+ blk_size[MAJOR_NR] = sizes; -+ INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes); -+ -+ cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR); -+ blk_init_queue(cow_queue, NULL); -+ INIT_ELV(cow_queue, &cow_queue->elevator); -+ blk_queue_make_request(cow_queue, cow_make_request); -+ -+ add_gendisk(&cow_gendisk); -+ -+ for(i=0;i<MAX_DEV;i++) -+ cow_add(i); -+ -+ return(0); -+} -+ -+__initcall(cow_init); -+ -+static int reader(__u64 start, char *buf, int count, void *arg) -+{ -+ dev_t dev = *((dev_t *) arg); -+ struct buffer_head *bh; -+ __u64 block; -+ int cur, offset, left, n, blocksize = get_hardsect_size(dev); -+ -+ if(blocksize == 0) -+ panic("Zero blocksize"); -+ -+ block = start / blocksize; -+ offset = start % blocksize; -+ left = count; -+ cur = 0; -+ while(left > 0){ -+ n = (left > blocksize) ? blocksize : left; -+ -+ bh = bread(dev, block, (n < 512) ? 512 : n); -+ if(bh == NULL) -+ return(-EIO); -+ -+ n -= offset; -+ memcpy(&buf[cur], bh->b_data + offset, n); -+ block++; -+ left -= n; -+ cur += n; -+ offset = 0; -+ brelse(bh); -+ } -+ -+ return(count); -+} -+ -+static int cow_open(struct inode *inode, struct file *filp) -+{ -+ int (*dev_ioctl)(struct inode *, struct file *, unsigned int, -+ unsigned long); -+ mm_segment_t fs; -+ struct cow *dev; -+ __u64 size; -+ __u32 version, align; -+ time_t mtime; -+ char *backing_file; -+ int n, offset, err = 0; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ if(n >= MAX_DEV) -+ return(-ENODEV); -+ dev = &cow_dev[n]; -+ offset = n << COW_SHIFT; -+ -+ spin_lock(&cow_lock); -+ -+ if(dev->count == 0){ -+ dev->cow_dev = name_to_kdev_t(dev->cow_path); -+ if(dev->cow_dev == 0){ -+ printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " -+ "failed\n", dev->cow_path); -+ err = -ENODEV; -+ } -+ -+ dev->backing_dev = name_to_kdev_t(dev->backing_path); -+ if(dev->backing_dev == 0){ -+ printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " -+ "failed\n", dev->backing_path); -+ err = -ENODEV; -+ } -+ -+ if(err) -+ goto out; -+ -+ dev->cow_bdev = bdget(dev->cow_dev); -+ if(dev->cow_bdev == NULL){ -+ printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", -+ dev->cow_path); -+ err = -ENOMEM; -+ } -+ dev->backing_bdev = bdget(dev->backing_dev); -+ if(dev->backing_bdev == NULL){ -+ printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", -+ dev->backing_path); -+ err = -ENOMEM; -+ } -+ -+ if(err) -+ goto out; -+ -+ err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, -+ BDEV_RAW); -+ if(err){ -+ printk("cow_open - blkdev_get of COW device failed, " -+ "error = %d\n", err); -+ goto out; -+ } -+ -+ err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW); -+ if(err){ -+ printk("cow_open - blkdev_get of backing device " -+ "failed, error = %d\n", err); -+ goto out; -+ } -+ -+ err = read_cow_header(reader, &dev->cow_dev, &version, -+ &backing_file, &mtime, &size, -+ &dev->sectorsize, &align, -+ &dev->bitmap_offset); -+ if(err){ -+ printk(KERN_ERR "cow_open - read_cow_header failed, " -+ "err = %d\n", err); -+ goto out; -+ } -+ -+ cow_sizes(version, size, dev->sectorsize, align, -+ dev->bitmap_offset, &dev->bitmap_len, -+ &dev->data_offset); -+ dev->bitmap = (void *) vmalloc(dev->bitmap_len); -+ if(dev->bitmap == NULL){ -+ err = -ENOMEM; -+ printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); -+ goto out; -+ } -+ flush_tlb_kernel_vm(); -+ -+ err = reader(dev->bitmap_offset, (char *) dev->bitmap, -+ dev->bitmap_len, &dev->cow_dev); -+ if(err < 0){ -+ printk(KERN_ERR "Failed to read COW bitmap\n"); -+ vfree(dev->bitmap); -+ goto out; -+ } -+ -+ dev_ioctl = dev->backing_bdev->bd_op->ioctl; -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = (*dev_ioctl)(inode, filp, BLKGETSIZE, -+ (unsigned long) &sizes[offset]); -+ set_fs(fs); -+ if(err){ -+ printk(KERN_ERR "cow_open - BLKGETSIZE failed, " -+ "error = %d\n", err); -+ goto out; -+ } -+ -+ kernel_thread(cow_thread, dev, -+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND); -+ down(&dev->sem); -+ } -+ dev->count++; -+ out: -+ spin_unlock(&cow_lock); -+ return(err); -+} -+ -+static int cow_release(struct inode * inode, struct file * file) -+{ -+ struct cow *dev; -+ int n, err; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ if(n >= MAX_DEV) -+ return(-ENODEV); -+ dev = &cow_dev[n]; -+ -+ spin_lock(&cow_lock); -+ -+ if(--dev->count > 0) -+ goto out; -+ -+ err = blkdev_put(dev->cow_bdev, BDEV_RAW); -+ if(err) -+ printk("cow_release - blkdev_put of cow device failed, " -+ "error = %d\n", err); -+ bdput(dev->cow_bdev); -+ dev->cow_bdev = 0; -+ -+ err = blkdev_put(dev->backing_bdev, BDEV_RAW); -+ if(err) -+ printk("cow_release - blkdev_put of backing device failed, " -+ "error = %d\n", err); -+ bdput(dev->backing_bdev); -+ dev->backing_bdev = 0; -+ -+ out: -+ spin_unlock(&cow_lock); -+ return(0); -+} -+ -+static int cow_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct cow *dev; -+ int (*dev_ioctl)(struct inode *, struct file *, unsigned int, -+ unsigned long); -+ int n; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ if(n >= MAX_DEV) -+ return(-ENODEV); -+ dev = &cow_dev[n]; -+ -+ dev_ioctl = dev->backing_bdev->bd_op->ioctl; -+ return((*dev_ioctl)(inode, file, cmd, arg)); -+} -+ -+static int cow_revalidate(kdev_t rdev) -+{ -+ printk(KERN_ERR "Need to implement cow_revalidate\n"); -+ return(0); -+} -+ -+static int parse_unit(char **ptr) -+{ -+ char *str = *ptr, *end; -+ int n = -1; -+ -+ if(isdigit(*str)) { -+ n = simple_strtoul(str, &end, 0); -+ if(end == str) -+ return(-1); -+ *ptr = end; -+ } -+ else if (('a' <= *str) && (*str <= 'h')) { -+ n = *str - 'a'; -+ str++; -+ *ptr = str; -+ } -+ return(n); -+} -+ -+static int cow_setup(char *str) -+{ -+ struct cow *dev; -+ char *cow_name, *backing_name; -+ int unit; -+ -+ unit = parse_unit(&str); -+ if(unit < 0){ -+ printk(KERN_ERR "cow_setup - Couldn't parse unit number\n"); -+ return(1); -+ } -+ -+ if(*str != '='){ -+ printk(KERN_ERR "cow_setup - Missing '=' after unit " -+ "number\n"); -+ return(1); -+ } -+ str++; -+ -+ cow_name = str; -+ backing_name = strchr(str, ','); -+ if(backing_name == NULL){ -+ printk(KERN_ERR "cow_setup - missing backing device name\n"); -+ return(0); -+ } -+ *backing_name = '\0'; -+ backing_name++; -+ -+ spin_lock(&cow_lock); -+ -+ dev = &cow_dev[unit]; -+ dev->cow_path = cow_name; -+ dev->backing_path = backing_name; -+ -+ spin_unlock(&cow_lock); -+ return(0); -+} -+ -+__setup("cow", cow_setup); -+ -+/* -+ * 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 -puN /dev/null arch/um/drivers/cow_sys.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/cow_sys.h 2004-06-29 21:02:55.707289960 +0200 -@@ -0,0 +1,48 @@ -+#ifndef __COW_SYS_H__ -+#define __COW_SYS_H__ -+ -+#include "kern_util.h" -+#include "user_util.h" -+#include "os.h" -+#include "user.h" -+ -+static inline void *cow_malloc(int size) -+{ -+ return(um_kmalloc(size)); -+} -+ -+static inline void cow_free(void *ptr) -+{ -+ kfree(ptr); -+} -+ -+#define cow_printf printk -+ -+static inline char *cow_strdup(char *str) -+{ -+ return(uml_strdup(str)); -+} -+ -+static inline int cow_seek_file(int fd, __u64 offset) -+{ -+ return(os_seek_file(fd, offset)); -+} -+ -+static inline int cow_file_size(char *file, __u64 *size_out) -+{ -+ return(os_file_size(file, size_out)); -+} -+ -+static inline int cow_write_file(int fd, char *buf, int size) -+{ -+ return(os_write_file(fd, buf, size)); -+} -+ -+#endif -+ -+/* -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -puN /dev/null arch/um/drivers/cow_user.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/cow_user.c 2004-06-29 21:02:55.708289808 +0200 -@@ -0,0 +1,375 @@ -+#include <stddef.h> -+#include <string.h> -+#include <errno.h> -+#include <unistd.h> -+#include <byteswap.h> -+#include <sys/time.h> -+#include <sys/param.h> -+#include <sys/user.h> -+#include <netinet/in.h> -+ -+#include "os.h" -+ -+#include "cow.h" -+#include "cow_sys.h" -+ -+#define PATH_LEN_V1 256 -+ -+struct cow_header_v1 { -+ int magic; -+ int version; -+ char backing_file[PATH_LEN_V1]; -+ time_t mtime; -+ __u64 size; -+ int sectorsize; -+}; -+ -+#define PATH_LEN_V2 MAXPATHLEN -+ -+struct cow_header_v2 { -+ unsigned long magic; -+ unsigned long version; -+ char backing_file[PATH_LEN_V2]; -+ time_t mtime; -+ __u64 size; -+ int sectorsize; -+}; -+ -+/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in -+ * case other systems have different values for MAXPATHLEN -+ */ -+#define PATH_LEN_V3 4096 -+ -+/* Changes from V2 - -+ * PATH_LEN_V3 as described above -+ * Explicitly specify field bit lengths for systems with different -+ * lengths for the usual C types. Not sure whether char or -+ * time_t should be changed, this can be changed later without -+ * breaking compatibility -+ * Add alignment field so that different alignments can be used for the -+ * bitmap and data -+ * Add cow_format field to allow for the possibility of different ways -+ * of specifying the COW blocks. For now, the only value is 0, -+ * for the traditional COW bitmap. -+ * Move the backing_file field to the end of the header. This allows -+ * for the possibility of expanding it into the padding required -+ * by the bitmap alignment. -+ * The bitmap and data portions of the file will be aligned as specified -+ * by the alignment field. This is to allow COW files to be -+ * put on devices with restrictions on access alignments, such as -+ * /dev/raw, with a 512 byte alignment restriction. This also -+ * allows the data to be more aligned more strictly than on -+ * sector boundaries. This is needed for ubd-mmap, which needs -+ * the data to be page aligned. -+ * Fixed (finally!) the rounding bug -+ */ -+ -+struct cow_header_v3 { -+ __u32 magic; -+ __u32 version; -+ time_t mtime; -+ __u64 size; -+ __u32 sectorsize; -+ __u32 alignment; -+ __u32 cow_format; -+ char backing_file[PATH_LEN_V3]; -+}; -+ -+/* COW format definitions - for now, we have only the usual COW bitmap */ -+#define COW_BITMAP 0 -+ -+union cow_header { -+ struct cow_header_v1 v1; -+ struct cow_header_v2 v2; -+ struct cow_header_v3 v3; -+}; -+ -+#define COW_MAGIC 0x4f4f4f4d /* MOOO */ -+#define COW_VERSION 3 -+ -+#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len)) -+#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align) -+ -+void cow_sizes(int version, __u64 size, int sectorsize, int align, -+ int bitmap_offset, unsigned long *bitmap_len_out, -+ int *data_offset_out) -+{ -+ if(version < 3){ -+ *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize); -+ -+ *data_offset_out = bitmap_offset + *bitmap_len_out; -+ *data_offset_out = (*data_offset_out + sectorsize - 1) / -+ sectorsize; -+ *data_offset_out *= sectorsize; -+ } -+ else { -+ *bitmap_len_out = DIV_ROUND(size, sectorsize); -+ *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8); -+ -+ *data_offset_out = bitmap_offset + *bitmap_len_out; -+ *data_offset_out = ROUND_UP(*data_offset_out, align); -+ } -+} -+ -+static int absolutize(char *to, int size, char *from) -+{ -+ char save_cwd[256], *slash; -+ int remaining; -+ -+ if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) { -+ cow_printf("absolutize : unable to get cwd - errno = %d\n", -+ errno); -+ return(-1); -+ } -+ slash = strrchr(from, '/'); -+ if(slash != NULL){ -+ *slash = '\0'; -+ if(chdir(from)){ -+ *slash = '/'; -+ cow_printf("absolutize : Can't cd to '%s' - " -+ "errno = %d\n", from, errno); -+ return(-1); -+ } -+ *slash = '/'; -+ if(getcwd(to, size) == NULL){ -+ cow_printf("absolutize : unable to get cwd of '%s' - " -+ "errno = %d\n", from, errno); -+ return(-1); -+ } -+ remaining = size - strlen(to); -+ if(strlen(slash) + 1 > remaining){ -+ cow_printf("absolutize : unable to fit '%s' into %d " -+ "chars\n", from, size); -+ return(-1); -+ } -+ strcat(to, slash); -+ } -+ else { -+ if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){ -+ cow_printf("absolutize : unable to fit '%s' into %d " -+ "chars\n", from, size); -+ return(-1); -+ } -+ strcpy(to, save_cwd); -+ strcat(to, "/"); -+ strcat(to, from); -+ } -+ chdir(save_cwd); -+ return(0); -+} -+ -+int write_cow_header(char *cow_file, int fd, char *backing_file, -+ int sectorsize, int alignment, long long *size) -+{ -+ struct cow_header_v3 *header; -+ unsigned long modtime; -+ int err; -+ -+ err = cow_seek_file(fd, 0); -+ if(err < 0){ -+ cow_printf("write_cow_header - lseek failed, err = %d\n", -err); -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ header = cow_malloc(sizeof(*header)); -+ if(header == NULL){ -+ cow_printf("Failed to allocate COW V3 header\n"); -+ goto out; -+ } -+ header->magic = htonl(COW_MAGIC); -+ header->version = htonl(COW_VERSION); -+ -+ err = -EINVAL; -+ if(strlen(backing_file) > sizeof(header->backing_file) - 1){ -+ cow_printf("Backing file name \"%s\" is too long - names are " -+ "limited to %d characters\n", backing_file, -+ sizeof(header->backing_file) - 1); -+ goto out_free; -+ } -+ -+ if(absolutize(header->backing_file, sizeof(header->backing_file), -+ backing_file)) -+ goto out_free; -+ -+ err = os_file_modtime(header->backing_file, &modtime); -+ if(err < 0){ -+ cow_printf("Backing file '%s' mtime request failed, " -+ "err = %d\n", header->backing_file, -err); -+ goto out_free; -+ } -+ -+ err = cow_file_size(header->backing_file, size); -+ if(err < 0){ -+ cow_printf("Couldn't get size of backing file '%s', " -+ "err = %d\n", header->backing_file, -err); -+ goto out_free; -+ } -+ -+ header->mtime = htonl(modtime); -+ header->size = htonll(*size); -+ header->sectorsize = htonl(sectorsize); -+ header->alignment = htonl(alignment); -+ header->cow_format = COW_BITMAP; -+ -+ err = os_write_file(fd, header, sizeof(*header)); -+ if(err != sizeof(*header)){ -+ cow_printf("Write of header to new COW file '%s' failed, " -+ "err = %d\n", cow_file, -err); -+ goto out_free; -+ } -+ err = 0; -+ out_free: -+ cow_free(header); -+ out: -+ return(err); -+} -+ -+int file_reader(__u64 offset, char *buf, int len, void *arg) -+{ -+ int fd = *((int *) arg); -+ -+ return(pread(fd, buf, len, offset)); -+} -+ -+/* XXX Need to sanity-check the values read from the header */ -+ -+int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, -+ __u32 *version_out, char **backing_file_out, -+ time_t *mtime_out, __u64 *size_out, -+ int *sectorsize_out, __u32 *align_out, -+ int *bitmap_offset_out) -+{ -+ union cow_header *header; -+ char *file; -+ int err, n; -+ unsigned long version, magic; -+ -+ header = cow_malloc(sizeof(*header)); -+ if(header == NULL){ -+ cow_printf("read_cow_header - Failed to allocate header\n"); -+ return(-ENOMEM); -+ } -+ err = -EINVAL; -+ n = (*reader)(0, (char *) header, sizeof(*header), arg); -+ if(n < offsetof(typeof(header->v1), backing_file)){ -+ cow_printf("read_cow_header - short header\n"); -+ goto out; -+ } -+ -+ magic = header->v1.magic; -+ if(magic == COW_MAGIC) { -+ version = header->v1.version; -+ } -+ else if(magic == ntohl(COW_MAGIC)){ -+ version = ntohl(header->v1.version); -+ } -+ /* No error printed because the non-COW case comes through here */ -+ else goto out; -+ -+ *version_out = version; -+ -+ if(version == 1){ -+ if(n < sizeof(header->v1)){ -+ cow_printf("read_cow_header - failed to read V1 " -+ "header\n"); -+ goto out; -+ } -+ *mtime_out = header->v1.mtime; -+ *size_out = header->v1.size; -+ *sectorsize_out = header->v1.sectorsize; -+ *bitmap_offset_out = sizeof(header->v1); -+ *align_out = *sectorsize_out; -+ file = header->v1.backing_file; -+ } -+ else if(version == 2){ -+ if(n < sizeof(header->v2)){ -+ cow_printf("read_cow_header - failed to read V2 " -+ "header\n"); -+ goto out; -+ } -+ *mtime_out = ntohl(header->v2.mtime); -+ *size_out = ntohll(header->v2.size); -+ *sectorsize_out = ntohl(header->v2.sectorsize); -+ *bitmap_offset_out = sizeof(header->v2); -+ *align_out = *sectorsize_out; -+ file = header->v2.backing_file; -+ } -+ else if(version == 3){ -+ if(n < sizeof(header->v3)){ -+ cow_printf("read_cow_header - failed to read V2 " -+ "header\n"); -+ goto out; -+ } -+ *mtime_out = ntohl(header->v3.mtime); -+ *size_out = ntohll(header->v3.size); -+ *sectorsize_out = ntohl(header->v3.sectorsize); -+ *align_out = ntohl(header->v3.alignment); -+ *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); -+ file = header->v3.backing_file; -+ } -+ else { -+ cow_printf("read_cow_header - invalid COW version\n"); -+ goto out; -+ } -+ err = -ENOMEM; -+ *backing_file_out = cow_strdup(file); -+ if(*backing_file_out == NULL){ -+ cow_printf("read_cow_header - failed to allocate backing " -+ "file\n"); -+ goto out; -+ } -+ err = 0; -+ out: -+ cow_free(header); -+ return(err); -+} -+ -+int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, -+ int alignment, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, int *data_offset_out) -+{ -+ __u64 size, offset; -+ char zero = 0; -+ int err; -+ -+ err = write_cow_header(cow_file, fd, backing_file, sectorsize, -+ alignment, &size); -+ if(err) -+ goto out; -+ -+ *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment); -+ cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out, -+ bitmap_len_out, data_offset_out); -+ -+ offset = *data_offset_out + size - sizeof(zero); -+ err = cow_seek_file(fd, offset); -+ if(err < 0){ -+ cow_printf("cow bitmap lseek failed : err = %d\n", -err); -+ goto out; -+ } -+ -+ /* does not really matter how much we write it is just to set EOF -+ * this also sets the entire COW bitmap -+ * to zero without having to allocate it -+ */ -+ err = cow_write_file(fd, &zero, sizeof(zero)); -+ if(err != sizeof(zero)){ -+ cow_printf("Write of bitmap to new COW file '%s' failed, " -+ "err = %d\n", cow_file, -err); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ return(0); -+ -+ out: -+ return(err); -+} -+ -+/* -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -puN arch/um/drivers/daemon_user.c~Main-uml-patch-no-skas arch/um/drivers/daemon_user.c ---- uml-linux-2.6.7/arch/um/drivers/daemon_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.443330088 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/daemon_user.c 2004-06-29 21:02:55.708289808 +0200 -@@ -53,7 +53,8 @@ static int connect_to_switch(struct daem - struct request_v3 req; - int fd, n, err; - -- if((pri->control = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){ -+ pri->control = socket(AF_UNIX, SOCK_STREAM, 0); -+ if(pri->control < 0){ - printk("daemon_open : control socket failed, errno = %d\n", - errno); - return(-errno); -@@ -67,7 +68,8 @@ static int connect_to_switch(struct daem - goto out; - } - -- if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){ -+ fd = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if(fd < 0){ - printk("daemon_open : data socket failed, errno = %d\n", - errno); - err = -errno; -@@ -91,18 +93,18 @@ static int connect_to_switch(struct daem - req.version = SWITCH_VERSION; - req.type = REQ_NEW_CONTROL; - req.sock = *local_addr; -- n = write(pri->control, &req, sizeof(req)); -+ n = os_write_file(pri->control, &req, sizeof(req)); - if(n != sizeof(req)){ -- printk("daemon_open : control setup request returned %d, " -- "errno = %d\n", n, errno); -+ printk("daemon_open : control setup request failed, err = %d\n", -+ -n); - err = -ENOTCONN; - goto out; - } - -- n = read(pri->control, sun, sizeof(*sun)); -+ n = os_read_file(pri->control, sun, sizeof(*sun)); - if(n != sizeof(*sun)){ -- printk("daemon_open : read of data socket returned %d, " -- "errno = %d\n", n, errno); -+ printk("daemon_open : read of data socket failed, err = %d\n", -+ -n); - err = -ENOTCONN; - goto out_close; - } -@@ -111,9 +113,9 @@ static int connect_to_switch(struct daem - return(fd); - - out_close: -- close(fd); -+ os_close_file(fd); - out: -- close(pri->control); -+ os_close_file(pri->control); - return(err); - } - -@@ -153,8 +155,8 @@ static void daemon_remove(void *data) - { - struct daemon_data *pri = data; - -- close(pri->fd); -- close(pri->control); -+ os_close_file(pri->fd); -+ os_close_file(pri->control); - if(pri->data_addr != NULL) kfree(pri->data_addr); - if(pri->ctl_addr != NULL) kfree(pri->ctl_addr); - if(pri->local_addr != NULL) kfree(pri->local_addr); -diff -puN arch/um/drivers/fd.c~Main-uml-patch-no-skas arch/um/drivers/fd.c ---- uml-linux-2.6.7/arch/um/drivers/fd.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.444329936 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/fd.c 2004-06-29 21:02:55.708289808 +0200 -@@ -35,7 +35,8 @@ void *fd_init(char *str, int device, str - printk("fd_init : couldn't parse file descriptor '%s'\n", str); - return(NULL); - } -- if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL); -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) return(NULL); - *data = ((struct fd_chan) { .fd = n, - .raw = opts->raw }); - return(data); -diff -puN arch/um/drivers/harddog_user.c~Main-uml-patch-no-skas arch/um/drivers/harddog_user.c ---- uml-linux-2.6.7/arch/um/drivers/harddog_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.445329784 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/harddog_user.c 2004-06-29 21:02:55.709289656 +0200 -@@ -27,10 +27,10 @@ static void pre_exec(void *d) - dup2(data->stdin, 0); - dup2(data->stdout, 1); - dup2(data->stdout, 2); -- close(data->stdin); -- close(data->stdout); -- close(data->close_me[0]); -- close(data->close_me[1]); -+ os_close_file(data->stdin); -+ os_close_file(data->stdout); -+ os_close_file(data->close_me[0]); -+ os_close_file(data->close_me[1]); - } - - int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) -@@ -44,15 +44,15 @@ int start_watchdog(int *in_fd_ret, int * - char **args = NULL; - - err = os_pipe(in_fds, 1, 0); -- if(err){ -- printk("harddog_open - os_pipe failed, errno = %d\n", -err); -- return(err); -+ if(err < 0){ -+ printk("harddog_open - os_pipe failed, err = %d\n", -err); -+ goto out; - } - - err = os_pipe(out_fds, 1, 0); -- if(err){ -- printk("harddog_open - os_pipe failed, errno = %d\n", -err); -- return(err); -+ if(err < 0){ -+ printk("harddog_open - os_pipe failed, err = %d\n", -err); -+ goto out_close_in; - } - - data.stdin = out_fds[0]; -@@ -72,42 +72,47 @@ int start_watchdog(int *in_fd_ret, int * - - pid = run_helper(pre_exec, &data, args, NULL); - -- close(out_fds[0]); -- close(in_fds[1]); -+ os_close_file(out_fds[0]); -+ os_close_file(in_fds[1]); - - if(pid < 0){ - err = -pid; -- printk("harddog_open - run_helper failed, errno = %d\n", err); -- goto out; -+ printk("harddog_open - run_helper failed, errno = %d\n", -err); -+ goto out_close_out; - } - -- n = read(in_fds[0], &c, sizeof(c)); -+ n = os_read_file(in_fds[0], &c, sizeof(c)); - if(n == 0){ - printk("harddog_open - EOF on watchdog pipe\n"); - helper_wait(pid); - err = -EIO; -- goto out; -+ goto out_close_out; - } - else if(n < 0){ - printk("harddog_open - read of watchdog pipe failed, " -- "errno = %d\n", errno); -+ "err = %d\n", -n); - helper_wait(pid); -- err = -errno; -- goto out; -+ err = n; -+ goto out_close_out; - } - *in_fd_ret = in_fds[0]; - *out_fd_ret = out_fds[1]; - return(0); -+ -+ out_close_in: -+ os_close_file(in_fds[0]); -+ os_close_file(in_fds[1]); -+ out_close_out: -+ os_close_file(out_fds[0]); -+ os_close_file(out_fds[1]); - out: -- close(out_fds[1]); -- close(in_fds[0]); - return(err); - } - - void stop_watchdog(int in_fd, int out_fd) - { -- close(in_fd); -- close(out_fd); -+ os_close_file(in_fd); -+ os_close_file(out_fd); - } - - int ping_watchdog(int fd) -@@ -115,11 +120,12 @@ int ping_watchdog(int fd) - int n; - char c = '\n'; - -- n = write(fd, &c, sizeof(c)); -- if(n < sizeof(c)){ -- printk("ping_watchdog - write failed, errno = %d\n", -- errno); -- return(-errno); -+ n = os_write_file(fd, &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("ping_watchdog - write failed, err = %d\n", -n); -+ if(n < 0) -+ return(n); -+ return(-EIO); - } - return 1; - -diff -puN arch/um/drivers/hostaudio_kern.c~Main-uml-patch-no-skas arch/um/drivers/hostaudio_kern.c ---- uml-linux-2.6.7/arch/um/drivers/hostaudio_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.459327656 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/hostaudio_kern.c 2004-06-29 21:02:55.709289656 +0200 -@@ -5,12 +5,12 @@ - - #include "linux/config.h" - #include "linux/module.h" --#include "linux/version.h" - #include "linux/init.h" - #include "linux/slab.h" - #include "linux/fs.h" - #include "linux/sound.h" - #include "linux/soundcard.h" -+#include "asm/uaccess.h" - #include "kern_util.h" - #include "init.h" - #include "hostaudio.h" -@@ -19,30 +19,39 @@ - char *dsp = HOSTAUDIO_DEV_DSP; - char *mixer = HOSTAUDIO_DEV_MIXER; - -+#define DSP_HELP \ -+" This is used to specify the host dsp device to the hostaudio driver.\n" \ -+" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n" -+ -+#define MIXER_HELP \ -+" This is used to specify the host mixer device to the hostaudio driver.\n" \ -+" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n" -+ - #ifndef MODULE - static int set_dsp(char *name, int *add) - { -- dsp = uml_strdup(name); -+ dsp = name; - return(0); - } - --__uml_setup("dsp=", set_dsp, --"dsp=<dsp device>\n" --" This is used to specify the host dsp device to the hostaudio driver.\n" --" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n" --); -+__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP); - - static int set_mixer(char *name, int *add) - { -- mixer = uml_strdup(name); -+ mixer = name; - return(0); - } - --__uml_setup("mixer=", set_mixer, --"mixer=<mixer device>\n" --" This is used to specify the host mixer device to the hostaudio driver.\n" --" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n" --); -+__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP); -+ -+#else /*MODULE*/ -+ -+MODULE_PARM(dsp, "s"); -+MODULE_PARM_DESC(dsp, DSP_HELP); -+ -+MODULE_PARM(mixer, "s"); -+MODULE_PARM_DESC(mixer, MIXER_HELP); -+ - #endif - - /* /dev/dsp file operations */ -@@ -51,23 +60,55 @@ static ssize_t hostaudio_read(struct fil - loff_t *ppos) - { - struct hostaudio_state *state = file->private_data; -+ void *kbuf; -+ int err; - - #ifdef DEBUG - printk("hostaudio: read called, count = %d\n", count); - #endif - -- return(hostaudio_read_user(state, buffer, count, ppos)); -+ kbuf = kmalloc(count, GFP_KERNEL); -+ if(kbuf == NULL) -+ return(-ENOMEM); -+ -+ err = hostaudio_read_user(state, kbuf, count, ppos); -+ if(err < 0) -+ goto out; -+ -+ if(copy_to_user(buffer, kbuf, err)) -+ err = -EFAULT; -+ -+ out: -+ kfree(kbuf); -+ return(err); - } - - static ssize_t hostaudio_write(struct file *file, const char *buffer, - size_t count, loff_t *ppos) - { - struct hostaudio_state *state = file->private_data; -+ void *kbuf; -+ int err; - - #ifdef DEBUG - printk("hostaudio: write called, count = %d\n", count); - #endif -- return(hostaudio_write_user(state, buffer, count, ppos)); -+ -+ kbuf = kmalloc(count, GFP_KERNEL); -+ if(kbuf == NULL) -+ return(-ENOMEM); -+ -+ err = -EFAULT; -+ if(copy_from_user(kbuf, buffer, count)) -+ goto out; -+ -+ err = hostaudio_write_user(state, kbuf, count, ppos); -+ if(err < 0) -+ goto out; -+ -+ out: -+ kfree(kbuf); -+ return(err); - } - - static unsigned int hostaudio_poll(struct file *file, -@@ -86,12 +127,43 @@ static int hostaudio_ioctl(struct inode - unsigned int cmd, unsigned long arg) - { - struct hostaudio_state *state = file->private_data; -+ unsigned long data = 0; -+ int err; - - #ifdef DEBUG - printk("hostaudio: ioctl called, cmd = %u\n", cmd); - #endif -+ switch(cmd){ -+ case SNDCTL_DSP_SPEED: -+ case SNDCTL_DSP_STEREO: -+ case SNDCTL_DSP_GETBLKSIZE: -+ case SNDCTL_DSP_CHANNELS: -+ case SNDCTL_DSP_SUBDIVIDE: -+ case SNDCTL_DSP_SETFRAGMENT: -+ if(get_user(data, (int *) arg)) -+ return(-EFAULT); -+ break; -+ default: -+ break; -+ } -+ -+ err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data); -+ -+ switch(cmd){ -+ case SNDCTL_DSP_SPEED: -+ case SNDCTL_DSP_STEREO: -+ case SNDCTL_DSP_GETBLKSIZE: -+ case SNDCTL_DSP_CHANNELS: -+ case SNDCTL_DSP_SUBDIVIDE: -+ case SNDCTL_DSP_SETFRAGMENT: -+ if(put_user(data, (int *) arg)) -+ return(-EFAULT); -+ break; -+ default: -+ break; -+ } - -- return(hostaudio_ioctl_user(state, cmd, arg)); -+ return(err); - } - - static int hostaudio_open(struct inode *inode, struct file *file) -@@ -225,7 +297,8 @@ MODULE_LICENSE("GPL"); - - static int __init hostaudio_init_module(void) - { -- printk(KERN_INFO "UML Audio Relay\n"); -+ printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", -+ dsp, mixer); - - module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); - if(module_data.dev_audio < 0){ -diff -puN arch/um/drivers/hostaudio_user.c~Main-uml-patch-no-skas arch/um/drivers/hostaudio_user.c ---- uml-linux-2.6.7/arch/um/drivers/hostaudio_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.460327504 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/hostaudio_user.c 2004-06-29 21:02:55.709289656 +0200 -@@ -4,9 +4,6 @@ - */ - - #include <sys/types.h> --#include <sys/stat.h> --#include <sys/ioctl.h> --#include <fcntl.h> - #include <unistd.h> - #include <errno.h> - #include "hostaudio.h" -@@ -20,45 +17,31 @@ - ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, - size_t count, loff_t *ppos) - { -- ssize_t ret; -- - #ifdef DEBUG - printk("hostaudio: read_user called, count = %d\n", count); - #endif - -- ret = read(state->fd, buffer, count); -- -- if(ret < 0) return(-errno); -- return(ret); -+ return(os_read_file(state->fd, buffer, count)); - } - - ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer, - size_t count, loff_t *ppos) - { -- ssize_t ret; -- - #ifdef DEBUG - printk("hostaudio: write_user called, count = %d\n", count); - #endif - -- ret = write(state->fd, buffer, count); -- -- if(ret < 0) return(-errno); -- return(ret); -+ return(os_write_file(state->fd, buffer, count)); - } - - int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, - unsigned long arg) - { -- int ret; - #ifdef DEBUG - printk("hostaudio: ioctl_user called, cmd = %u\n", cmd); - #endif - -- ret = ioctl(state->fd, cmd, arg); -- -- if(ret < 0) return(-errno); -- return(ret); -+ return(os_ioctl_generic(state->fd, cmd, arg)); - } - - int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp) -@@ -67,14 +50,15 @@ int hostaudio_open_user(struct hostaudio - printk("hostaudio: open_user called\n"); - #endif - -- state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); -- -- if(state->fd >= 0) return(0); -+ state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); - -- printk("hostaudio_open_user failed to open '%s', errno = %d\n", -- dsp, errno); -+ if(state->fd < 0) { -+ printk("hostaudio_open_user failed to open '%s', err = %d\n", -+ dsp, -state->fd); -+ return(state->fd); -+ } - -- return(-errno); -+ return(0); - } - - int hostaudio_release_user(struct hostaudio_state *state) -@@ -82,10 +66,10 @@ int hostaudio_release_user(struct hostau - #ifdef DEBUG - printk("hostaudio: release called\n"); - #endif -- if(state->fd >= 0){ -- close(state->fd); -- state->fd=-1; -- } -+ if(state->fd >= 0){ -+ os_close_file(state->fd); -+ state->fd = -1; -+ } - - return(0); - } -@@ -95,15 +79,11 @@ int hostaudio_release_user(struct hostau - int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, - unsigned int cmd, unsigned long arg) - { -- int ret; - #ifdef DEBUG - printk("hostmixer: ioctl_user called cmd = %u\n",cmd); - #endif - -- ret = ioctl(state->fd, cmd, arg); -- if(ret < 0) -- return(-errno); -- return(ret); -+ return(os_ioctl_generic(state->fd, cmd, arg)); - } - - int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w, -@@ -115,12 +95,13 @@ int hostmixer_open_mixdev_user(struct ho - - state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); - -- if(state->fd >= 0) return(0); -- -- printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n", -- mixer, errno); -+ if(state->fd < 0) { -+ printk("hostaudio_open_mixdev_user failed to open '%s', " -+ "err = %d\n", mixer, state->fd); -+ return(state->fd); -+ } - -- return(-errno); -+ return(0); - } - - int hostmixer_release_mixdev_user(struct hostmixer_state *state) -@@ -130,7 +111,7 @@ int hostmixer_release_mixdev_user(struct - #endif - - if(state->fd >= 0){ -- close(state->fd); -+ os_close_file(state->fd); - state->fd = -1; - } - -diff -puN arch/um/drivers/line.c~Main-uml-patch-no-skas arch/um/drivers/line.c ---- uml-linux-2.6.7/arch/um/drivers/line.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.462327200 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/line.c 2004-06-29 21:02:55.710289504 +0200 -@@ -6,8 +6,8 @@ - #include "linux/sched.h" - #include "linux/slab.h" - #include "linux/list.h" -+#include "linux/interrupt.h" - #include "linux/devfs_fs_kernel.h" --#include "asm/irq.h" - #include "asm/uaccess.h" - #include "chan_kern.h" - #include "irq_user.h" -@@ -16,38 +16,55 @@ - #include "user_util.h" - #include "kern_util.h" - #include "os.h" -+#include "irq_kern.h" - - #define LINE_BUFSIZE 4096 - --void line_interrupt(int irq, void *data, struct pt_regs *unused) -+static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused) - { - struct line *dev = data; - - if(dev->count > 0) - chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, - dev); -+ return IRQ_HANDLED; - } - --void line_timer_cb(void *arg) -+static void line_timer_cb(void *arg) - { - struct line *dev = arg; - - line_interrupt(dev->driver->read_irq, dev, NULL); - } - --static void buffer_data(struct line *line, const char *buf, int len) -+static int write_room(struct line *dev) - { -- int end; -+ int n; -+ -+ if(dev->buffer == NULL) return(LINE_BUFSIZE - 1); -+ -+ n = dev->head - dev->tail; -+ if(n <= 0) n = LINE_BUFSIZE + n; -+ return(n - 1); -+} -+ -+static int buffer_data(struct line *line, const char *buf, int len) -+{ -+ int end, room; - - if(line->buffer == NULL){ - line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC); - if(line->buffer == NULL){ - printk("buffer_data - atomic allocation failed\n"); -- return; -+ return(0); - } - line->head = line->buffer; - line->tail = line->buffer; - } -+ -+ room = write_room(line); -+ len = (len > room) ? room : len; -+ - end = line->buffer + LINE_BUFSIZE - line->tail; - if(len < end){ - memcpy(line->tail, buf, len); -@@ -60,6 +77,8 @@ static void buffer_data(struct line *lin - memcpy(line->buffer, buf, len); - line->tail = line->buffer + len; - } -+ -+ return(len); - } - - static int flush_buffer(struct line *line) -@@ -95,7 +114,7 @@ int line_write(struct line *lines, struc - struct line *line; - char *new; - unsigned long flags; -- int n, err, i; -+ int n, err, i, ret = 0; - - if(tty->stopped) return 0; - -@@ -104,9 +123,13 @@ int line_write(struct line *lines, struc - if(new == NULL) - return(0); - n = copy_from_user(new, buf, len); -- if(n == len) -- return(-EFAULT); - buf = new; -+ if(n == len){ -+ len = -EFAULT; -+ goto out_free; -+ } -+ -+ len -= n; - } - - i = tty->index; -@@ -115,41 +138,50 @@ int line_write(struct line *lines, struc - down(&line->sem); - if(line->head != line->tail){ - local_irq_save(flags); -- buffer_data(line, buf, len); -+ ret += buffer_data(line, buf, len); - err = flush_buffer(line); - local_irq_restore(flags); - if(err <= 0) -- goto out; -+ goto out_up; - } - else { - n = write_chan(&line->chan_list, buf, len, - line->driver->write_irq); - if(n < 0){ -- len = n; -- goto out; -+ ret = n; -+ goto out_up; - } -- if(n < len) -- buffer_data(line, buf + n, len - n); -+ -+ len -= n; -+ ret += n; -+ if(len > 0) -+ ret += buffer_data(line, buf + n, len); - } -- out: -+ out_up: - up(&line->sem); -- return(len); -+ out_free: -+ if(from_user) -+ kfree(buf); -+ return(ret); - } - --void line_write_interrupt(int irq, void *data, struct pt_regs *unused) -+static irqreturn_t line_write_interrupt(int irq, void *data, -+ struct pt_regs *unused) - { - struct line *dev = data; - struct tty_struct *tty = dev->tty; - int err; - - err = flush_buffer(dev); -- if(err == 0) return; -+ if(err == 0) -+ return(IRQ_NONE); - else if(err < 0){ - dev->head = dev->buffer; - dev->tail = dev->buffer; - } - -- if(tty == NULL) return; -+ if(tty == NULL) -+ return(IRQ_NONE); - - if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && - (tty->ldisc.write_wakeup != NULL)) -@@ -161,21 +193,9 @@ void line_write_interrupt(int irq, void - * writes. - */ - -- if (waitqueue_active(&tty->write_wait)) -+ if(waitqueue_active(&tty->write_wait)) - wake_up_interruptible(&tty->write_wait); -- --} -- --int line_write_room(struct tty_struct *tty) --{ -- struct line *dev = tty->driver_data; -- int n; -- -- if(dev->buffer == NULL) return(LINE_BUFSIZE - 1); -- -- n = dev->head - dev->tail; -- if(n <= 0) n = LINE_BUFSIZE + n; -- return(n - 1); -+ return(IRQ_HANDLED); - } - - int line_setup_irq(int fd, int input, int output, void *data) -@@ -305,7 +325,7 @@ int line_setup(struct line *lines, int n - if(*end != '='){ - printk(KERN_ERR "line_setup failed to parse \"%s\"\n", - init); -- return(1); -+ return(0); - } - init = end; - } -@@ -313,12 +333,12 @@ int line_setup(struct line *lines, int n - if((n >= 0) && (n >= num)){ - printk("line_setup - %d out of range ((0 ... %d) allowed)\n", - n, num); -- return(1); -+ return(0); - } - else if(n >= 0){ - if(lines[n].count > 0){ - printk("line_setup - device %d is open\n", n); -- return(1); -+ return(0); - } - if(lines[n].init_pri <= INIT_ONE){ - lines[n].init_pri = INIT_ONE; -@@ -332,7 +352,7 @@ int line_setup(struct line *lines, int n - else if(!all_allowed){ - printk("line_setup - can't configure all devices from " - "mconsole\n"); -- return(1); -+ return(0); - } - else { - for(i = 0; i < num; i++){ -@@ -346,7 +366,7 @@ int line_setup(struct line *lines, int n - } - } - } -- return(0); -+ return(1); - } - - int line_config(struct line *lines, int num, char *str) -@@ -357,7 +377,7 @@ int line_config(struct line *lines, int - printk("line_config - uml_strdup failed\n"); - return(-ENOMEM); - } -- return(line_setup(lines, num, new, 0)); -+ return(!line_setup(lines, num, new, 0)); - } - - int line_get_config(char *name, struct line *lines, int num, char *str, -@@ -369,7 +389,7 @@ int line_get_config(char *name, struct l - - dev = simple_strtoul(name, &end, 0); - if((*end != '\0') || (end == name)){ -- *error_out = "line_setup failed to parse device number"; -+ *error_out = "line_get_config failed to parse device number"; - return(0); - } - -@@ -379,15 +399,15 @@ int line_get_config(char *name, struct l - } - - line = &lines[dev]; -+ - down(&line->sem); -- - if(!line->valid) - CONFIG_CHUNK(str, size, n, "none", 1); - else if(line->count == 0) - CONFIG_CHUNK(str, size, n, line->init_str, 1); - else n = chan_config_string(&line->chan_list, str, size, error_out); -- - up(&line->sem); -+ - return(n); - } - -@@ -396,7 +416,14 @@ int line_remove(struct line *lines, int - char config[sizeof("conxxxx=none\0")]; - - sprintf(config, "%s=none", str); -- return(line_setup(lines, num, config, 0)); -+ return(!line_setup(lines, num, config, 0)); -+} -+ -+int line_write_room(struct tty_struct *tty) -+{ -+ struct line *dev = tty->driver_data; -+ -+ return(write_room(dev)); - } - - struct tty_driver *line_register_devfs(struct lines *set, -@@ -412,7 +439,8 @@ struct tty_driver *line_register_devfs(s - return NULL; - - driver->driver_name = line_driver->name; -- driver->name = line_driver->devfs_name; -+ driver->name = line_driver->device_name; -+ driver->devfs_name = line_driver->devfs_name; - driver->major = line_driver->major; - driver->minor_start = line_driver->minor_start; - driver->type = line_driver->type; -@@ -432,7 +460,7 @@ struct tty_driver *line_register_devfs(s - - for(i = 0; i < nlines; i++){ - if(!lines[i].valid) -- tty_unregister_devfs(driver, i); -+ tty_unregister_device(driver, i); - } - - mconsole_register_dev(&line_driver->mc); -@@ -465,24 +493,25 @@ struct winch { - struct line *line; - }; - --void winch_interrupt(int irq, void *data, struct pt_regs *unused) -+irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused) - { - struct winch *winch = data; - struct tty_struct *tty; - int err; - char c; - -- err = generic_read(winch->fd, &c, NULL); -- if(err < 0){ -- if(err != -EAGAIN){ -- printk("winch_interrupt : read failed, errno = %d\n", -- -err); -- printk("fd %d is losing SIGWINCH support\n", -- winch->tty_fd); -- free_irq(irq, data); -- return; -+ if(winch->fd != -1){ -+ err = generic_read(winch->fd, &c, NULL); -+ if(err < 0){ -+ if(err != -EAGAIN){ -+ printk("winch_interrupt : read failed, " -+ "errno = %d\n", -err); -+ printk("fd %d is losing SIGWINCH support\n", -+ winch->tty_fd); -+ return(IRQ_HANDLED); -+ } -+ goto out; - } -- goto out; - } - tty = winch->line->tty; - if(tty != NULL){ -@@ -492,7 +521,9 @@ void winch_interrupt(int irq, void *data - kill_pg(tty->pgrp, SIGWINCH, 1); - } - out: -- reactivate_fd(winch->fd, WINCH_IRQ); -+ if(winch->fd != -1) -+ reactivate_fd(winch->fd, WINCH_IRQ); -+ return(IRQ_HANDLED); - } - - DECLARE_MUTEX(winch_handler_sem); -@@ -529,7 +560,10 @@ static void winch_cleanup(void) - - list_for_each(ele, &winch_handlers){ - winch = list_entry(ele, struct winch, list); -- close(winch->fd); -+ if(winch->fd != -1){ -+ deactivate_fd(winch->fd, WINCH_IRQ); -+ os_close_file(winch->fd); -+ } - if(winch->pid != -1) - os_kill_process(winch->pid, 1); - } -diff -puN arch/um/drivers/Makefile~Main-uml-patch-no-skas arch/um/drivers/Makefile ---- uml-linux-2.6.7/arch/um/drivers/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.463327048 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/Makefile 2004-06-29 21:02:55.710289504 +0200 -@@ -1,5 +1,5 @@ - # --# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) -+# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com) - # Licensed under the GPL - # - -@@ -39,6 +39,8 @@ obj-$(CONFIG_PTY_CHAN) += pty.o - obj-$(CONFIG_TTY_CHAN) += tty.o - obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o - obj-$(CONFIG_UML_WATCHDOG) += harddog.o -+obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o -+obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o - - obj-y += stdio_console.o $(CHAN_OBJS) - -@@ -46,18 +48,7 @@ USER_SINGLE_OBJS = $(foreach f,$(patsubs - - USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \ - null.o pty.o tty.o xterm.o --USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file)) -+USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) - - $(USER_OBJS) : %.o: %.c - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -- --clean: -- --modules: -- --fastdep: -- --dep: -- --archmrproper: clean -- -diff -puN arch/um/drivers/mcast_user.c~Main-uml-patch-no-skas arch/um/drivers/mcast_user.c ---- uml-linux-2.6.7/arch/um/drivers/mcast_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.464326896 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/mcast_user.c 2004-06-29 21:02:55.711289352 +0200 -@@ -23,6 +23,7 @@ - #include "kern_util.h" - #include "user_util.h" - #include "user.h" -+#include "os.h" - - #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) - -@@ -62,7 +63,8 @@ static int mcast_open(void *data) - goto out; - } - -- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ -+ fd = socket(AF_INET, SOCK_DGRAM, 0); -+ if (fd < 0){ - printk("mcast_open : data socket failed, errno = %d\n", - errno); - fd = -ENOMEM; -@@ -72,7 +74,7 @@ static int mcast_open(void *data) - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { - printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", - errno); -- close(fd); -+ os_close_file(fd); - fd = -EINVAL; - goto out; - } -@@ -82,7 +84,7 @@ static int mcast_open(void *data) - sizeof(pri->ttl)) < 0) { - printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", - errno); -- close(fd); -+ os_close_file(fd); - fd = -EINVAL; - goto out; - } -@@ -91,7 +93,7 @@ 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); -- close(fd); -+ os_close_file(fd); - fd = -EINVAL; - goto out; - } -@@ -99,7 +101,7 @@ static int mcast_open(void *data) - /* bind socket to mcast address */ - if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { - printk("mcast_open : data bind failed, errno = %d\n", errno); -- close(fd); -+ os_close_file(fd); - fd = -EINVAL; - goto out; - } -@@ -115,7 +117,7 @@ static int mcast_open(void *data) - "interface on the host.\n"); - printk("eth0 should be configured in order to use the " - "multicast transport.\n"); -- close(fd); -+ os_close_file(fd); - fd = -EINVAL; - } - -@@ -137,7 +139,7 @@ static void mcast_close(int fd, void *da - errno); - } - -- close(fd); -+ os_close_file(fd); - } - - int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) -diff -puN arch/um/drivers/mconsole_kern.c~Main-uml-patch-no-skas arch/um/drivers/mconsole_kern.c ---- uml-linux-2.6.7/arch/um/drivers/mconsole_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.465326744 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_kern.c 2004-06-29 21:02:55.711289352 +0200 -@@ -1,6 +1,6 @@ - /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) -- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -15,6 +15,9 @@ - #include "linux/sysrq.h" - #include "linux/workqueue.h" - #include "linux/module.h" -+#include "linux/file.h" -+#include "linux/fs.h" -+#include "linux/namei.h" - #include "linux/proc_fs.h" - #include "asm/irq.h" - #include "asm/uaccess.h" -@@ -27,6 +30,7 @@ - #include "init.h" - #include "os.h" - #include "umid.h" -+#include "irq_kern.h" - - static int do_unlink_socket(struct notifier_block *notifier, - unsigned long what, void *data) -@@ -67,7 +71,7 @@ void mc_work_proc(void *unused) - - DECLARE_WORK(mconsole_work, mc_work_proc, NULL); - --void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs) - { - int fd; - struct mconsole_entry *new; -@@ -75,9 +79,10 @@ void mconsole_interrupt(int irq, void *d - - fd = (int) dev_id; - while (mconsole_get_request(fd, &req)){ -- if(req.cmd->as_interrupt) (*req.cmd->handler)(&req); -+ if(req.cmd->context == MCONSOLE_INTR) -+ (*req.cmd->handler)(&req); - else { -- new = kmalloc(sizeof(req), GFP_ATOMIC); -+ new = kmalloc(sizeof(*new), GFP_ATOMIC); - if(new == NULL) - mconsole_reply(&req, "Out of memory", 1, 0); - else { -@@ -88,6 +93,7 @@ void mconsole_interrupt(int irq, void *d - } - if(!list_empty(&mc_requests)) schedule_work(&mconsole_work); - reactivate_fd(fd, MCONSOLE_IRQ); -+ return(IRQ_HANDLED); - } - - void mconsole_version(struct mc_request *req) -@@ -100,20 +106,109 @@ void mconsole_version(struct mc_request - mconsole_reply(req, version, 0, 0); - } - -+void mconsole_log(struct mc_request *req) -+{ -+ int len; -+ char *ptr = req->request.data; -+ -+ ptr += strlen("log "); -+ -+ len = req->len - (ptr - req->request.data); -+ printk("%.*s", len, ptr); -+ mconsole_reply(req, "", 0, 0); -+} -+ -+void mconsole_proc(struct mc_request *req) -+{ -+ struct nameidata nd; -+ struct file_system_type *proc; -+ struct super_block *super; -+ struct file *file; -+ int n, err; -+ char *ptr = req->request.data, *buf; -+ -+ ptr += strlen("proc"); -+ while(isspace(*ptr)) ptr++; -+ -+ proc = get_fs_type("proc"); -+ if(proc == NULL){ -+ mconsole_reply(req, "procfs not registered", 1, 0); -+ goto out; -+ } -+ -+ super = (*proc->get_sb)(proc, 0, NULL, NULL); -+ put_filesystem(proc); -+ if(super == NULL){ -+ mconsole_reply(req, "Failed to get procfs superblock", 1, 0); -+ goto out; -+ } -+ up_write(&super->s_umount); -+ -+ nd.dentry = super->s_root; -+ nd.mnt = NULL; -+ nd.flags = O_RDONLY + 1; -+ nd.last_type = LAST_ROOT; -+ -+ err = link_path_walk(ptr, &nd); -+ if(err){ -+ mconsole_reply(req, "Failed to look up file", 1, 0); -+ goto out_kill; -+ } -+ -+ file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ if(IS_ERR(file)){ -+ mconsole_reply(req, "Failed to open file", 1, 0); -+ goto out_kill; -+ } -+ -+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL); -+ if(buf == NULL){ -+ mconsole_reply(req, "Failed to allocate buffer", 1, 0); -+ goto out_fput; -+ } -+ -+ if((file->f_op != NULL) && (file->f_op->read != NULL)){ -+ do { -+ n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, -+ &file->f_pos); -+ if(n >= 0){ -+ buf[n] = '\0'; -+ mconsole_reply(req, buf, 0, (n > 0)); -+ } -+ else { -+ mconsole_reply(req, "Read of file failed", -+ 1, 0); -+ goto out_free; -+ } -+ } while(n > 0); -+ } -+ else mconsole_reply(req, "", 0, 0); -+ -+ out_free: -+ kfree(buf); -+ out_fput: -+ fput(file); -+ out_kill: -+ deactivate_super(super); -+ out: ; -+} -+ - #define UML_MCONSOLE_HELPTEXT \ --"Commands: -- version - Get kernel version -- help - Print this message -- halt - Halt UML -- reboot - Reboot UML -- config <dev>=<config> - Add a new device to UML; -- same syntax as command line -- config <dev> - Query the configuration of a device -- remove <dev> - Remove a device from UML -- sysrq <letter> - Performs the SysRq action controlled by the letter -- cad - invoke the Ctl-Alt-Del handler -- stop - pause the UML; it will do nothing until it receives a 'go' -- go - continue the UML after a 'stop' -+"Commands: \n\ -+ version - Get kernel version \n\ -+ help - Print this message \n\ -+ halt - Halt UML \n\ -+ reboot - Reboot UML \n\ -+ config <dev>=<config> - Add a new device to UML; \n\ -+ same syntax as command line \n\ -+ config <dev> - Query the configuration of a device \n\ -+ remove <dev> - Remove a device from UML \n\ -+ sysrq <letter> - Performs the SysRq action controlled by the letter \n\ -+ cad - invoke the Ctl-Alt-Del handler \n\ -+ stop - pause the UML; it will do nothing until it receives a 'go' \n\ -+ go - continue the UML after a 'stop' \n\ -+ log <string> - make UML enter <string> into the kernel log\n\ -+ proc <file> - returns the contents of the UML's /proc/<file>\n\ - " - - void mconsole_help(struct mc_request *req) -@@ -302,7 +397,7 @@ int mconsole_init(void) - if(umid_file_name("mconsole", file, sizeof(file))) return(-1); - snprintf(mconsole_socket_name, sizeof(file), "%s", file); - -- sock = create_unix_socket(file, sizeof(file)); -+ sock = os_create_unix_socket(file, sizeof(file), 1); - if (sock < 0){ - printk("Failed to initialize management console\n"); - return(1); -@@ -344,11 +439,16 @@ static int write_proc_mconsole(struct fi - if(buf == NULL) - return(-ENOMEM); - -- if(copy_from_user(buf, buffer, count)) -- return(-EFAULT); -+ if(copy_from_user(buf, buffer, count)){ -+ count = -EFAULT; -+ goto out; -+ } -+ - buf[count] = '\0'; - - mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count); -+ out: -+ kfree(buf); - return(count); - } - -diff -puN arch/um/drivers/mconsole_user.c~Main-uml-patch-no-skas arch/um/drivers/mconsole_user.c ---- uml-linux-2.6.7/arch/um/drivers/mconsole_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.466326592 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_user.c 2004-06-29 21:02:55.712289200 +0200 -@@ -1,6 +1,6 @@ - /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) -- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -18,16 +18,18 @@ - #include "umid.h" - - static struct mconsole_command commands[] = { -- { "version", mconsole_version, 1 }, -- { "halt", mconsole_halt, 0 }, -- { "reboot", mconsole_reboot, 0 }, -- { "config", mconsole_config, 0 }, -- { "remove", mconsole_remove, 0 }, -- { "sysrq", mconsole_sysrq, 1 }, -- { "help", mconsole_help, 1 }, -- { "cad", mconsole_cad, 1 }, -- { "stop", mconsole_stop, 0 }, -- { "go", mconsole_go, 1 }, -+ { "version", mconsole_version, MCONSOLE_INTR }, -+ { "halt", mconsole_halt, MCONSOLE_PROC }, -+ { "reboot", mconsole_reboot, MCONSOLE_PROC }, -+ { "config", mconsole_config, MCONSOLE_PROC }, -+ { "remove", mconsole_remove, MCONSOLE_PROC }, -+ { "sysrq", mconsole_sysrq, MCONSOLE_INTR }, -+ { "help", mconsole_help, MCONSOLE_INTR }, -+ { "cad", mconsole_cad, MCONSOLE_INTR }, -+ { "stop", mconsole_stop, MCONSOLE_PROC }, -+ { "go", mconsole_go, MCONSOLE_INTR }, -+ { "log", mconsole_log, MCONSOLE_INTR }, -+ { "proc", mconsole_proc, MCONSOLE_PROC }, - }; - - /* Initialized in mconsole_init, which is an initcall */ -@@ -139,6 +141,7 @@ int mconsole_reply(struct mc_request *re - memcpy(reply.data, str, len); - reply.data[len] = '\0'; - total -= len; -+ str += len; - reply.len = len + 1; - - len = sizeof(reply) + reply.len - sizeof(reply.data); -diff -puN arch/um/drivers/mmapper_kern.c~Main-uml-patch-no-skas arch/um/drivers/mmapper_kern.c ---- uml-linux-2.6.7/arch/um/drivers/mmapper_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.467326440 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/mmapper_kern.c 2004-06-29 21:02:55.712289200 +0200 -@@ -120,7 +120,10 @@ static int __init mmapper_init(void) - printk(KERN_INFO "Mapper v0.1\n"); - - v_buf = (char *) find_iomem("mmapper", &mmapper_size); -- if(mmapper_size == 0) return(0); -+ if(mmapper_size == 0){ -+ printk(KERN_ERR "mmapper_init - find_iomem failed\n"); -+ return(0); -+ } - - p_buf = __pa(v_buf); - -diff -puN arch/um/drivers/net_kern.c~Main-uml-patch-no-skas arch/um/drivers/net_kern.c ---- uml-linux-2.6.7/arch/um/drivers/net_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.468326288 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/net_kern.c 2004-06-29 21:02:55.712289200 +0200 -@@ -26,6 +26,7 @@ - #include "mconsole_kern.h" - #include "init.h" - #include "irq_user.h" -+#include "irq_kern.h" - - static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED; - LIST_HEAD(opened); -@@ -37,7 +38,8 @@ static int uml_net_rx(struct net_device - struct sk_buff *skb; - - /* If we can't allocate memory, try again next round. */ -- if ((skb = dev_alloc_skb(dev->mtu)) == NULL) { -+ skb = dev_alloc_skb(dev->mtu); -+ if (skb == NULL) { - lp->stats.rx_dropped++; - return 0; - } -@@ -61,14 +63,14 @@ static int uml_net_rx(struct net_device - return pkt_len; - } - --void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) - { - struct net_device *dev = dev_id; - struct uml_net_private *lp = dev->priv; - int err; - - if(!netif_running(dev)) -- return; -+ return(IRQ_NONE); - - spin_lock(&lp->lock); - while((err = uml_net_rx(dev)) > 0) ; -@@ -83,6 +85,7 @@ void uml_net_interrupt(int irq, void *de - - out: - spin_unlock(&lp->lock); -+ return(IRQ_HANDLED); - } - - static int uml_net_open(struct net_device *dev) -@@ -250,37 +253,6 @@ void uml_net_user_timer_expire(unsigned - #endif - } - --/* -- * default do nothing hard header packet routines for struct net_device init. -- * real ethernet transports will overwrite with real routines. -- */ --static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev, -- unsigned short type, void *daddr, void *saddr, unsigned len) --{ -- return(0); /* no change */ --} -- --static int uml_net_rebuild_header(struct sk_buff *skb) --{ -- return(0); /* ignore */ --} -- --static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh) --{ -- return(-1); /* fail */ --} -- --static void uml_net_header_cache_update(struct hh_cache *hh, -- struct net_device *dev, unsigned char * haddr) --{ -- /* ignore */ --} -- --static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr) --{ -- return(0); /* nothing */ --} -- - static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED; - static struct list_head devices = LIST_HEAD_INIT(devices); - -@@ -290,7 +262,7 @@ static int eth_configure(int n, void *in - struct uml_net *device; - struct net_device *dev; - struct uml_net_private *lp; -- int err, size; -+ int save, err, size; - - size = transport->private_size + sizeof(struct uml_net_private) + - sizeof(((struct uml_net_private *) 0)->user); -@@ -332,12 +304,6 @@ static int eth_configure(int n, void *in - snprintf(dev->name, sizeof(dev->name), "eth%d", n); - device->dev = dev; - -- dev->hard_header = uml_net_hard_header; -- dev->rebuild_header = uml_net_rebuild_header; -- dev->hard_header_cache = uml_net_header_cache; -- dev->header_cache_update= uml_net_header_cache_update; -- dev->hard_header_parse = uml_net_header_parse; -- - (*transport->kern->init)(dev, init); - - dev->mtu = transport->user->max_packet; -@@ -364,21 +330,29 @@ static int eth_configure(int n, void *in - } - lp = dev->priv; - -- INIT_LIST_HEAD(&lp->list); -- spin_lock_init(&lp->lock); -- lp->dev = dev; -- lp->fd = -1; -- lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 }; -- lp->have_mac = device->have_mac; -- lp->protocol = transport->kern->protocol; -- lp->open = transport->user->open; -- lp->close = transport->user->close; -- lp->remove = transport->user->remove; -- lp->read = transport->kern->read; -- lp->write = transport->kern->write; -- lp->add_address = transport->user->add_address; -- lp->delete_address = transport->user->delete_address; -- lp->set_mtu = transport->user->set_mtu; -+ /* lp.user is the first four bytes of the transport data, which -+ * has already been initialized. This structure assignment will -+ * overwrite that, so we make sure that .user gets overwritten with -+ * what it already has. -+ */ -+ save = lp->user[0]; -+ *lp = ((struct uml_net_private) -+ { .list = LIST_HEAD_INIT(lp->list), -+ .lock = SPIN_LOCK_UNLOCKED, -+ .dev = dev, -+ .fd = -1, -+ .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, -+ .have_mac = device->have_mac, -+ .protocol = transport->kern->protocol, -+ .open = transport->user->open, -+ .close = transport->user->close, -+ .remove = transport->user->remove, -+ .read = transport->kern->read, -+ .write = transport->kern->write, -+ .add_address = transport->user->add_address, -+ .delete_address = transport->user->delete_address, -+ .set_mtu = transport->user->set_mtu, -+ .user = { save } }); - - init_timer(&lp->tl); - lp->tl.function = uml_net_user_timer_expire; -@@ -611,7 +585,8 @@ static int net_remove(char *str) - unregister_netdev(dev); - - list_del(&device->list); -- free_netdev(device); -+ kfree(device); -+ free_netdev(dev); - return(0); - } - -diff -puN arch/um/drivers/net_user.c~Main-uml-patch-no-skas arch/um/drivers/net_user.c ---- uml-linux-2.6.7/arch/um/drivers/net_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.469326136 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/net_user.c 2004-06-29 21:02:55.713289048 +0200 -@@ -26,8 +26,7 @@ int tap_open_common(void *dev, char *gat - if(gate_addr == NULL) return(0); - if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], - &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){ -- printk("Invalid tap IP address - '%s'\n", -- gate_addr); -+ printk("Invalid tap IP address - '%s'\n", gate_addr); - return(-EINVAL); - } - return(0); -@@ -60,18 +59,18 @@ void read_output(int fd, char *output, i - } - - *output = '\0'; -- if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){ -- printk("read_output - read of length failed, errno = %d\n", -- errno); -+ n = os_read_file(fd, &remain, sizeof(remain)); -+ if(n != sizeof(remain)){ -+ printk("read_output - read of length failed, err = %d\n", -n); - return; - } - - while(remain != 0){ - n = (remain < len) ? remain : len; -- actual = read(fd, output, n); -+ actual = os_read_file(fd, output, n); - if(actual != n){ - printk("read_output - read of data failed, " -- "errno = %d\n", errno); -+ "err = %d\n", -actual); - return; - } - remain -= actual; -@@ -83,13 +82,12 @@ int net_read(int fd, void *buf, int len) - { - int n; - -- while(((n = read(fd, buf, len)) < 0) && (errno == EINTR)) ; -+ n = os_read_file(fd, buf, len); - -- if(n < 0){ -- if(errno == EAGAIN) return(0); -- return(-errno); -- } -- else if(n == 0) return(-ENOTCONN); -+ if(n == -EAGAIN) -+ return(0); -+ else if(n == 0) -+ return(-ENOTCONN); - return(n); - } - -@@ -112,13 +110,13 @@ int net_write(int fd, void *buf, int len - { - int n; - -- while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ; -- if(n < 0){ -- if(errno == EAGAIN) return(0); -- return(-errno); -- } -- else if(n == 0) return(-ENOTCONN); -- return(n); -+ n = os_write_file(fd, buf, len); -+ -+ if(n == -EAGAIN) -+ return(0); -+ else if(n == 0) -+ return(-ENOTCONN); -+ return(n); - } - - int net_send(int fd, void *buf, int len) -@@ -157,7 +155,7 @@ static void change_pre_exec(void *arg) - { - struct change_pre_exec_data *data = arg; - -- close(data->close_me); -+ os_close_file(data->close_me); - dup2(data->stdout, 1); - } - -@@ -167,15 +165,15 @@ static int change_tramp(char **argv, cha - struct change_pre_exec_data pe_data; - - err = os_pipe(fds, 1, 0); -- if(err){ -- printk("change_tramp - pipe failed, errno = %d\n", -err); -+ if(err < 0){ -+ printk("change_tramp - pipe failed, err = %d\n", -err); - return(err); - } - pe_data.close_me = fds[0]; - pe_data.stdout = fds[1]; - pid = run_helper(change_pre_exec, &pe_data, argv, NULL); - -- close(fds[1]); -+ os_close_file(fds[1]); - read_output(fds[0], output, output_len); - waitpid(pid, NULL, 0); - return(pid); -diff -puN arch/um/drivers/null.c~Main-uml-patch-no-skas arch/um/drivers/null.c ---- uml-linux-2.6.7/arch/um/drivers/null.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.470325984 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/null.c 2004-06-29 21:02:55.713289048 +0200 -@@ -5,7 +5,6 @@ - - #include <stdlib.h> - #include <errno.h> --#include <fcntl.h> - #include "chan_user.h" - #include "os.h" - -diff -puN arch/um/drivers/port_kern.c~Main-uml-patch-no-skas arch/um/drivers/port_kern.c ---- uml-linux-2.6.7/arch/um/drivers/port_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.471325832 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/port_kern.c 2004-06-29 21:02:55.713289048 +0200 -@@ -6,6 +6,7 @@ - #include "linux/list.h" - #include "linux/sched.h" - #include "linux/slab.h" -+#include "linux/interrupt.h" - #include "linux/irq.h" - #include "linux/spinlock.h" - #include "linux/errno.h" -@@ -14,6 +15,7 @@ - #include "kern_util.h" - #include "kern.h" - #include "irq_user.h" -+#include "irq_kern.h" - #include "port.h" - #include "init.h" - #include "os.h" -@@ -38,21 +40,21 @@ struct port_dev { - struct connection { - struct list_head list; - int fd; -- int helper_pid; -+ int helper_pid; - int socket[2]; - int telnetd_pid; - struct port_list *port; - }; - --static void pipe_interrupt(int irq, void *data, struct pt_regs *regs) -+static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs) - { - struct connection *conn = data; - int fd; - -- fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); -+ fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); - if(fd < 0){ - if(fd == -EAGAIN) -- return; -+ return(IRQ_NONE); - - printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", - -fd); -@@ -65,6 +67,7 @@ static void pipe_interrupt(int irq, void - list_add(&conn->list, &conn->port->connections); - - up(&conn->port->sem); -+ return(IRQ_HANDLED); - } - - static int port_accept(struct port_list *port) -@@ -102,8 +105,7 @@ static int port_accept(struct port_list - } - - list_add(&conn->list, &port->pending); -- ret = 1; -- goto out; -+ return(1); - - out_free: - kfree(conn); -@@ -138,12 +140,13 @@ void port_work_proc(void *unused) - - DECLARE_WORK(port_work, port_work_proc, NULL); - --static void port_interrupt(int irq, void *data, struct pt_regs *regs) -+static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs) - { - struct port_list *port = data; - - port->has_connection = 1; - schedule_work(&port_work); -+ return(IRQ_HANDLED); - } - - void *port_data(int port_num) -diff -puN arch/um/drivers/port_user.c~Main-uml-patch-no-skas arch/um/drivers/port_user.c ---- uml-linux-2.6.7/arch/um/drivers/port_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.473325528 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/port_user.c 2004-06-29 21:02:55.714288896 +0200 -@@ -47,10 +47,12 @@ void *port_init(char *str, int device, s - return(NULL); - } - -- if((kern_data = port_data(port)) == NULL) -+ kern_data = port_data(port); -+ if(kern_data == NULL) - return(NULL); - -- if((data = um_kmalloc(sizeof(*data))) == NULL) -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) - goto err; - - *data = ((struct port_chan) { .raw = opts->raw, -@@ -90,7 +92,7 @@ void port_close(int fd, void *d) - struct port_chan *data = d; - - port_remove_dev(data->kernel_data); -- close(fd); -+ os_close_file(fd); - } - - int port_console_write(int fd, const char *buf, int n, void *d) -@@ -130,11 +132,15 @@ int port_listen_fd(int port) - goto out; - } - -- if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){ -+ if(listen(fd, 1) < 0){ - err = -errno; - goto out; - } - -+ err = os_set_fd_block(fd, 0); -+ if(err < 0) -+ goto out; -+ - return(fd); - out: - os_close_file(fd); -@@ -153,10 +159,10 @@ void port_pre_exec(void *arg) - dup2(data->sock_fd, 0); - dup2(data->sock_fd, 1); - dup2(data->sock_fd, 2); -- close(data->sock_fd); -+ os_close_file(data->sock_fd); - dup2(data->pipe_fd, 3); - os_shutdown_socket(3, 1, 0); -- close(data->pipe_fd); -+ os_close_file(data->pipe_fd); - } - - int port_connection(int fd, int *socket, int *pid_out) -@@ -166,11 +172,12 @@ int port_connection(int fd, int *socket, - "/usr/lib/uml/port-helper", NULL }; - struct port_pre_exec_data data; - -- if((new = os_accept_connection(fd)) < 0) -- return(-errno); -+ new = os_accept_connection(fd); -+ if(new < 0) -+ return(new); - - err = os_pipe(socket, 0, 0); -- if(err) -+ if(err < 0) - goto out_close; - - data = ((struct port_pre_exec_data) -@@ -186,11 +193,11 @@ int port_connection(int fd, int *socket, - - out_shutdown: - os_shutdown_socket(socket[0], 1, 1); -- close(socket[0]); -+ os_close_file(socket[0]); - os_shutdown_socket(socket[1], 1, 1); -- close(socket[1]); -+ os_close_file(socket[1]); - out_close: -- close(new); -+ os_close_file(new); - return(err); - } - -diff -puN arch/um/drivers/pty.c~Main-uml-patch-no-skas arch/um/drivers/pty.c ---- uml-linux-2.6.7/arch/um/drivers/pty.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.474325376 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/pty.c 2004-06-29 21:02:55.714288896 +0200 -@@ -7,12 +7,12 @@ - #include <unistd.h> - #include <string.h> - #include <errno.h> --#include <fcntl.h> - #include <termios.h> - #include "chan_user.h" - #include "user.h" - #include "user_util.h" - #include "kern_util.h" -+#include "os.h" - - struct pty_chan { - void (*announce)(char *dev_name, int dev); -@@ -26,7 +26,8 @@ void *pty_chan_init(char *str, int devic - { - struct pty_chan *data; - -- if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL); -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) return(NULL); - *data = ((struct pty_chan) { .announce = opts->announce, - .dev = device, - .raw = opts->raw }); -@@ -39,7 +40,8 @@ int pts_open(int input, int output, int - char *dev; - int fd; - -- if((fd = get_pty()) < 0){ -+ fd = get_pty(); -+ if(fd < 0){ - printk("open_pts : Failed to open pts\n"); - return(-errno); - } -@@ -57,29 +59,27 @@ int pts_open(int input, int output, int - - int getmaster(char *line) - { -- struct stat stb; - char *pty, *bank, *cp; -- int master; -+ int master, err; - - pty = &line[strlen("/dev/ptyp")]; - for (bank = "pqrs"; *bank; bank++) { - line[strlen("/dev/pty")] = *bank; - *pty = '0'; -- if (stat(line, &stb) < 0) -+ if (os_stat_file(line, NULL) < 0) - break; - for (cp = "0123456789abcdef"; *cp; cp++) { - *pty = *cp; -- master = open(line, O_RDWR); -+ master = os_open_file(line, of_rdwr(OPENFLAGS()), 0); - if (master >= 0) { - char *tp = &line[strlen("/dev/")]; -- int ok; - - /* verify slave side is usable */ - *tp = 't'; -- ok = access(line, R_OK|W_OK) == 0; -+ err = os_access(line, OS_ACC_RW_OK); - *tp = 'p'; -- if (ok) return(master); -- (void) close(master); -+ if(err == 0) return(master); -+ (void) os_close_file(master); - } - } - } -diff -puN arch/um/drivers/slip_user.c~Main-uml-patch-no-skas arch/um/drivers/slip_user.c ---- uml-linux-2.6.7/arch/um/drivers/slip_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.475325224 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/slip_user.c 2004-06-29 21:02:55.714288896 +0200 -@@ -4,11 +4,9 @@ - #include <stddef.h> - #include <sched.h> - #include <string.h> --#include <sys/fcntl.h> - #include <sys/errno.h> - #include <sys/termios.h> - #include <sys/wait.h> --#include <sys/ioctl.h> - #include <sys/signal.h> - #include "user_util.h" - #include "kern_util.h" -@@ -65,9 +63,9 @@ static void slip_pre_exec(void *arg) - { - struct slip_pre_exec_data *data = arg; - -- if(data->stdin != -1) dup2(data->stdin, 0); -+ if(data->stdin >= 0) dup2(data->stdin, 0); - dup2(data->stdout, 1); -- if(data->close_me != -1) close(data->close_me); -+ if(data->close_me >= 0) os_close_file(data->close_me); - } - - static int slip_tramp(char **argv, int fd) -@@ -77,8 +75,8 @@ static int slip_tramp(char **argv, int f - int status, pid, fds[2], err, output_len; - - err = os_pipe(fds, 1, 0); -- if(err){ -- printk("slip_tramp : pipe failed, errno = %d\n", -err); -+ if(err < 0){ -+ printk("slip_tramp : pipe failed, err = %d\n", -err); - return(err); - } - -@@ -96,7 +94,7 @@ static int slip_tramp(char **argv, int f - printk("slip_tramp : failed to allocate output " - "buffer\n"); - -- close(fds[1]); -+ os_close_file(fds[1]); - read_output(fds[0], output, output_len); - if(output != NULL){ - printk("%s", output); -@@ -105,7 +103,7 @@ static int slip_tramp(char **argv, int f - if(waitpid(pid, &status, 0) < 0) err = errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ - printk("'%s' didn't exit with status 0\n", argv[0]); -- err = EINVAL; -+ err = -EINVAL; - } - } - return(err); -@@ -118,15 +116,17 @@ static int slip_open(void *data) - char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; - char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, - NULL }; -- int sfd, mfd, disc, sencap, err; -+ int sfd, mfd, err; - -- if((mfd = get_pty()) < 0){ -- printk("umn : Failed to open pty\n"); -- return(-1); -+ mfd = get_pty(); -+ if(mfd < 0){ -+ printk("umn : Failed to open pty, err = %d\n", -mfd); -+ return(mfd); - } -- if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){ -- printk("Couldn't open tty for slip line\n"); -- return(-1); -+ sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); -+ if(sfd < 0){ -+ printk("Couldn't open tty for slip line, err = %d\n", -sfd); -+ return(sfd); - } - if(set_up_tty(sfd)) return(-1); - pri->slave = sfd; -@@ -138,28 +138,23 @@ static int slip_open(void *data) - - err = slip_tramp(argv, sfd); - -- if(err != 0){ -- printk("slip_tramp failed - errno = %d\n", err); -- return(-err); -+ if(err < 0){ -+ printk("slip_tramp failed - err = %d\n", -err); -+ return(err); - } -- if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){ -- printk("SIOCGIFNAME failed, errno = %d\n", errno); -- return(-errno); -+ err = os_get_ifname(pri->slave, pri->name); -+ if(err < 0){ -+ printk("get_ifname failed, err = %d\n", -err); -+ return(err); - } - iter_addresses(pri->dev, open_addr, pri->name); - } - else { -- disc = N_SLIP; -- if(ioctl(sfd, TIOCSETD, &disc) < 0){ -- printk("Failed to set slip line discipline - " -- "errno = %d\n", errno); -- return(-errno); -- } -- sencap = 0; -- if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){ -- printk("Failed to set slip encapsulation - " -- "errno = %d\n", errno); -- return(-errno); -+ err = os_set_slip(sfd); -+ if(err < 0){ -+ printk("Failed to set slip discipline encapsulation - " -+ "err = %d\n", -err); -+ return(err); - } - } - return(mfd); -@@ -181,9 +176,9 @@ static void slip_close(int fd, void *dat - err = slip_tramp(argv, -1); - - if(err != 0) -- printk("slip_tramp failed - errno = %d\n", err); -- close(fd); -- close(pri->slave); -+ printk("slip_tramp failed - errno = %d\n", -err); -+ os_close_file(fd); -+ os_close_file(pri->slave); - pri->slave = -1; - } - -@@ -243,7 +238,7 @@ static void slip_add_addr(unsigned char - { - struct slip_data *pri = data; - -- if(pri->slave == -1) return; -+ if(pri->slave < 0) return; - open_addr(addr, netmask, pri->name); - } - -@@ -252,7 +247,7 @@ static void slip_del_addr(unsigned char - { - struct slip_data *pri = data; - -- if(pri->slave == -1) return; -+ if(pri->slave < 0) return; - close_addr(addr, netmask, pri->name); - } - -diff -puN arch/um/drivers/slirp_user.c~Main-uml-patch-no-skas arch/um/drivers/slirp_user.c ---- uml-linux-2.6.7/arch/um/drivers/slirp_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.476325072 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/slirp_user.c 2004-06-29 21:02:55.715288744 +0200 -@@ -4,7 +4,6 @@ - #include <stddef.h> - #include <sched.h> - #include <string.h> --#include <sys/fcntl.h> - #include <sys/errno.h> - #include <sys/wait.h> - #include <sys/signal.h> -@@ -48,15 +47,15 @@ static int slirp_tramp(char **argv, int - - return(pid); - } -- -+ -+/* XXX This is just a trivial wrapper around os_pipe */ - static int slirp_datachan(int *mfd, int *sfd) - { - int fds[2], err; - - err = os_pipe(fds, 1, 1); -- if(err){ -- printk("slirp_datachan: Failed to open pipe, errno = %d\n", -- -err); -+ if(err < 0){ -+ printk("slirp_datachan: Failed to open pipe, err = %d\n", -err); - return(err); - } - -@@ -77,7 +76,7 @@ static int slirp_open(void *data) - pid = slirp_tramp(pri->argw.argv, sfd); - - if(pid < 0){ -- printk("slirp_tramp failed - errno = %d\n", pid); -+ printk("slirp_tramp failed - errno = %d\n", -pid); - os_close_file(sfd); - os_close_file(mfd); - return(pid); -@@ -97,8 +96,8 @@ static void slirp_close(int fd, void *da - struct slirp_data *pri = data; - int status,err; - -- close(fd); -- close(pri->slave); -+ os_close_file(fd); -+ os_close_file(pri->slave); - - pri->slave = -1; - -diff -puN arch/um/drivers/ssl.c~Main-uml-patch-no-skas arch/um/drivers/ssl.c ---- uml-linux-2.6.7/arch/um/drivers/ssl.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.477324920 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/ssl.c 2004-06-29 21:02:55.715288744 +0200 -@@ -10,6 +10,7 @@ - #include "linux/major.h" - #include "linux/mm.h" - #include "linux/init.h" -+#include "linux/console.h" - #include "asm/termbits.h" - #include "asm/irq.h" - #include "line.h" -@@ -53,8 +54,9 @@ static int ssl_remove(char *str); - - static struct line_driver driver = { - .name = "UML serial line", -- .devfs_name = "tts/%d", -- .major = TTYAUX_MAJOR, -+ .device_name = "ttS", -+ .devfs_name = "tts/", -+ .major = TTY_MAJOR, - .minor_start = 64, - .type = TTY_DRIVER_TYPE_SERIAL, - .subtype = 0, -@@ -149,6 +151,9 @@ static int ssl_ioctl(struct tty_struct * - case TCSETSW: - case TCGETA: - case TIOCMGET: -+ case TCSBRK: -+ case TCSBRKP: -+ case TIOCMSET: - ret = -ENOIOCTLCMD; - break; - default: -@@ -212,6 +217,37 @@ static struct tty_operations ssl_ops = { - */ - static int ssl_init_done = 0; - -+static void ssl_console_write(struct console *c, const char *string, -+ unsigned len) -+{ -+ struct line *line = &serial_lines[c->index]; -+ if(ssl_init_done) -+ down(&line->sem); -+ console_write_chan(&line->chan_list, string, len); -+ if(ssl_init_done) -+ up(&line->sem); -+} -+ -+static struct tty_driver *ssl_console_device(struct console *c, int *index) -+{ -+ *index = c->index; -+ return ssl_driver; -+} -+ -+static int ssl_console_setup(struct console *co, char *options) -+{ -+ return(0); -+} -+ -+static struct console ssl_cons = { -+ name: "ttyS", -+ write: ssl_console_write, -+ device: ssl_console_device, -+ setup: ssl_console_setup, -+ flags: CON_PRINTBUFFER, -+ index: -1, -+}; -+ - int ssl_init(void) - { - char *new_title; -@@ -227,17 +263,18 @@ int ssl_init(void) - new_title = add_xterm_umid(opts.xterm_title); - if(new_title != NULL) opts.xterm_title = new_title; - -+ register_console(&ssl_cons); - ssl_init_done = 1; - return(0); - } - --__initcall(ssl_init); -+late_initcall(ssl_init); - - static int ssl_chan_setup(char *str) - { -- line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]), -- str, 1); -- return(1); -+ return(line_setup(serial_lines, -+ sizeof(serial_lines)/sizeof(serial_lines[0]), -+ str, 1)); - } - - __setup("ssl", ssl_chan_setup); -diff -puN arch/um/drivers/stdio_console.c~Main-uml-patch-no-skas arch/um/drivers/stdio_console.c ---- uml-linux-2.6.7/arch/um/drivers/stdio_console.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.478324768 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/stdio_console.c 2004-06-29 21:02:55.715288744 +0200 -@@ -83,7 +83,8 @@ static int con_remove(char *str); - - static struct line_driver driver = { - .name = "UML console", -- .devfs_name = "vc/%d", -+ .device_name = "tty", -+ .devfs_name = "vc/", - .major = TTY_MAJOR, - .minor_start = 0, - .type = TTY_DRIVER_TYPE_CONSOLE, -@@ -159,6 +160,15 @@ static int chars_in_buffer(struct tty_st - - static int con_init_done = 0; - -+static struct tty_operations console_ops = { -+ .open = con_open, -+ .close = con_close, -+ .write = con_write, -+ .chars_in_buffer = chars_in_buffer, -+ .set_termios = set_termios, -+ .write_room = line_write_room, -+}; -+ - int stdio_init(void) - { - char *new_title; -@@ -166,7 +176,8 @@ int stdio_init(void) - printk(KERN_INFO "Initializing stdio console driver\n"); - - console_driver = line_register_devfs(&console_lines, &driver, -- &console_ops, vts, sizeof(vts)/sizeof(vts[0])); -+ &console_ops, vts, -+ sizeof(vts)/sizeof(vts[0])); - - lines_init(vts, sizeof(vts)/sizeof(vts[0])); - -@@ -178,24 +189,19 @@ int stdio_init(void) - return(0); - } - --__initcall(stdio_init); -+late_initcall(stdio_init); - - static void console_write(struct console *console, const char *string, - unsigned len) - { -- if(con_init_done) down(&vts[console->index].sem); -- console_write_chan(&vts[console->index].chan_list, string, len); -- if(con_init_done) up(&vts[console->index].sem); --} -+ struct line *line = &vts[console->index]; - --static struct tty_operations console_ops = { -- .open = con_open, -- .close = con_close, -- .write = con_write, -- .chars_in_buffer = chars_in_buffer, -- .set_termios = set_termios, -- .write_room = line_write_room, --}; -+ if(con_init_done) -+ down(&line->sem); -+ console_write_chan(&line->chan_list, string, len); -+ if(con_init_done) -+ up(&line->sem); -+} - - static struct tty_driver *console_device(struct console *c, int *index) - { -@@ -208,22 +214,28 @@ static int console_setup(struct console - return(0); - } - --static struct console stdiocons = INIT_CONSOLE("tty", console_write, -- console_device, console_setup, -- CON_PRINTBUFFER); -+static struct console stdiocons = { -+ name: "tty", -+ write: console_write, -+ device: console_device, -+ setup: console_setup, -+ flags: CON_PRINTBUFFER, -+ index: -1, -+}; - --static void __init stdio_console_init(void) -+static int __init stdio_console_init(void) - { - INIT_LIST_HEAD(&vts[0].chan_list); - list_add(&init_console_chan.list, &vts[0].chan_list); - register_console(&stdiocons); -+ return(0); - } -+ - console_initcall(stdio_console_init); - - static int console_chan_setup(char *str) - { -- line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1); -- return(1); -+ return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1)); - } - - __setup("con", console_chan_setup); -diff -puN arch/um/drivers/tty.c~Main-uml-patch-no-skas arch/um/drivers/tty.c ---- uml-linux-2.6.7/arch/um/drivers/tty.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.479324616 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/tty.c 2004-06-29 21:02:55.715288744 +0200 -@@ -5,7 +5,6 @@ - - #include <stdio.h> - #include <termios.h> --#include <fcntl.h> - #include <errno.h> - #include <unistd.h> - #include "chan_user.h" -@@ -30,7 +29,8 @@ void *tty_chan_init(char *str, int devic - } - str++; - -- if((data = um_kmalloc(sizeof(*data))) == NULL) -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) - return(NULL); - *data = ((struct tty_chan) { .dev = str, - .raw = opts->raw }); -diff -puN arch/um/drivers/ubd_kern.c~Main-uml-patch-no-skas arch/um/drivers/ubd_kern.c ---- uml-linux-2.6.7/arch/um/drivers/ubd_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.480324464 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/ubd_kern.c 2004-06-29 21:02:55.717288440 +0200 -@@ -8,6 +8,13 @@ - * old style ubd by setting UBD_SHIFT to 0 - * 2002-09-27...2002-10-18 massive tinkering for 2.5 - * partitions have changed in 2.5 -+ * 2003-01-29 more tinkering for 2.5.59-1 -+ * This should now address the sysfs problems and has -+ * the symlink for devfs to allow for booting with -+ * the common /dev/ubd/discX/... names rather than -+ * only /dev/ubdN/discN this version also has lots of -+ * clean ups preparing for ubd-many. -+ * James McMechan - */ - - #define MAJOR_NR UBD_MAJOR -@@ -40,9 +47,12 @@ - #include "mconsole_kern.h" - #include "init.h" - #include "irq_user.h" -+#include "irq_kern.h" - #include "ubd_user.h" - #include "2_5compat.h" - #include "os.h" -+#include "mem.h" -+#include "mem_kern.h" - - static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED; - static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED; -@@ -56,6 +66,10 @@ static int ubd_ioctl(struct inode * inod - - #define MAX_DEV (8) - -+/* Changed in early boot */ -+static int ubd_do_mmap = 0; -+#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE -+ - static struct block_device_operations ubd_blops = { - .owner = THIS_MODULE, - .open = ubd_open, -@@ -67,7 +81,7 @@ static struct block_device_operations ub - static request_queue_t *ubd_queue; - - /* Protected by ubd_lock */ --static int fake_major = 0; -+static int fake_major = MAJOR_NR; - - static struct gendisk *ubd_gendisk[MAX_DEV]; - static struct gendisk *fake_gendisk[MAX_DEV]; -@@ -96,13 +110,19 @@ struct cow { - - struct ubd { - char *file; -- int is_dir; - int count; - int fd; - __u64 size; - struct openflags boot_openflags; - struct openflags openflags; -+ int no_cow; - struct cow cow; -+ -+ int map_writes; -+ int map_reads; -+ int nomap_writes; -+ int nomap_reads; -+ int write_maps; - }; - - #define DEFAULT_COW { \ -@@ -115,21 +135,28 @@ struct ubd { - - #define DEFAULT_UBD { \ - .file = NULL, \ -- .is_dir = 0, \ - .count = 0, \ - .fd = -1, \ - .size = -1, \ - .boot_openflags = OPEN_FLAGS, \ - .openflags = OPEN_FLAGS, \ -+ .no_cow = 0, \ - .cow = DEFAULT_COW, \ -+ .map_writes = 0, \ -+ .map_reads = 0, \ -+ .nomap_writes = 0, \ -+ .nomap_reads = 0, \ -+ .write_maps = 0, \ - } - - struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; - - static int ubd0_init(void) - { -- if(ubd_dev[0].file == NULL) -- ubd_dev[0].file = "root_fs"; -+ struct ubd *dev = &ubd_dev[0]; -+ -+ if(dev->file == NULL) -+ dev->file = "root_fs"; - return(0); - } - -@@ -196,19 +223,46 @@ __uml_help(fake_ide_setup, - " Create ide0 entries that map onto ubd devices.\n\n" - ); - -+static int parse_unit(char **ptr) -+{ -+ char *str = *ptr, *end; -+ int n = -1; -+ -+ if(isdigit(*str)) { -+ n = simple_strtoul(str, &end, 0); -+ if(end == str) -+ return(-1); -+ *ptr = end; -+ } -+ else if (('a' <= *str) && (*str <= 'h')) { -+ n = *str - 'a'; -+ str++; -+ *ptr = str; -+ } -+ return(n); -+} -+ - static int ubd_setup_common(char *str, int *index_out) - { -+ struct ubd *dev; - struct openflags flags = global_openflags; - char *backing_file; - int n, err; - - if(index_out) *index_out = -1; -- n = *str++; -+ n = *str; - if(n == '='){ -- static int fake_major_allowed = 1; - char *end; - int major; - -+ str++; -+ if(!strcmp(str, "mmap")){ -+ CHOOSE_MODE(printk("mmap not supported by the ubd " -+ "driver in tt mode\n"), -+ ubd_do_mmap = 1); -+ return(0); -+ } -+ - if(!strcmp(str, "sync")){ - global_openflags.s = 1; - return(0); -@@ -220,20 +274,14 @@ static int ubd_setup_common(char *str, i - return(1); - } - -- if(!fake_major_allowed){ -- printk(KERN_ERR "Can't assign a fake major twice\n"); -- return(1); -- } -- - err = 1; - spin_lock(&ubd_lock); -- if(!fake_major_allowed){ -+ if(fake_major != MAJOR_NR){ - printk(KERN_ERR "Can't assign a fake major twice\n"); - goto out1; - } - - fake_major = major; -- fake_major_allowed = 0; - - printk(KERN_INFO "Setting extra ubd major number to %d\n", - major); -@@ -243,25 +291,23 @@ static int ubd_setup_common(char *str, i - return(err); - } - -- if(n < '0'){ -- printk(KERN_ERR "ubd_setup : index out of range\n"); } -- -- if((n >= '0') && (n <= '9')) n -= '0'; -- else if((n >= 'a') && (n <= 'z')) n -= 'a'; -- else { -- printk(KERN_ERR "ubd_setup : device syntax invalid\n"); -+ n = parse_unit(&str); -+ if(n < 0){ -+ printk(KERN_ERR "ubd_setup : couldn't parse unit number " -+ "'%s'\n", str); - return(1); - } - if(n >= MAX_DEV){ -- printk(KERN_ERR "ubd_setup : index out of range " -- "(%d devices)\n", MAX_DEV); -+ printk(KERN_ERR "ubd_setup : index %d out of range " -+ "(%d devices)\n", n, MAX_DEV); - return(1); - } - - err = 1; - spin_lock(&ubd_lock); - -- if(ubd_dev[n].file != NULL){ -+ dev = &ubd_dev[n]; -+ if(dev->file != NULL){ - printk(KERN_ERR "ubd_setup : device already configured\n"); - goto out2; - } -@@ -276,6 +322,11 @@ static int ubd_setup_common(char *str, i - flags.s = 1; - str++; - } -+ if (*str == 'd'){ -+ dev->no_cow = 1; -+ str++; -+ } -+ - if(*str++ != '='){ - printk(KERN_ERR "ubd_setup : Expected '='\n"); - goto out2; -@@ -284,14 +335,17 @@ static int ubd_setup_common(char *str, i - err = 0; - backing_file = strchr(str, ','); - if(backing_file){ -- *backing_file = '\0'; -- backing_file++; -+ if(dev->no_cow) -+ printk(KERN_ERR "Can't specify both 'd' and a " -+ "cow file\n"); -+ else { -+ *backing_file = '\0'; -+ backing_file++; -+ } - } -- ubd_dev[n].file = str; -- if(ubd_is_dir(ubd_dev[n].file)) -- ubd_dev[n].is_dir = 1; -- ubd_dev[n].cow.file = backing_file; -- ubd_dev[n].boot_openflags = flags; -+ dev->file = str; -+ dev->cow.file = backing_file; -+ dev->boot_openflags = flags; - out2: - spin_unlock(&ubd_lock); - return(err); -@@ -321,8 +375,7 @@ __uml_help(ubd_setup, - static int fakehd_set = 0; - static int fakehd(char *str) - { -- printk(KERN_INFO -- "fakehd : Changing ubd name to \"hd\".\n"); -+ printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n"); - fakehd_set = 1; - return 1; - } -@@ -368,32 +421,42 @@ static void ubd_handler(void) - { - struct io_thread_req req; - struct request *rq = elv_next_request(ubd_queue); -- int n; -+ int n, err; - - do_ubd = NULL; - intr_count++; - n = read_ubd_fs(thread_fd, &req, sizeof(req)); - if(n != sizeof(req)){ - printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " -- "errno = %d\n", os_getpid(), -n); -+ "err = %d\n", os_getpid(), -n); - spin_lock(&ubd_io_lock); - end_request(rq, 0); - spin_unlock(&ubd_io_lock); - return; - } - -- if((req.offset != ((__u64) (rq->sector)) << 9) || -- (req.length != (rq->current_nr_sectors) << 9)) -+ if((req.op != UBD_MMAP) && -+ ((req.offset != ((__u64) (rq->sector)) << 9) || -+ (req.length != (rq->current_nr_sectors) << 9))) - panic("I/O op mismatch"); - -+ if(req.map_fd != -1){ -+ err = physmem_subst_mapping(req.buffer, req.map_fd, -+ req.map_offset, 1); -+ if(err) -+ printk("ubd_handler - physmem_subst_mapping failed, " -+ "err = %d\n", -err); -+ } -+ - ubd_finish(rq, req.error); - reactivate_fd(thread_fd, UBD_IRQ); - do_ubd_request(ubd_queue); - } - --static void ubd_intr(int irq, void *dev, struct pt_regs *unused) -+static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused) - { - ubd_handler(); -+ return(IRQ_HANDLED); - } - - /* Only changed by ubd_init, which is an initcall. */ -@@ -417,10 +480,14 @@ static int ubd_file_size(struct ubd *dev - - static void ubd_close(struct ubd *dev) - { -+ if(ubd_do_mmap) -+ physmem_forget_descriptor(dev->fd); - os_close_file(dev->fd); - if(dev->cow.file == NULL) - return; - -+ if(ubd_do_mmap) -+ physmem_forget_descriptor(dev->cow.fd); - os_close_file(dev->cow.fd); - vfree(dev->cow.bitmap); - dev->cow.bitmap = NULL; -@@ -429,18 +496,20 @@ static void ubd_close(struct ubd *dev) - static int ubd_open_dev(struct ubd *dev) - { - struct openflags flags; -- int err, n, create_cow, *create_ptr; -+ char **back_ptr; -+ int err, create_cow, *create_ptr; - -+ dev->openflags = dev->boot_openflags; - create_cow = 0; - create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; -- dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file, -+ back_ptr = dev->no_cow ? NULL : &dev->cow.file; -+ dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr, - &dev->cow.bitmap_offset, &dev->cow.bitmap_len, - &dev->cow.data_offset, create_ptr); - - if((dev->fd == -ENOENT) && create_cow){ -- n = dev - ubd_dev; - dev->fd = create_cow_file(dev->file, dev->cow.file, -- dev->openflags, 1 << 9, -+ dev->openflags, 1 << 9, PAGE_SIZE, - &dev->cow.bitmap_offset, - &dev->cow.bitmap_len, - &dev->cow.data_offset); -@@ -455,13 +524,17 @@ static int ubd_open_dev(struct ubd *dev) - if(dev->cow.file != NULL){ - err = -ENOMEM; - dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len); -- if(dev->cow.bitmap == NULL) goto error; -+ if(dev->cow.bitmap == NULL){ -+ printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); -+ goto error; -+ } - flush_tlb_kernel_vm(); - - err = read_cow_bitmap(dev->fd, dev->cow.bitmap, - dev->cow.bitmap_offset, - dev->cow.bitmap_len); -- if(err) goto error; -+ if(err < 0) -+ goto error; - - flags = dev->openflags; - flags.w = 0; -@@ -481,17 +554,31 @@ static int ubd_new_disk(int major, u64 s - - { - struct gendisk *disk; -+ char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")]; -+ int err; - - disk = alloc_disk(1 << UBD_SHIFT); -- if (!disk) -- return -ENOMEM; -+ if(disk == NULL) -+ return(-ENOMEM); - - disk->major = major; - disk->first_minor = unit << UBD_SHIFT; - disk->fops = &ubd_blops; - set_capacity(disk, size / 512); -- sprintf(disk->disk_name, "ubd"); -- sprintf(disk->devfs_name, "ubd/disc%d", unit); -+ if(major == MAJOR_NR){ -+ sprintf(disk->disk_name, "ubd%c", 'a' + unit); -+ sprintf(disk->devfs_name, "ubd/disc%d", unit); -+ sprintf(from, "ubd/%d", unit); -+ sprintf(to, "disc%d/disc", unit); -+ err = devfs_mk_symlink(from, to); -+ if(err) -+ printk("ubd_new_disk failed to make link from %s to " -+ "%s, error = %d\n", from, to, err); -+ } -+ else { -+ sprintf(disk->disk_name, "ubd_fake%d", unit); -+ sprintf(disk->devfs_name, "ubd_fake/disc%d", unit); -+ } - - disk->private_data = &ubd_dev[unit]; - disk->queue = ubd_queue; -@@ -506,24 +593,21 @@ static int ubd_add(int n) - struct ubd *dev = &ubd_dev[n]; - int err; - -- if(dev->is_dir) -- return(-EISDIR); -- -- if (!dev->file) -+ if(dev->file == NULL) - return(-ENODEV); - - if (ubd_open_dev(dev)) - return(-ENODEV); - - err = ubd_file_size(dev, &dev->size); -- if(err) -+ if(err < 0) - return(err); - - err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); - if(err) - return(err); - -- if(fake_major) -+ if(fake_major != MAJOR_NR) - ubd_new_disk(fake_major, dev->size, n, - &fake_gendisk[n]); - -@@ -561,42 +645,42 @@ static int ubd_config(char *str) - return(err); - } - --static int ubd_get_config(char *dev, char *str, int size, char **error_out) -+static int ubd_get_config(char *name, char *str, int size, char **error_out) - { -- struct ubd *ubd; -+ struct ubd *dev; - char *end; -- int major, n = 0; -+ int n, len = 0; - -- major = simple_strtoul(dev, &end, 0); -- if((*end != '\0') || (end == dev)){ -- *error_out = "ubd_get_config : didn't parse major number"; -+ n = simple_strtoul(name, &end, 0); -+ if((*end != '\0') || (end == name)){ -+ *error_out = "ubd_get_config : didn't parse device number"; - return(-1); - } - -- if((major >= MAX_DEV) || (major < 0)){ -- *error_out = "ubd_get_config : major number out of range"; -+ if((n >= MAX_DEV) || (n < 0)){ -+ *error_out = "ubd_get_config : device number out of range"; - return(-1); - } - -- ubd = &ubd_dev[major]; -+ dev = &ubd_dev[n]; - spin_lock(&ubd_lock); - -- if(ubd->file == NULL){ -- CONFIG_CHUNK(str, size, n, "", 1); -+ if(dev->file == NULL){ -+ CONFIG_CHUNK(str, size, len, "", 1); - goto out; - } - -- CONFIG_CHUNK(str, size, n, ubd->file, 0); -+ CONFIG_CHUNK(str, size, len, dev->file, 0); - -- if(ubd->cow.file != NULL){ -- CONFIG_CHUNK(str, size, n, ",", 0); -- CONFIG_CHUNK(str, size, n, ubd->cow.file, 1); -+ if(dev->cow.file != NULL){ -+ CONFIG_CHUNK(str, size, len, ",", 0); -+ CONFIG_CHUNK(str, size, len, dev->cow.file, 1); - } -- else CONFIG_CHUNK(str, size, n, "", 1); -+ else CONFIG_CHUNK(str, size, len, "", 1); - - out: - spin_unlock(&ubd_lock); -- return(n); -+ return(len); - } - - static int ubd_remove(char *str) -@@ -604,11 +688,9 @@ static int ubd_remove(char *str) - struct ubd *dev; - int n, err = -ENODEV; - -- if(!isdigit(*str)) -- return(err); /* it should be a number 0-7/a-h */ -+ n = parse_unit(&str); - -- n = *str - '0'; -- if(n >= MAX_DEV) -+ if((n < 0) || (n >= MAX_DEV)) - return(err); - - dev = &ubd_dev[n]; -@@ -669,7 +751,7 @@ int ubd_init(void) - - elevator_init(ubd_queue, &elevator_noop); - -- if (fake_major != 0) { -+ if (fake_major != MAJOR_NR) { - char name[sizeof("ubd_nnn\0")]; - - snprintf(name, sizeof(name), "ubd_%d", fake_major); -@@ -696,6 +778,7 @@ int ubd_driver_init(void){ - io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), - &thread_fd); - if(io_pid < 0){ -+ io_pid = -1; - printk(KERN_ERR - "ubd : Failed to start I/O thread (errno = %d) - " - "falling back to synchronous I/O\n", -io_pid); -@@ -703,8 +786,8 @@ int ubd_driver_init(void){ - } - err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, - SA_INTERRUPT, "ubd", ubd_dev); -- if(err != 0) printk(KERN_ERR -- "um_request_irq failed - errno = %d\n", -err); -+ if(err != 0) -+ printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); - return(err); - } - -@@ -714,15 +797,9 @@ static int ubd_open(struct inode *inode, - { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ubd *dev = disk->private_data; -- int err = -EISDIR; -- -- if(dev->is_dir == 1) -- goto out; -+ int err = 0; - -- err = 0; - if(dev->count == 0){ -- dev->openflags = dev->boot_openflags; -- - err = ubd_open_dev(dev); - if(err){ - printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n", -@@ -749,62 +826,156 @@ static int ubd_release(struct inode * in - return(0); - } - --void cowify_req(struct io_thread_req *req, struct ubd *dev) -+static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, -+ __u64 *cow_offset, unsigned long *bitmap, -+ __u64 bitmap_offset, unsigned long *bitmap_words, -+ __u64 bitmap_len) -+{ -+ __u64 sector = io_offset >> 9; -+ int i, update_bitmap = 0; -+ -+ for(i = 0; i < length >> 9; i++){ -+ if(cow_mask != NULL) -+ ubd_set_bit(i, (unsigned char *) cow_mask); -+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) -+ continue; -+ -+ update_bitmap = 1; -+ ubd_set_bit(sector + i, (unsigned char *) bitmap); -+ } -+ -+ if(!update_bitmap) -+ return; -+ -+ *cow_offset = sector / (sizeof(unsigned long) * 8); -+ -+ /* This takes care of the case where we're exactly at the end of the -+ * device, and *cow_offset + 1 is off the end. So, just back it up -+ * by one word. Thanks to Lynn Kerby for the fix and James McMechan -+ * for the original diagnosis. -+ */ -+ if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / -+ sizeof(unsigned long) - 1)) -+ (*cow_offset)--; -+ -+ bitmap_words[0] = bitmap[*cow_offset]; -+ bitmap_words[1] = bitmap[*cow_offset + 1]; -+ -+ *cow_offset *= sizeof(unsigned long); -+ *cow_offset += bitmap_offset; -+} -+ -+static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, -+ __u64 bitmap_offset, __u64 bitmap_len) - { -- int i, update_bitmap, sector = req->offset >> 9; -+ __u64 sector = req->offset >> 9; -+ int i; - - if(req->length > (sizeof(req->sector_mask) * 8) << 9) - panic("Operation too long"); -+ - if(req->op == UBD_READ) { - for(i = 0; i < req->length >> 9; i++){ -- if(ubd_test_bit(sector + i, (unsigned char *) -- dev->cow.bitmap)){ -+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) - ubd_set_bit(i, (unsigned char *) - &req->sector_mask); -- } - } -- } -- else { -- update_bitmap = 0; -- for(i = 0; i < req->length >> 9; i++){ -- ubd_set_bit(i, (unsigned char *) -- &req->sector_mask); -- if(!ubd_test_bit(sector + i, (unsigned char *) -- dev->cow.bitmap)) -- update_bitmap = 1; -- ubd_set_bit(sector + i, (unsigned char *) -- dev->cow.bitmap); -- } -- if(update_bitmap){ -- req->cow_offset = sector / (sizeof(unsigned long) * 8); -- req->bitmap_words[0] = -- dev->cow.bitmap[req->cow_offset]; -- req->bitmap_words[1] = -- dev->cow.bitmap[req->cow_offset + 1]; -- req->cow_offset *= sizeof(unsigned long); -- req->cow_offset += dev->cow.bitmap_offset; -+ } -+ else cowify_bitmap(req->offset, req->length, &req->sector_mask, -+ &req->cow_offset, bitmap, bitmap_offset, -+ req->bitmap_words, bitmap_len); -+} -+ -+static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset) -+{ -+ __u64 sector; -+ unsigned char *bitmap; -+ int bit, i; -+ -+ /* mmap must have been requested on the command line */ -+ if(!ubd_do_mmap) -+ return(-1); -+ -+ /* The buffer must be page aligned */ -+ if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0) -+ return(-1); -+ -+ /* The request must be a page long */ -+ if((req->current_nr_sectors << 9) != PAGE_SIZE) -+ return(-1); -+ -+ if(dev->cow.file == NULL) -+ return(dev->fd); -+ -+ sector = offset >> 9; -+ bitmap = (unsigned char *) dev->cow.bitmap; -+ bit = ubd_test_bit(sector, bitmap); -+ -+ for(i = 1; i < req->current_nr_sectors; i++){ -+ if(ubd_test_bit(sector + i, bitmap) != bit) -+ return(-1); -+ } -+ -+ if(bit || (rq_data_dir(req) == WRITE)) -+ offset += dev->cow.data_offset; -+ -+ /* The data on disk must be page aligned */ -+ if((offset % UBD_MMAP_BLOCK_SIZE) != 0) -+ return(-1); -+ -+ return(bit ? dev->fd : dev->cow.fd); -+} -+ -+static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, -+ struct request *req, -+ struct io_thread_req *io_req) -+{ -+ int err; -+ -+ if(rq_data_dir(req) == WRITE){ -+ /* Writes are almost no-ops since the new data is already in the -+ * host page cache -+ */ -+ dev->map_writes++; -+ if(dev->cow.file != NULL) -+ cowify_bitmap(io_req->offset, io_req->length, -+ &io_req->sector_mask, &io_req->cow_offset, -+ dev->cow.bitmap, dev->cow.bitmap_offset, -+ io_req->bitmap_words, -+ dev->cow.bitmap_len); -+ } -+ else { -+ int w; -+ -+ if((dev->cow.file != NULL) && (fd == dev->cow.fd)) -+ w = 0; -+ else w = dev->openflags.w; -+ -+ if((dev->cow.file != NULL) && (fd == dev->fd)) -+ offset += dev->cow.data_offset; -+ -+ err = physmem_subst_mapping(req->buffer, fd, offset, w); -+ if(err){ -+ printk("physmem_subst_mapping failed, err = %d\n", -+ -err); -+ return(1); - } -+ dev->map_reads++; - } -+ io_req->op = UBD_MMAP; -+ io_req->buffer = req->buffer; -+ return(0); - } - - static int prepare_request(struct request *req, struct io_thread_req *io_req) - { - struct gendisk *disk = req->rq_disk; - struct ubd *dev = disk->private_data; -- __u64 block; -- int nsect; -+ __u64 offset; -+ int len, fd; - - if(req->rq_status == RQ_INACTIVE) return(1); - -- if(dev->is_dir){ -- strcpy(req->buffer, "HOSTFS:"); -- strcat(req->buffer, dev->file); -- spin_lock(&ubd_io_lock); -- end_request(req, 1); -- spin_unlock(&ubd_io_lock); -- return(1); -- } -- - if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ - printk("Write attempted on readonly ubd device %s\n", - disk->disk_name); -@@ -814,23 +985,49 @@ static int prepare_request(struct reques - return(1); - } - -- block = req->sector; -- nsect = req->current_nr_sectors; -+ offset = ((__u64) req->sector) << 9; -+ len = req->current_nr_sectors << 9; - -- io_req->op = rq_data_dir(req) == READ ? UBD_READ : UBD_WRITE; - io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; - io_req->fds[1] = dev->fd; -+ io_req->map_fd = -1; -+ io_req->cow_offset = -1; -+ io_req->offset = offset; -+ io_req->length = len; -+ io_req->error = 0; -+ io_req->sector_mask = 0; -+ -+ fd = mmap_fd(req, dev, io_req->offset); -+ if(fd > 0){ -+ /* If mmapping is otherwise OK, but the first access to the -+ * page is a write, then it's not mapped in yet. So we have -+ * to write the data to disk first, then we can map the disk -+ * page in and continue normally from there. -+ */ -+ if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){ -+ io_req->map_fd = dev->fd; -+ io_req->map_offset = io_req->offset + -+ dev->cow.data_offset; -+ dev->write_maps++; -+ } -+ else return(prepare_mmap_request(dev, fd, io_req->offset, req, -+ io_req)); -+ } -+ -+ if(rq_data_dir(req) == READ) -+ dev->nomap_reads++; -+ else dev->nomap_writes++; -+ -+ io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; - io_req->offsets[0] = 0; - io_req->offsets[1] = dev->cow.data_offset; -- io_req->offset = ((__u64) block) << 9; -- io_req->length = nsect << 9; - io_req->buffer = req->buffer; - io_req->sectorsize = 1 << 9; -- io_req->sector_mask = 0; -- io_req->cow_offset = -1; -- io_req->error = 0; - -- if(dev->cow.file != NULL) cowify_req(io_req, dev); -+ if(dev->cow.file != NULL) -+ cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset, -+ dev->cow.bitmap_len); -+ - return(0); - } - -@@ -841,7 +1038,7 @@ static void do_ubd_request(request_queue - int err, n; - - if(thread_fd == -1){ -- while(!list_empty(&q->queue_head)){ -+ while(!elv_queue_empty(q)){ - req = elv_next_request(q); - err = prepare_request(req, &io_req); - if(!err){ -@@ -851,7 +1048,8 @@ static void do_ubd_request(request_queue - } - } - else { -- if(do_ubd || list_empty(&q->queue_head)) return; -+ if(do_ubd || elv_queue_empty(q)) -+ return; - req = elv_next_request(q); - err = prepare_request(req, &io_req); - if(!err){ -@@ -885,7 +1083,7 @@ static int ubd_ioctl(struct inode * inod - g.heads = 128; - g.sectors = 32; - g.cylinders = dev->size / (128 * 32 * 512); -- g.start = 2; -+ g.start = get_start_sect(inode->i_bdev); - return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0); - - case HDIO_SET_UNMASKINTR: -@@ -935,6 +1133,142 @@ static int ubd_ioctl(struct inode * inod - return(-EINVAL); - } - -+static int ubd_check_remapped(int fd, unsigned long address, int is_write, -+ __u64 offset) -+{ -+ __u64 bitmap_offset; -+ unsigned long new_bitmap[2]; -+ int i, err, n; -+ -+ /* If it's not a write access, we can't do anything about it */ -+ if(!is_write) -+ return(0); -+ -+ /* We have a write */ -+ for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){ -+ struct ubd *dev = &ubd_dev[i]; -+ -+ if((dev->fd != fd) && (dev->cow.fd != fd)) -+ continue; -+ -+ /* It's a write to a ubd device */ -+ -+ if(!dev->openflags.w){ -+ /* It's a write access on a read-only device - probably -+ * shouldn't happen. If the kernel is trying to change -+ * something with no intention of writing it back out, -+ * then this message will clue us in that this needs -+ * fixing -+ */ -+ printk("Write access to mapped page from readonly ubd " -+ "device %d\n", i); -+ return(0); -+ } -+ -+ /* It's a write to a writeable ubd device - it must be COWed -+ * because, otherwise, the page would have been mapped in -+ * writeable -+ */ -+ -+ if(!dev->cow.file) -+ panic("Write fault on writeable non-COW ubd device %d", -+ i); -+ -+ /* It should also be an access to the backing file since the -+ * COW pages should be mapped in read-write -+ */ -+ -+ if(fd == dev->fd) -+ panic("Write fault on a backing page of ubd " -+ "device %d\n", i); -+ -+ /* So, we do the write, copying the backing data to the COW -+ * file... -+ */ -+ -+ err = os_seek_file(dev->fd, offset + dev->cow.data_offset); -+ if(err < 0) -+ panic("Couldn't seek to %lld in COW file of ubd " -+ "device %d, err = %d", -+ offset + dev->cow.data_offset, i, -err); -+ -+ n = os_write_file(dev->fd, (void *) address, PAGE_SIZE); -+ if(n != PAGE_SIZE) -+ panic("Couldn't copy data to COW file of ubd " -+ "device %d, err = %d", i, -n); -+ -+ /* ... updating the COW bitmap... */ -+ -+ cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, -+ dev->cow.bitmap, dev->cow.bitmap_offset, -+ new_bitmap, dev->cow.bitmap_len); -+ -+ err = os_seek_file(dev->fd, bitmap_offset); -+ if(err < 0) -+ panic("Couldn't seek to %lld in COW file of ubd " -+ "device %d, err = %d", bitmap_offset, i, -err); -+ -+ n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap)); -+ if(n != sizeof(new_bitmap)) -+ panic("Couldn't update bitmap of ubd device %d, " -+ "err = %d", i, -n); -+ -+ /* Maybe we can map the COW page in, and maybe we can't. If -+ * it is a pre-V3 COW file, we can't, since the alignment will -+ * be wrong. If it is a V3 or later COW file which has been -+ * moved to a system with a larger page size, then maybe we -+ * can't, depending on the exact location of the page. -+ */ -+ -+ offset += dev->cow.data_offset; -+ -+ /* Remove the remapping, putting the original anonymous page -+ * back. If the COW file can be mapped in, that is done. -+ * Otherwise, the COW page is read in. -+ */ -+ -+ if(!physmem_remove_mapping((void *) address)) -+ panic("Address 0x%lx not remapped by ubd device %d", -+ address, i); -+ if((offset % UBD_MMAP_BLOCK_SIZE) == 0) -+ physmem_subst_mapping((void *) address, dev->fd, -+ offset, 1); -+ else { -+ err = os_seek_file(dev->fd, offset); -+ if(err < 0) -+ panic("Couldn't seek to %lld in COW file of " -+ "ubd device %d, err = %d", offset, i, -+ -err); -+ -+ n = os_read_file(dev->fd, (void *) address, PAGE_SIZE); -+ if(n != PAGE_SIZE) -+ panic("Failed to read page from offset %llx of " -+ "COW file of ubd device %d, err = %d", -+ offset, i, -n); -+ } -+ -+ return(1); -+ } -+ -+ /* It's not a write on a ubd device */ -+ return(0); -+} -+ -+static struct remapper ubd_remapper = { -+ .list = LIST_HEAD_INIT(ubd_remapper.list), -+ .proc = ubd_check_remapped, -+}; -+ -+static int ubd_remapper_setup(void) -+{ -+ if(ubd_do_mmap) -+ register_remapper(&ubd_remapper); -+ -+ return(0); -+} -+ -+__initcall(ubd_remapper_setup); -+ - /* - * 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 -puN arch/um/drivers/ubd_user.c~Main-uml-patch-no-skas arch/um/drivers/ubd_user.c ---- uml-linux-2.6.7/arch/um/drivers/ubd_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.481324312 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/ubd_user.c 2004-06-29 21:02:55.718288288 +0200 -@@ -11,11 +11,8 @@ - #include <signal.h> - #include <string.h> - #include <netinet/in.h> --#include <sys/stat.h> - #include <sys/time.h> --#include <sys/fcntl.h> - #include <sys/socket.h> --#include <string.h> - #include <sys/mman.h> - #include <sys/param.h> - #include "asm/types.h" -@@ -24,146 +21,30 @@ - #include "user.h" - #include "ubd_user.h" - #include "os.h" -+#include "cow.h" - - #include <endian.h> - #include <byteswap.h> --#if __BYTE_ORDER == __BIG_ENDIAN --# define ntohll(x) (x) --# define htonll(x) (x) --#elif __BYTE_ORDER == __LITTLE_ENDIAN --# define ntohll(x) bswap_64(x) --# define htonll(x) bswap_64(x) --#else --#error "__BYTE_ORDER not defined" --#endif -- --#define PATH_LEN_V1 256 -- --struct cow_header_v1 { -- int magic; -- int version; -- char backing_file[PATH_LEN_V1]; -- time_t mtime; -- __u64 size; -- int sectorsize; --}; -- --#define PATH_LEN_V2 MAXPATHLEN -- --struct cow_header_v2 { -- unsigned long magic; -- unsigned long version; -- char backing_file[PATH_LEN_V2]; -- time_t mtime; -- __u64 size; -- int sectorsize; --}; -- --union cow_header { -- struct cow_header_v1 v1; -- struct cow_header_v2 v2; --}; -- --#define COW_MAGIC 0x4f4f4f4d /* MOOO */ --#define COW_VERSION 2 -- --static void sizes(__u64 size, int sectorsize, int bitmap_offset, -- unsigned long *bitmap_len_out, int *data_offset_out) --{ -- *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize); -- -- *data_offset_out = bitmap_offset + *bitmap_len_out; -- *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize; -- *data_offset_out *= sectorsize; --} -- --static int read_cow_header(int fd, int *magic_out, char **backing_file_out, -- time_t *mtime_out, __u64 *size_out, -- int *sectorsize_out, int *bitmap_offset_out) --{ -- union cow_header *header; -- char *file; -- int err, n; -- unsigned long version, magic; -- -- header = um_kmalloc(sizeof(*header)); -- if(header == NULL){ -- printk("read_cow_header - Failed to allocate header\n"); -- return(-ENOMEM); -- } -- err = -EINVAL; -- n = read(fd, header, sizeof(*header)); -- if(n < offsetof(typeof(header->v1), backing_file)){ -- printk("read_cow_header - short header\n"); -- goto out; -- } -- -- magic = header->v1.magic; -- if(magic == COW_MAGIC) { -- version = header->v1.version; -- } -- else if(magic == ntohl(COW_MAGIC)){ -- version = ntohl(header->v1.version); -- } -- else goto out; -- -- *magic_out = COW_MAGIC; -- -- if(version == 1){ -- if(n < sizeof(header->v1)){ -- printk("read_cow_header - failed to read V1 header\n"); -- goto out; -- } -- *mtime_out = header->v1.mtime; -- *size_out = header->v1.size; -- *sectorsize_out = header->v1.sectorsize; -- *bitmap_offset_out = sizeof(header->v1); -- file = header->v1.backing_file; -- } -- else if(version == 2){ -- if(n < sizeof(header->v2)){ -- printk("read_cow_header - failed to read V2 header\n"); -- goto out; -- } -- *mtime_out = ntohl(header->v2.mtime); -- *size_out = ntohll(header->v2.size); -- *sectorsize_out = ntohl(header->v2.sectorsize); -- *bitmap_offset_out = sizeof(header->v2); -- file = header->v2.backing_file; -- } -- else { -- printk("read_cow_header - invalid COW version\n"); -- goto out; -- } -- err = -ENOMEM; -- *backing_file_out = uml_strdup(file); -- if(*backing_file_out == NULL){ -- printk("read_cow_header - failed to allocate backing file\n"); -- goto out; -- } -- err = 0; -- out: -- kfree(header); -- return(err); --} - - static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) - { -- struct stat buf1, buf2; -+ struct uml_stat buf1, buf2; -+ int err; - - if(from_cmdline == NULL) return(1); - if(!strcmp(from_cmdline, from_cow)) return(1); - -- if(stat(from_cmdline, &buf1) < 0){ -- printk("Couldn't stat '%s', errno = %d\n", from_cmdline, -- errno); -+ err = os_stat_file(from_cmdline, &buf1); -+ if(err < 0){ -+ printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err); - return(1); - } -- if(stat(from_cow, &buf2) < 0){ -- printk("Couldn't stat '%s', errno = %d\n", from_cow, errno); -+ err = os_stat_file(from_cow, &buf2); -+ if(err < 0){ -+ printk("Couldn't stat '%s', err = %d\n", from_cow, -err); - return(1); - } -- if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino)) -+ if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino)) - return(1); - - printk("Backing file mismatch - \"%s\" requested,\n" -@@ -174,20 +55,21 @@ static int same_backing_files(char *from - - static int backing_file_mismatch(char *file, __u64 size, time_t mtime) - { -- struct stat64 buf; -+ unsigned long modtime; - long long actual; - int err; - -- if(stat64(file, &buf) < 0){ -- printk("Failed to stat backing file \"%s\", errno = %d\n", -- file, errno); -- return(-errno); -+ err = os_file_modtime(file, &modtime); -+ if(err < 0){ -+ printk("Failed to get modification time of backing file " -+ "\"%s\", err = %d\n", file, -err); -+ return(err); - } - - err = os_file_size(file, &actual); -- if(err){ -+ if(err < 0){ - printk("Failed to get size of backing file \"%s\", " -- "errno = %d\n", file, -err); -+ "err = %d\n", file, -err); - return(err); - } - -@@ -196,9 +78,9 @@ static int backing_file_mismatch(char *f - "file\n", size, actual); - return(-EINVAL); - } -- if(buf.st_mtime != mtime){ -+ if(modtime != mtime){ - printk("mtime mismatch (%ld vs %ld) of COW header vs backing " -- "file\n", mtime, buf.st_mtime); -+ "file\n", mtime, modtime); - return(-EINVAL); - } - return(0); -@@ -209,124 +91,16 @@ int read_cow_bitmap(int fd, void *buf, i - int err; - - err = os_seek_file(fd, offset); -- if(err != 0) return(-errno); -- err = read(fd, buf, len); -- if(err < 0) return(-errno); -- return(0); --} -+ if(err < 0) -+ return(err); - --static int absolutize(char *to, int size, char *from) --{ -- char save_cwd[256], *slash; -- int remaining; -+ err = os_read_file(fd, buf, len); -+ if(err < 0) -+ return(err); - -- if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) { -- printk("absolutize : unable to get cwd - errno = %d\n", errno); -- return(-1); -- } -- slash = strrchr(from, '/'); -- if(slash != NULL){ -- *slash = '\0'; -- if(chdir(from)){ -- *slash = '/'; -- printk("absolutize : Can't cd to '%s' - errno = %d\n", -- from, errno); -- return(-1); -- } -- *slash = '/'; -- if(getcwd(to, size) == NULL){ -- printk("absolutize : unable to get cwd of '%s' - " -- "errno = %d\n", from, errno); -- return(-1); -- } -- remaining = size - strlen(to); -- if(strlen(slash) + 1 > remaining){ -- printk("absolutize : unable to fit '%s' into %d " -- "chars\n", from, size); -- return(-1); -- } -- strcat(to, slash); -- } -- else { -- if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){ -- printk("absolutize : unable to fit '%s' into %d " -- "chars\n", from, size); -- return(-1); -- } -- strcpy(to, save_cwd); -- strcat(to, "/"); -- strcat(to, from); -- } -- chdir(save_cwd); - return(0); - } - --static int write_cow_header(char *cow_file, int fd, char *backing_file, -- int sectorsize, long long *size) --{ -- struct cow_header_v2 *header; -- struct stat64 buf; -- int err; -- -- err = os_seek_file(fd, 0); -- if(err != 0){ -- printk("write_cow_header - lseek failed, errno = %d\n", errno); -- return(-errno); -- } -- -- err = -ENOMEM; -- header = um_kmalloc(sizeof(*header)); -- if(header == NULL){ -- printk("Failed to allocate COW V2 header\n"); -- goto out; -- } -- header->magic = htonl(COW_MAGIC); -- header->version = htonl(COW_VERSION); -- -- err = -EINVAL; -- if(strlen(backing_file) > sizeof(header->backing_file) - 1){ -- printk("Backing file name \"%s\" is too long - names are " -- "limited to %d characters\n", backing_file, -- sizeof(header->backing_file) - 1); -- goto out_free; -- } -- -- if(absolutize(header->backing_file, sizeof(header->backing_file), -- backing_file)) -- goto out_free; -- -- err = stat64(header->backing_file, &buf); -- if(err < 0){ -- printk("Stat of backing file '%s' failed, errno = %d\n", -- header->backing_file, errno); -- err = -errno; -- goto out_free; -- } -- -- err = os_file_size(header->backing_file, size); -- if(err){ -- printk("Couldn't get size of backing file '%s', errno = %d\n", -- header->backing_file, -*size); -- goto out_free; -- } -- -- header->mtime = htonl(buf.st_mtime); -- header->size = htonll(*size); -- header->sectorsize = htonl(sectorsize); -- -- err = write(fd, header, sizeof(*header)); -- if(err != sizeof(*header)){ -- printk("Write of header to new COW file '%s' failed, " -- "errno = %d\n", cow_file, errno); -- goto out_free; -- } -- err = 0; -- out_free: -- kfree(header); -- out: -- return(err); --} -- - int open_ubd_file(char *file, struct openflags *openflags, - char **backing_file_out, int *bitmap_offset_out, - unsigned long *bitmap_len_out, int *data_offset_out, -@@ -334,26 +108,36 @@ int open_ubd_file(char *file, struct ope - { - time_t mtime; - __u64 size; -+ __u32 version, align; - char *backing_file; -- int fd, err, sectorsize, magic, same, mode = 0644; -+ int fd, err, sectorsize, same, mode = 0644; - -- if((fd = os_open_file(file, *openflags, mode)) < 0){ -+ fd = os_open_file(file, *openflags, mode); -+ if(fd < 0){ - if((fd == -ENOENT) && (create_cow_out != NULL)) - *create_cow_out = 1; - if(!openflags->w || - ((errno != EROFS) && (errno != EACCES))) return(-errno); - openflags->w = 0; -- if((fd = os_open_file(file, *openflags, mode)) < 0) -+ fd = os_open_file(file, *openflags, mode); -+ if(fd < 0) - return(fd); - } -+ -+ err = os_lock_file(fd, openflags->w); -+ if(err < 0){ -+ printk("Failed to lock '%s', err = %d\n", file, -err); -+ goto out_close; -+ } -+ - if(backing_file_out == NULL) return(fd); - -- err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, -- §orsize, bitmap_offset_out); -+ err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, -+ &size, §orsize, &align, bitmap_offset_out); - if(err && (*backing_file_out != NULL)){ - printk("Failed to read COW header from COW file \"%s\", " -- "errno = %d\n", file, err); -- goto error; -+ "errno = %d\n", file, -err); -+ goto out_close; - } - if(err) return(fd); - -@@ -363,36 +147,33 @@ int open_ubd_file(char *file, struct ope - - if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){ - printk("Switching backing file to '%s'\n", *backing_file_out); -- err = write_cow_header(file, fd, *backing_file_out, -- sectorsize, &size); -+ err = write_cow_header(file, fd, *backing_file_out, -+ sectorsize, align, &size); - if(err){ -- printk("Switch failed, errno = %d\n", err); -+ printk("Switch failed, errno = %d\n", -err); - return(err); - } - } - else { - *backing_file_out = backing_file; - err = backing_file_mismatch(*backing_file_out, size, mtime); -- if(err) goto error; -+ if(err) goto out_close; - } - -- sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, -- data_offset_out); -+ cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, -+ bitmap_len_out, data_offset_out); - - return(fd); -- error: -- close(fd); -+ out_close: -+ os_close_file(fd); - return(err); - } - - int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, -- int sectorsize, int *bitmap_offset_out, -+ int sectorsize, int alignment, int *bitmap_offset_out, - unsigned long *bitmap_len_out, int *data_offset_out) - { -- __u64 blocks; -- long zero; -- int err, fd, i; -- long long size; -+ int err, fd; - - flags.c = 1; - fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL); -@@ -403,57 +184,49 @@ int create_cow_file(char *cow_file, char - goto out; - } - -- err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size); -- if(err) goto out_close; -- -- blocks = (size + sectorsize - 1) / sectorsize; -- blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8); -- zero = 0; -- for(i = 0; i < blocks; i++){ -- err = write(fd, &zero, sizeof(zero)); -- if(err != sizeof(zero)){ -- printk("Write of bitmap to new COW file '%s' failed, " -- "errno = %d\n", cow_file, errno); -- goto out_close; -- } -- } -- -- sizes(size, sectorsize, sizeof(struct cow_header_v2), -- bitmap_len_out, data_offset_out); -- *bitmap_offset_out = sizeof(struct cow_header_v2); -- -- return(fd); -- -- out_close: -- close(fd); -+ err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment, -+ bitmap_offset_out, bitmap_len_out, -+ data_offset_out); -+ if(!err) -+ return(fd); -+ os_close_file(fd); - out: - return(err); - } - -+/* XXX Just trivial wrappers around os_read_file and os_write_file */ - int read_ubd_fs(int fd, void *buffer, int len) - { -- int n; -- -- n = read(fd, buffer, len); -- if(n < 0) return(-errno); -- else return(n); -+ return(os_read_file(fd, buffer, len)); - } - - int write_ubd_fs(int fd, char *buffer, int len) - { -- int n; -- -- n = write(fd, buffer, len); -- if(n < 0) return(-errno); -- else return(n); -+ return(os_write_file(fd, buffer, len)); - } - --int ubd_is_dir(char *file) -+static int update_bitmap(struct io_thread_req *req) - { -- struct stat64 buf; -+ int n; -+ -+ if(req->cow_offset == -1) -+ return(0); -+ -+ n = os_seek_file(req->fds[1], req->cow_offset); -+ if(n < 0){ -+ printk("do_io - bitmap lseek failed : err = %d\n", -n); -+ return(1); -+ } -+ -+ n = os_write_file(req->fds[1], &req->bitmap_words, -+ sizeof(req->bitmap_words)); -+ if(n != sizeof(req->bitmap_words)){ -+ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, -+ req->fds[1]); -+ return(1); -+ } - -- if(stat64(file, &buf) < 0) return(0); -- return(S_ISDIR(buf.st_mode)); -+ return(0); - } - - void do_io(struct io_thread_req *req) -@@ -461,8 +234,18 @@ void do_io(struct io_thread_req *req) - char *buf; - unsigned long len; - int n, nsectors, start, end, bit; -+ int err; - __u64 off; - -+ if(req->op == UBD_MMAP){ -+ /* Touch the page to force the host to do any necessary IO to -+ * get it into memory -+ */ -+ n = *((volatile int *) req->buffer); -+ req->error = update_bitmap(req); -+ return; -+ } -+ - nsectors = req->length / req->sectorsize; - start = 0; - do { -@@ -473,15 +256,14 @@ void do_io(struct io_thread_req *req) - &req->sector_mask) == bit)) - end++; - -- if(end != nsectors) -- printk("end != nsectors\n"); - off = req->offset + req->offsets[bit] + - start * req->sectorsize; - len = (end - start) * req->sectorsize; - buf = &req->buffer[start * req->sectorsize]; - -- if(os_seek_file(req->fds[bit], off) != 0){ -- printk("do_io - lseek failed : errno = %d\n", errno); -+ err = os_seek_file(req->fds[bit], off); -+ if(err < 0){ -+ printk("do_io - lseek failed : err = %d\n", -err); - req->error = 1; - return; - } -@@ -490,11 +272,10 @@ void do_io(struct io_thread_req *req) - do { - buf = &buf[n]; - len -= n; -- n = read(req->fds[bit], buf, len); -+ n = os_read_file(req->fds[bit], buf, len); - if (n < 0) { -- printk("do_io - read returned %d : " -- "errno = %d fd = %d\n", n, -- errno, req->fds[bit]); -+ printk("do_io - read failed, err = %d " -+ "fd = %d\n", -n, req->fds[bit]); - req->error = 1; - return; - } -@@ -502,11 +283,10 @@ void do_io(struct io_thread_req *req) - if (n < len) memset(&buf[n], 0, len - n); - } - else { -- n = write(req->fds[bit], buf, len); -+ n = os_write_file(req->fds[bit], buf, len); - if(n != len){ -- printk("do_io - write returned %d : " -- "errno = %d fd = %d\n", n, -- errno, req->fds[bit]); -+ printk("do_io - write failed err = %d " -+ "fd = %d\n", -n, req->fds[bit]); - req->error = 1; - return; - } -@@ -515,24 +295,7 @@ void do_io(struct io_thread_req *req) - start = end; - } while(start < nsectors); - -- if(req->cow_offset != -1){ -- if(os_seek_file(req->fds[1], req->cow_offset) != 0){ -- printk("do_io - bitmap lseek failed : errno = %d\n", -- errno); -- req->error = 1; -- return; -- } -- n = write(req->fds[1], &req->bitmap_words, -- sizeof(req->bitmap_words)); -- if(n != sizeof(req->bitmap_words)){ -- printk("do_io - bitmap update returned %d : " -- "errno = %d fd = %d\n", n, errno, req->fds[1]); -- req->error = 1; -- return; -- } -- } -- req->error = 0; -- return; -+ req->error = update_bitmap(req); - } - - /* Changed in start_io_thread, which is serialized by being called only -@@ -550,19 +313,23 @@ int io_thread(void *arg) - - signal(SIGWINCH, SIG_IGN); - while(1){ -- n = read(kernel_fd, &req, sizeof(req)); -- if(n < 0) printk("io_thread - read returned %d, errno = %d\n", -- n, errno); -- else if(n < sizeof(req)){ -- printk("io_thread - short read : length = %d\n", n); -+ n = os_read_file(kernel_fd, &req, sizeof(req)); -+ if(n != sizeof(req)){ -+ if(n < 0) -+ printk("io_thread - read failed, fd = %d, " -+ "err = %d\n", kernel_fd, -n); -+ else { -+ printk("io_thread - short read, fd = %d, " -+ "length = %d\n", kernel_fd, n); -+ } - continue; - } - io_count++; - do_io(&req); -- n = write(kernel_fd, &req, sizeof(req)); -+ n = os_write_file(kernel_fd, &req, sizeof(req)); - if(n != sizeof(req)) -- printk("io_thread - write failed, errno = %d\n", -- errno); -+ printk("io_thread - write failed, fd = %d, err = %d\n", -+ kernel_fd, -n); - } - } - -@@ -571,10 +338,11 @@ int start_io_thread(unsigned long sp, in - int pid, fds[2], err; - - err = os_pipe(fds, 1, 1); -- if(err){ -- printk("start_io_thread - os_pipe failed, errno = %d\n", -err); -- return(-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]; - -@@ -582,32 +350,19 @@ int start_io_thread(unsigned long sp, in - NULL); - if(pid < 0){ - printk("start_io_thread - clone failed : errno = %d\n", errno); -- return(-errno); -+ goto out_close; - } -- return(pid); --} -- --#ifdef notdef --int start_io_thread(unsigned long sp, int *fd_out) --{ -- int pid; - -- if((kernel_fd = get_pty()) < 0) return(-1); -- raw(kernel_fd, 0); -- if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){ -- printk("Couldn't open tty for IO\n"); -- return(-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); -- return(-errno); -- } - return(pid); -+ -+ out_close: -+ os_close_file(fds[0]); -+ os_close_file(fds[1]); -+ kernel_fd = -1; -+ *fd_out = -1; -+ out: -+ return(err); - } --#endif - - /* - * Overrides for Emacs so that we follow Linus's tabbing style. -diff -puN arch/um/drivers/xterm.c~Main-uml-patch-no-skas arch/um/drivers/xterm.c ---- uml-linux-2.6.7/arch/um/drivers/xterm.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.483324008 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/xterm.c 2004-06-29 21:02:55.718288288 +0200 -@@ -8,7 +8,6 @@ - #include <unistd.h> - #include <string.h> - #include <errno.h> --#include <fcntl.h> - #include <termios.h> - #include <signal.h> - #include <sched.h> -@@ -36,7 +35,8 @@ void *xterm_init(char *str, int device, - { - struct xterm_chan *data; - -- if((data = malloc(sizeof(*data))) == NULL) return(NULL); -+ data = malloc(sizeof(*data)); -+ if(data == NULL) return(NULL); - *data = ((struct xterm_chan) { .pid = -1, - .helper_pid = -1, - .device = device, -@@ -93,7 +93,7 @@ int xterm_open(int input, int output, in - "/usr/lib/uml/port-helper", "-uml-socket", - file, NULL }; - -- if(access(argv[4], X_OK)) -+ if(os_access(argv[4], OS_ACC_X_OK) < 0) - argv[4] = "port-helper"; - - fd = mkstemp(file); -@@ -106,13 +106,13 @@ int xterm_open(int input, int output, in - printk("xterm_open : unlink failed, errno = %d\n", errno); - return(-errno); - } -- close(fd); -+ os_close_file(fd); - -- fd = create_unix_socket(file, sizeof(file)); -+ fd = os_create_unix_socket(file, sizeof(file), 1); - if(fd < 0){ - printk("xterm_open : create_unix_socket failed, errno = %d\n", - -fd); -- return(-fd); -+ return(fd); - } - - sprintf(title, data->title, data->device); -@@ -128,15 +128,16 @@ int xterm_open(int input, int output, in - if(data->direct_rcv) - new = os_rcv_fd(fd, &data->helper_pid); - else { -- if((err = os_set_fd_block(fd, 0)) != 0){ -+ err = os_set_fd_block(fd, 0); -+ if(err < 0){ - printk("xterm_open : failed to set descriptor " -- "non-blocking, errno = %d\n", err); -+ "non-blocking, err = %d\n", -err); - return(err); - } - new = xterm_fd(fd, &data->helper_pid); - } - if(new < 0){ -- printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new); -+ printk("xterm_open : os_rcv_fd failed, err = %d\n", -new); - goto out; - } - -@@ -160,7 +161,7 @@ void xterm_close(int fd, void *d) - if(data->helper_pid != -1) - os_kill_process(data->helper_pid, 0); - data->helper_pid = -1; -- close(fd); -+ os_close_file(fd); - } - - void xterm_free(void *d) -diff -puN arch/um/drivers/xterm_kern.c~Main-uml-patch-no-skas arch/um/drivers/xterm_kern.c ---- uml-linux-2.6.7/arch/um/drivers/xterm_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.484323856 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/xterm_kern.c 2004-06-29 21:02:55.719288136 +0200 -@@ -5,9 +5,12 @@ - - #include "linux/errno.h" - #include "linux/slab.h" -+#include "linux/signal.h" -+#include "linux/interrupt.h" - #include "asm/semaphore.h" - #include "asm/irq.h" - #include "irq_user.h" -+#include "irq_kern.h" - #include "kern_util.h" - #include "os.h" - #include "xterm.h" -@@ -19,17 +22,18 @@ struct xterm_wait { - int new_fd; - }; - --static void xterm_interrupt(int irq, void *data, struct pt_regs *regs) -+static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs) - { - struct xterm_wait *xterm = data; - int fd; - - fd = os_rcv_fd(xterm->fd, &xterm->pid); - if(fd == -EAGAIN) -- return; -+ return(IRQ_NONE); - - xterm->new_fd = fd; - up(&xterm->sem); -+ return(IRQ_HANDLED); - } - - int xterm_fd(int socket, int *pid_out) -@@ -54,7 +58,8 @@ int xterm_fd(int socket, int *pid_out) - if(err){ - printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " - "err = %d\n", err); -- return(err); -+ ret = err; -+ goto out; - } - down(&data->sem); - -@@ -62,6 +67,7 @@ int xterm_fd(int socket, int *pid_out) - - ret = data->new_fd; - *pid_out = data->pid; -+ out: - kfree(data); - - return(ret); -diff -puN arch/um/dyn.lds.S~Main-uml-patch-no-skas arch/um/dyn.lds.S ---- uml-linux-2.6.7/arch/um/dyn.lds.S~Main-uml-patch-no-skas 2004-06-29 21:02:55.485323704 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/dyn.lds.S 2004-06-29 21:02:55.719288136 +0200 -@@ -1,3 +1,5 @@ -+#include <asm-generic/vmlinux.lds.h> -+ - OUTPUT_FORMAT(ELF_FORMAT) - OUTPUT_ARCH(ELF_ARCH) - ENTRY(_start) -@@ -10,12 +12,15 @@ SECTIONS - { - . = START + SIZEOF_HEADERS; - .interp : { *(.interp) } -- . = ALIGN(4096); - __binary_start = .; - . = ALIGN(4096); /* Init code and data */ - _stext = .; - __init_begin = .; -- .text.init : { *(.text.init) } -+ .init.text : { -+ _sinittext = .; -+ *(.init.text) -+ _einittext = .; -+ } - - . = ALIGN(4096); - -@@ -55,7 +60,9 @@ SECTIONS - } =0x90909090 - .plt : { *(.plt) } - .text : { -- *(.text .stub .text.* .gnu.linkonce.t.*) -+ *(.text) -+ SCHED_TEXT -+ *(.stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } =0x90909090 -@@ -67,7 +74,7 @@ SECTIONS - - #include "asm/common.lds.S" - -- .data.init : { *(.data.init) } -+ init.data : { *(.init.data) } - - /* Ensure the __preinit_array_start label is properly aligned. We - could instead move the label definition inside the section, but -diff -puN arch/um/include/2_5compat.h~Main-uml-patch-no-skas arch/um/include/2_5compat.h ---- uml-linux-2.6.7/arch/um/include/2_5compat.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.486323552 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/2_5compat.h 2004-06-29 21:02:55.719288136 +0200 -@@ -6,20 +6,6 @@ - #ifndef __2_5_COMPAT_H__ - #define __2_5_COMPAT_H__ - --#include "linux/version.h" -- --#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \ -- name : dev_name, \ -- write : write_proc, \ -- read : NULL, \ -- device : device_proc, \ -- setup : setup_proc, \ -- flags : f, \ -- index : -1, \ -- cflag : 0, \ -- next : NULL \ --} -- - #define INIT_HARDSECT(arr, maj, sizes) - - #define SET_PRI(task) do ; while(0) -diff -puN /dev/null arch/um/include/irq_kern.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/include/irq_kern.h 2004-06-29 21:02:55.719288136 +0200 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __IRQ_KERN_H__ -+#define __IRQ_KERN_H__ -+ -+#include "linux/interrupt.h" -+ -+extern int um_request_irq(unsigned int irq, int fd, int type, -+ irqreturn_t (*handler)(int, void *, -+ struct pt_regs *), -+ unsigned long irqflags, const char * devname, -+ void *dev_id); -+ -+#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 -puN arch/um/include/kern_util.h~Main-uml-patch-no-skas arch/um/include/kern_util.h ---- uml-linux-2.6.7/arch/um/include/kern_util.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.487323400 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/kern_util.h 2004-06-29 21:02:55.720287984 +0200 -@@ -60,12 +60,11 @@ extern void finish_fork(void); - extern void paging_init(void); - extern void init_flush_vm(void); - extern void *syscall_sp(void *t); --extern void syscall_trace(void); -+extern void syscall_trace(union uml_pt_regs *regs, int entryexit); - extern int hz(void); --extern void idle_timer(void); -+extern void uml_idle_timer(void); - extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); - extern int external_pid(void *t); --extern int pid_to_processor_id(int pid); - extern void boot_timer_handler(int sig); - extern void interrupt_end(void); - extern void initial_thread_cb(void (*proc)(void *), void *arg); -@@ -89,9 +88,7 @@ extern int remove_gdb(void); - extern char *uml_strdup(char *string); - extern void unprotect_kernel_mem(void); - extern void protect_kernel_mem(void); --extern void set_kmem_end(unsigned long); - extern void uml_cleanup(void); --extern int pid_to_processor_id(int pid); - extern void set_current(void *t); - extern void lock_signalled_task(void *t); - extern void IPI_handler(int cpu); -@@ -100,7 +97,9 @@ extern void *get_init_task(void); - extern int clear_user_proc(void *buf, int size); - extern int copy_to_user_proc(void *to, void *from, int size); - extern int copy_from_user_proc(void *to, void *from, int size); -+extern int strlen_user_proc(char *str); - extern void bus_handler(int sig, union uml_pt_regs *regs); -+extern void winch(int sig, union uml_pt_regs *regs); - extern long execute_syscall(void *r); - extern int smp_sigio_handler(void); - extern void *get_current(void); -@@ -111,6 +110,8 @@ extern void arch_switch(void); - extern void free_irq(unsigned int, void *); - extern int um_in_interrupt(void); - extern int cpu(void); -+extern unsigned long long time_stamp(void); -+ - #endif - - /* -diff -puN arch/um/include/line.h~Main-uml-patch-no-skas arch/um/include/line.h ---- uml-linux-2.6.7/arch/um/include/line.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.488323248 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/line.h 2004-06-29 21:02:55.720287984 +0200 -@@ -9,12 +9,14 @@ - #include "linux/list.h" - #include "linux/workqueue.h" - #include "linux/tty.h" -+#include "linux/interrupt.h" - #include "asm/semaphore.h" - #include "chan_user.h" - #include "mconsole_kern.h" - - struct line_driver { - char *name; -+ char *device_name; - char *devfs_name; - short major; - short minor_start; -@@ -67,8 +69,6 @@ struct lines { - - #define LINES_INIT(n) { num : n } - --extern void line_interrupt(int irq, void *data, struct pt_regs *unused); --extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused); - extern void line_close(struct line *lines, struct tty_struct *tty); - extern int line_open(struct line *lines, struct tty_struct *tty, - struct chan_opts *opts); -diff -puN arch/um/include/mconsole.h~Main-uml-patch-no-skas arch/um/include/mconsole.h ---- uml-linux-2.6.7/arch/um/include/mconsole.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.489323096 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/mconsole.h 2004-06-29 21:02:55.720287984 +0200 -@@ -41,11 +41,13 @@ struct mconsole_notify { - - struct mc_request; - -+enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC }; -+ - struct mconsole_command - { - char *command; - void (*handler)(struct mc_request *req); -- int as_interrupt; -+ enum mc_context context; - }; - - struct mc_request -@@ -77,6 +79,8 @@ extern void mconsole_sysrq(struct mc_req - extern void mconsole_cad(struct mc_request *req); - 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 int mconsole_get_request(int fd, struct mc_request *req); - extern int mconsole_notify(char *sock_name, int type, const void *data, -diff -puN arch/um/include/mem.h~Main-uml-patch-no-skas arch/um/include/mem.h ---- uml-linux-2.6.7/arch/um/include/mem.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.490322944 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/mem.h 2004-06-29 21:02:55.720287984 +0200 -@@ -1,19 +1,18 @@ - /* -- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - - #ifndef __MEM_H__ - #define __MEM_H__ - --struct vm_reserved { -- struct list_head list; -- unsigned long start; -- unsigned long end; --}; -+#include "linux/types.h" - --extern void set_usable_vm(unsigned long start, unsigned long end); --extern void set_kmem_end(unsigned long new); -+extern int phys_mapping(unsigned long phys, __u64 *offset_out); -+extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w); -+extern int is_remapped(void *virt); -+extern int physmem_remove_mapping(void *virt); -+extern void physmem_forget_descriptor(int fd); - - #endif - -diff -puN /dev/null arch/um/include/mem_kern.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/include/mem_kern.h 2004-06-29 21:02:55.721287832 +0200 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MEM_KERN_H__ -+#define __MEM_KERN_H__ -+ -+#include "linux/list.h" -+#include "linux/types.h" -+ -+struct remapper { -+ struct list_head list; -+ int (*proc)(int, unsigned long, int, __u64); -+}; -+ -+extern void register_remapper(struct remapper *info); -+ -+#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 -puN arch/um/include/mem_user.h~Main-uml-patch-no-skas arch/um/include/mem_user.h ---- uml-linux-2.6.7/arch/um/include/mem_user.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.492322640 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/mem_user.h 2004-06-29 21:02:55.721287832 +0200 -@@ -32,43 +32,38 @@ - #ifndef _MEM_USER_H - #define _MEM_USER_H - --struct mem_region { -+struct iomem_region { -+ struct iomem_region *next; - char *driver; -- unsigned long start_pfn; -- unsigned long start; -- unsigned long len; -- void *mem_map; - int fd; -+ int size; -+ unsigned long phys; -+ unsigned long virt; - }; - --extern struct mem_region *regions[]; --extern struct mem_region physmem_region; -+extern struct iomem_region *iomem_regions; -+extern int iomem_size; - - #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1)) - - extern unsigned long host_task_size; - 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_range(int fd, char *driver, unsigned long start, -- unsigned long pfn, unsigned long total, int need_vm, -- struct mem_region *region, void *reserved); - extern void setup_memory(void *entry); - extern unsigned long find_iomem(char *driver, unsigned long *len_out); --extern int init_maps(struct mem_region *region); --extern int nregions(void); --extern int reserve_vm(unsigned long start, unsigned long end, void *e); -+extern int init_maps(unsigned long physmem, unsigned long iomem, -+ unsigned long highmem); - extern unsigned long get_vm(unsigned long len); - extern void setup_physmem(unsigned long start, unsigned long usable, -- unsigned long len); --extern int setup_region(struct mem_region *region, void *entry); -+ unsigned long len, unsigned long highmem); - extern void add_iomem(char *name, int fd, unsigned long size); --extern struct mem_region *phys_region(unsigned long phys); - extern unsigned long phys_offset(unsigned long phys); - extern void unmap_physmem(void); --extern int map_memory(unsigned long virt, unsigned long phys, -- unsigned long len, int r, int w, int x); -+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); -diff -puN arch/um/include/os.h~Main-uml-patch-no-skas arch/um/include/os.h ---- uml-linux-2.6.7/arch/um/include/os.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.493322488 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/os.h 2004-06-29 21:02:55.721287832 +0200 -@@ -17,6 +17,32 @@ - #define OS_TYPE_FIFO 6 - #define OS_TYPE_SOCK 7 - -+/* os_access() flags */ -+#define OS_ACC_F_OK 0 /* Test for existence. */ -+#define OS_ACC_X_OK 1 /* Test for execute permission. */ -+#define OS_ACC_W_OK 2 /* Test for write permission. */ -+#define OS_ACC_R_OK 4 /* Test for read permission. */ -+#define OS_ACC_RW_OK (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */ -+ -+/* -+ * types taken from stat_file() in hostfs_user.c -+ * (if they are wrong here, they are wrong there...). -+ */ -+struct uml_stat { -+ int ust_dev; /* device */ -+ unsigned long long ust_ino; /* inode */ -+ int ust_mode; /* protection */ -+ int ust_nlink; /* number of hard links */ -+ int ust_uid; /* user ID of owner */ -+ int ust_gid; /* group ID of owner */ -+ unsigned long long ust_size; /* total size, in bytes */ -+ int ust_blksize; /* blocksize for filesystem I/O */ -+ unsigned long long ust_blocks; /* number of blocks allocated */ -+ unsigned long ust_atime; /* time of last access */ -+ unsigned long ust_mtime; /* time of last modification */ -+ unsigned long ust_ctime; /* time of last change */ -+}; -+ - struct openflags { - unsigned int r : 1; - unsigned int w : 1; -@@ -84,29 +110,47 @@ static inline struct openflags of_excl(s - flags.e = 1; - return(flags); - } -- -+ - static inline struct openflags of_cloexec(struct openflags flags) - { - flags.cl = 1; - return(flags); - } - -+extern int os_stat_file(const char *file_name, struct uml_stat *buf); -+extern int os_stat_fd(const int fd, struct uml_stat *buf); -+extern int os_access(const char *file, int mode); -+extern void os_print_error(int error, const char* str); -+extern int os_get_exec_close(int fd, int *close_on_exec); -+extern int os_set_exec_close(int fd, int close_on_exec); -+extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg); -+extern int os_window_size(int fd, int *rows, int *cols); -+extern int os_new_tty_pgrp(int fd, int pid); -+extern int os_get_ifname(int fd, char *namebuf); -+extern int os_set_slip(int fd); -+extern int os_set_owner(int fd, int pid); -+extern int os_sigio_async(int master, int slave); -+extern int os_mode_fd(int fd, int mode); -+ - extern int os_seek_file(int fd, __u64 offset); - extern int os_open_file(char *file, struct openflags flags, int mode); - extern int os_read_file(int fd, void *buf, int len); --extern int os_write_file(int fd, void *buf, int count); -+extern int os_write_file(int fd, const void *buf, int count); - extern int os_file_size(char *file, long long *size_out); -+extern int os_file_modtime(char *file, unsigned long *modtime); - extern int os_pipe(int *fd, int stream, int close_on_exec); - extern int os_set_fd_async(int fd, int owner); - extern int os_set_fd_block(int fd, int blocking); - extern int os_accept_connection(int fd); -+extern int os_create_unix_socket(char *file, int len, int close_on_exec); - extern int os_shutdown_socket(int fd, int r, int w); - extern void os_close_file(int fd); - extern int os_rcv_fd(int fd, int *helper_pid_out); --extern int create_unix_socket(char *file, int len); -+extern int create_unix_socket(char *file, int len, int close_on_exec); - extern int os_connect_socket(char *name); - extern int os_file_type(char *file); - extern int os_file_mode(char *file, struct openflags *mode_out); -+extern int os_lock_file(int fd, int excl); - - extern unsigned long os_process_pc(int pid); - extern int os_process_parent(int pid); -@@ -115,11 +159,12 @@ extern void os_kill_process(int pid, int - extern void os_usr1_process(int pid); - extern int os_getpid(void); - --extern int os_map_memory(void *virt, int fd, unsigned long off, -+extern int os_map_memory(void *virt, int fd, unsigned long long off, - unsigned long len, int r, int w, int x); - extern int os_protect_memory(void *addr, unsigned long len, - int r, int w, int x); - extern int os_unmap_memory(void *addr, int len); -+extern void os_flush_stdout(void); - - #endif - -diff -puN arch/um/include/signal_user.h~Main-uml-patch-no-skas arch/um/include/signal_user.h ---- uml-linux-2.6.7/arch/um/include/signal_user.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.494322336 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/signal_user.h 2004-06-29 21:02:55.722287680 +0200 -@@ -11,6 +11,8 @@ extern int signal_stack_size; - extern int change_sig(int signal, int on); - extern void set_sigstack(void *stack, int size); - extern void set_handler(int sig, void (*handler)(int), int flags, ...); -+extern int set_signals(int enable); -+extern int get_signals(void); - - #endif - -diff -puN arch/um/include/skas_ptrace.h~Main-uml-patch-no-skas arch/um/include/skas_ptrace.h ---- uml-linux-2.6.7/arch/um/include/skas_ptrace.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.495322184 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/skas_ptrace.h 2004-06-29 21:02:55.722287680 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -diff -puN arch/um/include/sysdep-i386/frame_user.h~Main-uml-patch-no-skas arch/um/include/sysdep-i386/frame_user.h ---- uml-linux-2.6.7/arch/um/include/sysdep-i386/frame_user.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.496322032 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/sysdep-i386/frame_user.h 2004-06-29 21:02:55.722287680 +0200 -@@ -56,26 +56,26 @@ static inline void setup_arch_frame(stru - * it would have to be __builtin_frame_address(1). - */ - --static inline unsigned long frame_restorer(void) --{ -- unsigned long *fp; -- -- fp = __builtin_frame_address(0); -- return((unsigned long) (fp + 1)); --} -+#define frame_restorer() \ -+({ \ -+ unsigned long *fp; \ -+\ -+ fp = __builtin_frame_address(0); \ -+ ((unsigned long) (fp + 1)); \ -+}) - - /* Similarly, this returns the value of sp when the handler was first - * entered. This is used to calculate the proper sp when delivering - * signals. - */ - --static inline unsigned long frame_sp(void) --{ -- unsigned long *fp; -- -- fp = __builtin_frame_address(0); -- return((unsigned long) (fp + 1)); --} -+#define frame_sp() \ -+({ \ -+ unsigned long *fp; \ -+\ -+ fp = __builtin_frame_address(0); \ -+ ((unsigned long) (fp + 1)); \ -+}) - - #endif - -diff -puN arch/um/include/sysdep-i386/sigcontext.h~Main-uml-patch-no-skas arch/um/include/sysdep-i386/sigcontext.h ---- uml-linux-2.6.7/arch/um/include/sysdep-i386/sigcontext.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.497321880 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/sysdep-i386/sigcontext.h 2004-06-29 21:02:55.722287680 +0200 -@@ -28,8 +28,8 @@ - */ - #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) - --/* These are General Protection and Page Fault */ --#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14)) -+/* This is Page Fault */ -+#define SEGV_IS_FIXABLE(trap) (trap == 14) - - #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc))) - -diff -puN arch/um/include/sysdep-i386/syscalls.h~Main-uml-patch-no-skas arch/um/include/sysdep-i386/syscalls.h ---- uml-linux-2.6.7/arch/um/include/sysdep-i386/syscalls.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.498321728 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/sysdep-i386/syscalls.h 2004-06-29 21:02:55.723287528 +0200 -@@ -11,39 +11,34 @@ typedef long syscall_handler_t(struct pt - #define EXECUTE_SYSCALL(syscall, regs) \ - ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) - --extern syscall_handler_t sys_modify_ldt; --extern syscall_handler_t old_mmap_i386; --extern syscall_handler_t old_select; --extern syscall_handler_t sys_ni_syscall; -- - #define ARCH_SYSCALLS \ -- [ __NR_mmap ] = old_mmap_i386, \ -- [ __NR_select ] = old_select, \ -- [ __NR_vm86old ] = sys_ni_syscall, \ -- [ __NR_modify_ldt ] = sys_modify_ldt, \ -- [ __NR_lchown32 ] = sys_lchown, \ -- [ __NR_getuid32 ] = sys_getuid, \ -- [ __NR_getgid32 ] = sys_getgid, \ -- [ __NR_geteuid32 ] = sys_geteuid, \ -- [ __NR_getegid32 ] = sys_getegid, \ -- [ __NR_setreuid32 ] = sys_setreuid, \ -- [ __NR_setregid32 ] = sys_setregid, \ -- [ __NR_getgroups32 ] = sys_getgroups, \ -- [ __NR_setgroups32 ] = sys_setgroups, \ -- [ __NR_fchown32 ] = sys_fchown, \ -- [ __NR_setresuid32 ] = sys_setresuid, \ -- [ __NR_getresuid32 ] = sys_getresuid, \ -- [ __NR_setresgid32 ] = sys_setresgid, \ -- [ __NR_getresgid32 ] = sys_getresgid, \ -- [ __NR_chown32 ] = sys_chown, \ -- [ __NR_setuid32 ] = sys_setuid, \ -- [ __NR_setgid32 ] = sys_setgid, \ -- [ __NR_setfsuid32 ] = sys_setfsuid, \ -- [ __NR_setfsgid32 ] = sys_setfsgid, \ -- [ __NR_pivot_root ] = sys_pivot_root, \ -- [ __NR_mincore ] = sys_mincore, \ -- [ __NR_madvise ] = sys_madvise, \ -- [ 222 ] = sys_ni_syscall, -+ [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \ -+ [ __NR_select ] = (syscall_handler_t *) old_select, \ -+ [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \ -+ [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \ -+ [ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \ -+ [ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \ -+ [ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \ -+ [ __NR_geteuid32 ] = (syscall_handler_t *) sys_geteuid, \ -+ [ __NR_getegid32 ] = (syscall_handler_t *) sys_getegid, \ -+ [ __NR_setreuid32 ] = (syscall_handler_t *) sys_setreuid, \ -+ [ __NR_setregid32 ] = (syscall_handler_t *) sys_setregid, \ -+ [ __NR_getgroups32 ] = (syscall_handler_t *) sys_getgroups, \ -+ [ __NR_setgroups32 ] = (syscall_handler_t *) sys_setgroups, \ -+ [ __NR_fchown32 ] = (syscall_handler_t *) sys_fchown, \ -+ [ __NR_setresuid32 ] = (syscall_handler_t *) sys_setresuid, \ -+ [ __NR_getresuid32 ] = (syscall_handler_t *) sys_getresuid, \ -+ [ __NR_setresgid32 ] = (syscall_handler_t *) sys_setresgid, \ -+ [ __NR_getresgid32 ] = (syscall_handler_t *) sys_getresgid, \ -+ [ __NR_chown32 ] = (syscall_handler_t *) sys_chown, \ -+ [ __NR_setuid32 ] = (syscall_handler_t *) sys_setuid, \ -+ [ __NR_setgid32 ] = (syscall_handler_t *) sys_setgid, \ -+ [ __NR_setfsuid32 ] = (syscall_handler_t *) sys_setfsuid, \ -+ [ __NR_setfsgid32 ] = (syscall_handler_t *) sys_setfsgid, \ -+ [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \ -+ [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \ -+ [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \ -+ [ 222 ] = (syscall_handler_t *) sys_ni_syscall, - - /* 222 doesn't yet have a name in include/asm-i386/unistd.h */ - -diff -puN arch/um/include/ubd_user.h~Main-uml-patch-no-skas arch/um/include/ubd_user.h ---- uml-linux-2.6.7/arch/um/include/ubd_user.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.500321424 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/ubd_user.h 2004-06-29 21:02:55.723287528 +0200 -@@ -9,7 +9,7 @@ - - #include "os.h" - --enum ubd_req { UBD_READ, UBD_WRITE }; -+enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP }; - - struct io_thread_req { - enum ubd_req op; -@@ -20,8 +20,10 @@ struct io_thread_req { - char *buffer; - int sectorsize; - unsigned long sector_mask; -- unsigned long cow_offset; -+ unsigned long long cow_offset; - unsigned long bitmap_words[2]; -+ int map_fd; -+ unsigned long long map_offset; - int error; - }; - -@@ -31,7 +33,7 @@ extern int open_ubd_file(char *file, str - int *create_cow_out); - extern int create_cow_file(char *cow_file, char *backing_file, - struct openflags flags, int sectorsize, -- int *bitmap_offset_out, -+ int alignment, int *bitmap_offset_out, - unsigned long *bitmap_len_out, - int *data_offset_out); - extern int read_cow_bitmap(int fd, void *buf, int offset, int len); -@@ -39,7 +41,6 @@ extern int read_ubd_fs(int fd, void *buf - extern int write_ubd_fs(int fd, char *buffer, int len); - extern int start_io_thread(unsigned long sp, int *fds_out); - extern void do_io(struct io_thread_req *req); --extern int ubd_is_dir(char *file); - - static inline int ubd_test_bit(__u64 bit, unsigned char *data) - { -diff -puN arch/um/include/um_uaccess.h~Main-uml-patch-no-skas arch/um/include/um_uaccess.h ---- uml-linux-2.6.7/arch/um/include/um_uaccess.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.501321272 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/um_uaccess.h 2004-06-29 21:02:55.723287528 +0200 -@@ -38,22 +38,73 @@ static inline int copy_to_user(void *to, - from, n)); - } - -+/* -+ * strncpy_from_user: - Copy a NUL terminated string from userspace. -+ * @dst: Destination address, in kernel space. This buffer must be at -+ * least @count bytes long. -+ * @src: Source address, in user space. -+ * @count: Maximum number of bytes to copy, including the trailing NUL. -+ * -+ * Copies a NUL-terminated string from userspace to kernel space. -+ * -+ * On success, returns the length of the string (not including the trailing -+ * NUL). -+ * -+ * If access to userspace fails, returns -EFAULT (some data may have been -+ * copied). -+ * -+ * If @count is smaller than the length of the string, copies @count bytes -+ * and returns @count. -+ */ -+ - static inline int strncpy_from_user(char *dst, const char *src, int count) - { - return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas, - dst, src, count)); - } - -+/* -+ * __clear_user: - Zero a block of memory in user space, with less checking. -+ * @to: Destination address, in user space. -+ * @n: Number of bytes to zero. -+ * -+ * Zero a block of memory in user space. Caller must check -+ * the specified block with access_ok() before calling this function. -+ * -+ * Returns number of bytes that could not be cleared. -+ * On success, this will be zero. -+ */ - static inline int __clear_user(void *mem, int len) - { - return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len)); - } - -+/* -+ * clear_user: - Zero a block of memory in user space. -+ * @to: Destination address, in user space. -+ * @n: Number of bytes to zero. -+ * -+ * Zero a block of memory in user space. -+ * -+ * Returns number of bytes that could not be cleared. -+ * On success, this will be zero. -+ */ - static inline int clear_user(void *mem, int len) - { - return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len)); - } - -+/* -+ * strlen_user: - Get the size of a string in user space. -+ * @str: The string to measure. -+ * @n: The maximum valid length -+ * -+ * Get the size of a NUL-terminated string in user space. -+ * -+ * Returns the size of the string INCLUDING the terminating NUL. -+ * On exception, returns 0. -+ * If the string is too long, returns a value greater than @n. -+ */ - static inline int strnlen_user(const void *str, int len) - { - return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len)); -diff -puN arch/um/include/user.h~Main-uml-patch-no-skas arch/um/include/user.h ---- uml-linux-2.6.7/arch/um/include/user.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.513319448 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/user.h 2004-06-29 21:02:55.723287528 +0200 -@@ -14,6 +14,7 @@ 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); - - #endif - -diff -puN arch/um/include/user_util.h~Main-uml-patch-no-skas arch/um/include/user_util.h ---- uml-linux-2.6.7/arch/um/include/user_util.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.515319144 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/user_util.h 2004-06-29 21:02:55.724287376 +0200 -@@ -14,8 +14,6 @@ extern int grantpt(int __fd); - extern int unlockpt(int __fd); - extern char *ptsname(int __fd); - --enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; -- - struct cpu_task { - int pid; - void *task; -@@ -59,7 +57,6 @@ extern int wait_for_stop(int pid, int si - extern void *add_signal_handler(int sig, void (*handler)(int)); - extern int start_fork_tramp(void *arg, unsigned long temp_stack, - int clone_flags, int (*tramp)(void *)); --extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags); - extern int linux_main(int argc, char **argv); - extern void set_cmdline(char *cmd); - extern void input_cb(void (*proc)(void *), void *arg, int arg_len); -@@ -86,11 +83,13 @@ extern void check_sigio(void); - extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); - extern void write_sigio_workaround(void); - extern void arch_check_bugs(void); -+extern int cpu_feature(char *what, char *buf, int len); - extern int arch_handle_signal(int sig, union uml_pt_regs *regs); - extern int arch_fixup(unsigned long address, void *sc_ptr); - extern void forward_pending_sigio(int target); - extern int can_do_skas(void); -- -+extern void arch_init_thread(void); -+ - #endif - - /* -diff -puN arch/um/Kconfig~Main-uml-patch-no-skas arch/um/Kconfig ---- uml-linux-2.6.7/arch/um/Kconfig~Main-uml-patch-no-skas 2004-06-29 21:02:55.516318992 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Kconfig 2004-06-29 21:02:55.724287376 +0200 -@@ -61,6 +61,20 @@ config MODE_SKAS - - config NET - bool "Networking support" -+ help -+ Unless you really know what you are doing, you should say Y here. -+ The reason is that some programs need kernel networking support even -+ when running on a stand-alone machine that isn't connected to any -+ other computer. If you are upgrading from an older kernel, you -+ should consider updating your networking tools too because changes -+ in the kernel and the tools often go hand in hand. The tools are -+ contained in the package net-tools, the location and version number -+ of which are given in Documentation/Changes. -+ -+ For a general introduction to Linux networking, it is highly -+ recommended to read the NET-HOWTO, available from -+ <http://www.tldp.org/docs.html#howto>. -+ - - source "fs/Kconfig.binfmt" - -@@ -85,6 +99,19 @@ config HOSTFS - If you'd like to be able to work with files stored on the host, - say Y or M here; otherwise say N. - -+config HPPFS -+ tristate "HoneyPot ProcFS" -+ help -+ hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc -+ entries to be overridden, removed, or fabricated from the host. -+ Its purpose is to allow a UML to appear to be a physical machine -+ by removing or changing anything in /proc which gives away the -+ identity of a UML. -+ -+ See http://user-mode-linux.sf.net/hppfs.html for more information. -+ -+ You only need this if you are setting up a UML honeypot. Otherwise, -+ it is safe to say 'N' here. - - config MCONSOLE - bool "Management console" -@@ -105,6 +132,16 @@ config MCONSOLE - config MAGIC_SYSRQ - bool "Magic SysRq key" - depends on MCONSOLE -+ help -+ If you say Y here, you will have some control over the system even -+ if the system crashes for example during kernel debugging (e.g., you -+ will be able to flush the buffer cache to disk, reboot the system -+ immediately or dump some status information). This is accomplished -+ by pressing various keys while holding SysRq (Alt+PrintScreen). It -+ also works on a serial console (on PC hardware at least), if you -+ send a BREAK and then within 5 seconds a command keypress. The -+ keys are documented in Documentation/sysrq.txt. Don't say Y -+ unless you really know what this hack does. - - config HOST_2G_2G - bool "2G/2G host address space split" -@@ -168,6 +205,17 @@ config KERNEL_STACK_ORDER - be 1 << order pages. The default is OK unless you're running Valgrind - on UML, in which case, set this to 3. - -+config UML_REAL_TIME_CLOCK -+ bool "Real-time Clock" -+ default y -+ help -+ This option makes UML time deltas match wall clock deltas. This should -+ normally be enabled. The exception would be if you are debugging with -+ UML and spend long times with UML stopped at a breakpoint. In this -+ case, when UML is restarted, it will call the timer enough times to make -+ up for the time spent at the breakpoint. This could result in a -+ noticable lag. If this is a problem, then disable this option. -+ - endmenu - - source "init/Kconfig" -@@ -240,6 +288,10 @@ config FRAME_POINTER - config PT_PROXY - bool "Enable ptrace proxy" - depends on XTERM_CHAN && DEBUG_INFO -+ help -+ This option enables a debugging interface which allows gdb to debug -+ the kernel without needing to actually attach to kernel threads. -+ If you want to do kernel debugging, say Y here; otherwise say N. - - config GPROF - bool "Enable gprof support" -diff -puN arch/um/Kconfig_block~Main-uml-patch-no-skas arch/um/Kconfig_block ---- uml-linux-2.6.7/arch/um/Kconfig_block~Main-uml-patch-no-skas 2004-06-29 21:02:55.517318840 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Kconfig_block 2004-06-29 21:02:55.724287376 +0200 -@@ -29,6 +29,20 @@ config BLK_DEV_UBD_SYNC - wise choice too. In all other cases (for example, if you're just - playing around with User-Mode Linux) you can choose N. - -+# Turn this back on when the driver actually works -+# -+#config BLK_DEV_COW -+# tristate "COW block device" -+# help -+# This is a layered driver which sits above two other block devices. -+# One is read-only, and the other is a read-write layer which stores -+# all changes. This provides the illusion that the read-only layer -+# can be mounted read-write and changed. -+ -+config BLK_DEV_COW_COMMON -+ bool -+ default BLK_DEV_COW || BLK_DEV_UBD -+ - config BLK_DEV_LOOP - tristate "Loopback device support" - -diff -puN arch/um/Kconfig_net~Main-uml-patch-no-skas arch/um/Kconfig_net ---- uml-linux-2.6.7/arch/um/Kconfig_net~Main-uml-patch-no-skas 2004-06-29 21:02:55.518318688 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Kconfig_net 2004-06-29 21:02:55.725287224 +0200 -@@ -1,5 +1,5 @@ - --menu "Network Devices" -+menu "UML Network Devices" - depends on NET - - # UML virtual driver -@@ -176,73 +176,5 @@ config UML_NET_SLIRP - - Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp" - -- --# Below are hardware-independent drivers mirrored from --# drivers/net/Config.in. It would be nice if Linux --# had HW independent drivers separated from the other --# but it does not. Until then each non-ISA/PCI arch --# needs to provide it's own menu of network drivers --config DUMMY -- tristate "Dummy net driver support" -- --config BONDING -- tristate "Bonding driver support" -- --config EQUALIZER -- tristate "EQL (serial line load balancing) support" -- --config TUN -- tristate "Universal TUN/TAP device driver support" -- --config ETHERTAP -- tristate "Ethertap network tap (OBSOLETE)" -- depends on EXPERIMENTAL && NETLINK -- --config PPP -- tristate "PPP (point-to-point protocol) support" -- --config PPP_MULTILINK -- bool "PPP multilink support (EXPERIMENTAL)" -- depends on PPP && EXPERIMENTAL -- --config PPP_FILTER -- bool "PPP filtering" -- depends on PPP && FILTER -- --config PPP_ASYNC -- tristate "PPP support for async serial ports" -- depends on PPP -- --config PPP_SYNC_TTY -- tristate "PPP support for sync tty ports" -- depends on PPP -- --config PPP_DEFLATE -- tristate "PPP Deflate compression" -- depends on PPP -- --config PPP_BSDCOMP -- tristate "PPP BSD-Compress compression" -- depends on PPP -- --config PPPOE -- tristate "PPP over Ethernet (EXPERIMENTAL)" -- depends on PPP && EXPERIMENTAL -- --config SLIP -- tristate "SLIP (serial line) support" -- --config SLIP_COMPRESSED -- bool "CSLIP compressed headers" -- depends on SLIP=y -- --config SLIP_SMART -- bool "Keepalive and linefill" -- depends on SLIP=y -- --config SLIP_MODE_SLIP6 -- bool "Six bit SLIP encapsulation" -- depends on SLIP=y -- - endmenu - -diff -puN arch/um/kernel/config.c.in~Main-uml-patch-no-skas arch/um/kernel/config.c.in ---- uml-linux-2.6.7/arch/um/kernel/config.c.in~Main-uml-patch-no-skas 2004-06-29 21:02:55.519318536 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/config.c.in 2004-06-29 21:02:55.725287224 +0200 -@@ -7,9 +7,7 @@ - #include <stdlib.h> - #include "init.h" - --static __initdata char *config = " --CONFIG --"; -+static __initdata char *config = "CONFIG"; - - static int __init print_config(char *line, int *add) - { -diff -puN arch/um/kernel/exec_kern.c~Main-uml-patch-no-skas arch/um/kernel/exec_kern.c ---- uml-linux-2.6.7/arch/um/kernel/exec_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.520318384 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/exec_kern.c 2004-06-29 21:02:55.725287224 +0200 -@@ -32,10 +32,15 @@ void start_thread(struct pt_regs *regs, - CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); - } - -+extern void log_exec(char **argv, void *tty); -+ - static int execve1(char *file, char **argv, char **env) - { - int error; - -+#ifdef CONFIG_TTY_LOG -+ log_exec(argv, current->tty); -+#endif - error = do_execve(file, argv, env, ¤t->thread.regs); - if (error == 0){ - current->ptrace &= ~PT_DTRACE; -diff -puN arch/um/kernel/frame.c~Main-uml-patch-no-skas arch/um/kernel/frame.c ---- uml-linux-2.6.7/arch/um/kernel/frame.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.521318232 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/frame.c 2004-06-29 21:02:55.725287224 +0200 -@@ -279,7 +279,7 @@ void capture_signal_stack(void) - struct sc_frame_raw raw_sc; - struct si_frame_raw raw_si; - void *stack, *sigstack; -- unsigned long top, sig_top, base; -+ unsigned long top, base; - - stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -@@ -292,7 +292,6 @@ void capture_signal_stack(void) - } - - top = (unsigned long) stack + PAGE_SIZE - sizeof(void *); -- sig_top = (unsigned long) sigstack + PAGE_SIZE; - - /* Get the sigcontext, no sigrestorer layout */ - raw_sc.restorer = 0; -diff -puN arch/um/kernel/frame_kern.c~Main-uml-patch-no-skas arch/um/kernel/frame_kern.c ---- uml-linux-2.6.7/arch/um/kernel/frame_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.522318080 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/frame_kern.c 2004-06-29 21:02:55.726287072 +0200 -@@ -6,7 +6,6 @@ - #include "asm/ptrace.h" - #include "asm/uaccess.h" - #include "asm/signal.h" --#include "asm/uaccess.h" - #include "asm/ucontext.h" - #include "frame_kern.h" - #include "sigcontext.h" -@@ -29,12 +28,15 @@ static int copy_restorer(void (*restorer - sizeof(restorer))); - } - -+extern int userspace_pid[]; -+ - static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, - struct arch_frame_data *arch) - { - return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), - arch), -- copy_sc_to_user_skas(to, fp, &from->regs, -+ copy_sc_to_user_skas(userspace_pid[0], to, fp, -+ &from->regs, - current->thread.cr2, - current->thread.err))); - } -diff -puN arch/um/kernel/helper.c~Main-uml-patch-no-skas arch/um/kernel/helper.c ---- uml-linux-2.6.7/arch/um/kernel/helper.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.524317776 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/helper.c 2004-06-29 21:02:55.726287072 +0200 -@@ -7,7 +7,6 @@ - #include <stdlib.h> - #include <unistd.h> - #include <errno.h> --#include <fcntl.h> - #include <sched.h> - #include <sys/signal.h> - #include <sys/wait.h> -@@ -33,6 +32,7 @@ static int helper_child(void *arg) - { - struct helper_data *data = arg; - char **argv = data->argv; -+ int errval; - - if(helper_pause){ - signal(SIGHUP, helper_hup); -@@ -41,8 +41,9 @@ static int helper_child(void *arg) - if(data->pre_exec != NULL) - (*data->pre_exec)(data->pre_data); - execvp(argv[0], argv); -+ errval = errno; - printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); -- write(data->fd, &errno, sizeof(errno)); -+ os_write_file(data->fd, &errval, sizeof(errval)); - os_kill_process(os_getpid(), 0); - return(0); - } -@@ -59,17 +60,20 @@ int run_helper(void (*pre_exec)(void *), - if((stack_out != NULL) && (*stack_out != 0)) - stack = *stack_out; - else stack = alloc_stack(0, um_in_interrupt()); -- if(stack == 0) return(-ENOMEM); -+ if(stack == 0) -+ return(-ENOMEM); - - err = os_pipe(fds, 1, 0); -- if(err){ -- printk("run_helper : pipe failed, errno = %d\n", -err); -- return(err); -+ if(err < 0){ -+ printk("run_helper : pipe failed, err = %d\n", -err); -+ goto out_free; - } -- if(fcntl(fds[1], F_SETFD, 1) != 0){ -- printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n", -- errno); -- return(-errno); -+ -+ err = os_set_exec_close(fds[1], 1); -+ if(err < 0){ -+ printk("run_helper : setting FD_CLOEXEC failed, err = %d\n", -+ -err); -+ goto out_close; - } - - sp = stack + page_size() - sizeof(void *); -@@ -80,23 +84,34 @@ int run_helper(void (*pre_exec)(void *), - pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); - if(pid < 0){ - printk("run_helper : clone failed, errno = %d\n", errno); -- return(-errno); -+ err = -errno; -+ goto out_close; - } -- close(fds[1]); -- n = read(fds[0], &err, sizeof(err)); -+ -+ os_close_file(fds[1]); -+ n = os_read_file(fds[0], &err, sizeof(err)); - if(n < 0){ -- printk("run_helper : read on pipe failed, errno = %d\n", -- errno); -- return(-errno); -+ printk("run_helper : read on pipe failed, err = %d\n", -n); -+ err = n; -+ goto out_kill; - } - else if(n != 0){ - waitpid(pid, NULL, 0); -- pid = -err; -+ pid = -errno; - } - - if(stack_out == NULL) free_stack(stack, 0); - else *stack_out = stack; - return(pid); -+ -+ out_kill: -+ os_kill_process(pid, 1); -+ out_close: -+ os_close_file(fds[0]); -+ os_close_file(fds[1]); -+ out_free: -+ free_stack(stack, 0); -+ return(err); - } - - int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, -@@ -117,9 +132,11 @@ int run_helper_thread(int (*proc)(void * - } - if(stack_out == NULL){ - pid = waitpid(pid, &status, 0); -- if(pid < 0) -+ if(pid < 0){ - printk("run_helper_thread - wait failed, errno = %d\n", -- pid); -+ errno); -+ pid = -errno; -+ } - if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) - printk("run_helper_thread - thread returned status " - "0x%x\n", status); -diff -puN arch/um/kernel/initrd_user.c~Main-uml-patch-no-skas arch/um/kernel/initrd_user.c ---- uml-linux-2.6.7/arch/um/kernel/initrd_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.525317624 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/initrd_user.c 2004-06-29 21:02:55.726287072 +0200 -@@ -6,7 +6,6 @@ - #include <unistd.h> - #include <sys/types.h> - #include <sys/stat.h> --#include <fcntl.h> - #include <errno.h> - - #include "user_util.h" -@@ -19,13 +18,15 @@ int load_initrd(char *filename, void *bu - { - int fd, n; - -- if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){ -- printk("Opening '%s' failed - errno = %d\n", filename, errno); -+ fd = os_open_file(filename, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Opening '%s' failed - err = %d\n", filename, -fd); - return(-1); - } -- if((n = read(fd, buf, size)) != size){ -- printk("Read of %d bytes from '%s' returned %d, errno = %d\n", -- size, filename, n, errno); -+ n = os_read_file(fd, buf, size); -+ if(n != size){ -+ printk("Read of %d bytes from '%s' failed, err = %d\n", size, -+ filename, -n); - return(-1); - } - return(0); -diff -puN arch/um/kernel/init_task.c~Main-uml-patch-no-skas arch/um/kernel/init_task.c ---- uml-linux-2.6.7/arch/um/kernel/init_task.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.526317472 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/init_task.c 2004-06-29 21:02:55.726287072 +0200 -@@ -8,7 +8,6 @@ - #include "linux/module.h" - #include "linux/sched.h" - #include "linux/init_task.h" --#include "linux/version.h" - #include "asm/uaccess.h" - #include "asm/pgtable.h" - #include "user_util.h" -@@ -18,7 +17,7 @@ static struct fs_struct init_fs = INIT_F - struct mm_struct init_mm = INIT_MM(init_mm); - static struct files_struct init_files = INIT_FILES; - static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -- -+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); - EXPORT_SYMBOL(init_mm); - - /* -@@ -43,26 +42,12 @@ union thread_union init_thread_union - __attribute__((__section__(".data.init_task"))) = - { INIT_THREAD_INFO(init_task) }; - --struct task_struct *alloc_task_struct(void) --{ -- return((struct task_struct *) -- __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER)); --} -- - void unprotect_stack(unsigned long stack) - { - protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, - 1, 1, 0, 1); - } - --void free_task_struct(struct task_struct *task) --{ -- /* free_pages decrements the page counter and only actually frees -- * the pages if they are now not accessed by anything. -- */ -- free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER); --} -- - /* - * 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 -puN arch/um/kernel/irq.c~Main-uml-patch-no-skas arch/um/kernel/irq.c ---- uml-linux-2.6.7/arch/um/kernel/irq.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.527317320 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/irq.c 2004-06-29 21:02:55.727286920 +0200 -@@ -29,6 +29,7 @@ - #include "user_util.h" - #include "kern_util.h" - #include "irq_user.h" -+#include "irq_kern.h" - - static void register_irq_proc (unsigned int irq); - -@@ -83,65 +84,55 @@ struct hw_interrupt_type no_irq_type = { - end_none - }; - --/* Not changed */ --volatile unsigned long irq_err_count; -- - /* - * Generic, controller-independent functions: - */ - --int get_irq_list(char *buf) -+int show_interrupts(struct seq_file *p, void *v) - { -- int i, j; -- unsigned long flags; -+ int i = *(loff_t *) v, j; - struct irqaction * action; -- char *p = buf; -+ unsigned long flags; - -- p += sprintf(p, " "); -- for (j=0; j<num_online_cpus(); j++) -- p += sprintf(p, "CPU%d ",j); -- *p++ = '\n'; -+ if (i == 0) { -+ seq_printf(p, " "); -+ for (j=0; j<NR_CPUS; j++) -+ if (cpu_online(j)) -+ seq_printf(p, "CPU%d ",j); -+ seq_putc(p, '\n'); -+ } - -- for (i = 0 ; i < NR_IRQS ; i++) { -+ if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) -- goto end; -- p += sprintf(p, "%3d: ",i); -+ goto skip; -+ seq_printf(p, "%3d: ",i); - #ifndef CONFIG_SMP -- p += sprintf(p, "%10u ", kstat_irqs(i)); -+ seq_printf(p, "%10u ", kstat_irqs(i)); - #else -- for (j = 0; j < num_online_cpus(); j++) -- p += sprintf(p, "%10u ", -- kstat_cpu(cpu_logical_map(j)).irqs[i]); -+ for (j = 0; j < NR_CPUS; j++) -+ if (cpu_online(j)) -+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); - #endif -- p += sprintf(p, " %14s", irq_desc[i].handler->typename); -- p += sprintf(p, " %s", action->name); -+ seq_printf(p, " %14s", irq_desc[i].handler->typename); -+ seq_printf(p, " %s", action->name); - - for (action=action->next; action; action = action->next) -- p += sprintf(p, ", %s", action->name); -- *p++ = '\n'; -- end: -+ seq_printf(p, ", %s", action->name); -+ -+ seq_putc(p, '\n'); -+skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); -+ } else if (i == NR_IRQS) { -+ seq_printf(p, "NMI: "); -+ for (j = 0; j < NR_CPUS; j++) -+ if (cpu_online(j)) -+ seq_printf(p, "%10u ", nmi_count(j)); -+ seq_putc(p, '\n'); - } -- p += sprintf(p, "\n"); --#ifdef notdef --#ifdef CONFIG_SMP -- p += sprintf(p, "LOC: "); -- for (j = 0; j < num_online_cpus(); j++) -- p += sprintf(p, "%10u ", -- apic_timer_irqs[cpu_logical_map(j)]); -- p += sprintf(p, "\n"); --#endif --#endif -- p += sprintf(p, "ERR: %10lu\n", irq_err_count); -- return p - buf; --} -- - --int show_interrupts(struct seq_file *p, void *v) --{ -- return(0); -+ return 0; - } - - /* -@@ -282,13 +273,12 @@ unsigned int do_IRQ(int irq, union uml_p - * 0 return value means that this irq is already being - * handled by some other CPU. (or is disabled) - */ -- int cpu = smp_processor_id(); - irq_desc_t *desc = irq_desc + irq; - struct irqaction * action; - unsigned int status; - - irq_enter(); -- kstat_cpu(cpu).irqs[irq]++; -+ kstat_this_cpu.irqs[irq]++; - spin_lock(&desc->lock); - desc->handler->ack(irq); - /* -@@ -385,7 +375,7 @@ out: - */ - - int request_irq(unsigned int irq, -- void (*handler)(int, void *, struct pt_regs *), -+ irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, - const char * devname, - void *dev_id) -@@ -433,15 +423,19 @@ int request_irq(unsigned int irq, - EXPORT_SYMBOL(request_irq); - - int um_request_irq(unsigned int irq, int fd, int type, -- void (*handler)(int, void *, struct pt_regs *), -+ irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char * devname, - void *dev_id) - { -- int retval; -+ int err; - -- retval = request_irq(irq, handler, irqflags, devname, dev_id); -- if(retval) return(retval); -- return(activate_fd(irq, fd, type, dev_id)); -+ err = request_irq(irq, handler, irqflags, devname, dev_id); -+ if(err) -+ return(err); -+ -+ if(fd != -1) -+ err = activate_fd(irq, fd, type, dev_id); -+ return(err); - } - - /* this was setup_x86_irq but it seems pretty generic */ -@@ -474,7 +468,8 @@ int setup_irq(unsigned int irq, struct i - */ - spin_lock_irqsave(&desc->lock,flags); - p = &desc->action; -- if ((old = *p) != NULL) { -+ old = *p; -+ if (old != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) { - spin_unlock_irqrestore(&desc->lock,flags); -@@ -586,12 +581,14 @@ static int irq_affinity_write_proc (stru - unsigned long count, void *data) - { - int irq = (long) data, full_count = count, err; -- cpumask_t new_value, tmp; -+ cpumask_t new_value; - - if (!irq_desc[irq].handler->set_affinity) - return -EIO; - - err = cpumask_parse(buffer, count, new_value); -+ if(err) -+ return(err); - - #ifdef CONFIG_SMP - /* -@@ -599,9 +596,11 @@ static int irq_affinity_write_proc (stru - * way to make the system unusable accidentally :-) At least - * one online CPU still has to be targeted. - */ -- cpus_and(tmp, new_value, cpu_online_map); -- if (cpus_empty(tmp)) -- return -EINVAL; -+ { cpumask_t tmp; -+ cpus_and(tmp, new_value, cpu_online_map); -+ if (cpus_empty(tmp)) -+ return -EINVAL; -+ } - #endif - - irq_affinity[irq] = new_value; -diff -puN arch/um/kernel/irq_user.c~Main-uml-patch-no-skas arch/um/kernel/irq_user.c ---- uml-linux-2.6.7/arch/um/kernel/irq_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.528317168 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/irq_user.c 2004-06-29 21:02:55.727286920 +0200 -@@ -6,7 +6,6 @@ - #include <stdlib.h> - #include <unistd.h> - #include <errno.h> --#include <fcntl.h> - #include <signal.h> - #include <string.h> - #include <sys/poll.h> -@@ -49,7 +48,8 @@ void sigio_handler(int sig, union uml_pt - - if(smp_sigio_handler()) return; - while(1){ -- if((n = poll(pollfds, pollfds_num, 0)) < 0){ -+ n = poll(pollfds, pollfds_num, 0); -+ if(n < 0){ - if(errno == EINTR) continue; - printk("sigio_handler : poll returned %d, " - "errno = %d\n", n, errno); -@@ -366,34 +366,31 @@ void deactivate_fd(int fd, int irqnum) - - void forward_ipi(int fd, int pid) - { -- if(fcntl(fd, F_SETOWN, pid) < 0){ -- int save_errno = errno; -- if(fcntl(fd, F_GETOWN, 0) != pid){ -- printk("forward_ipi: F_SETOWN failed, fd = %d, " -- "me = %d, target = %d, errno = %d\n", fd, -- os_getpid(), pid, save_errno); -- } -- } -+ int err; -+ -+ err = os_set_owner(fd, pid); -+ if(err < 0) -+ printk("forward_ipi: set_owner failed, fd = %d, me = %d, " -+ "target = %d, err = %d\n", fd, os_getpid(), pid, -err); - } - - void forward_interrupts(int pid) - { - struct irq_fd *irq; - unsigned long flags; -+ int err; - - flags = irq_lock(); - for(irq=active_fds;irq != NULL;irq = irq->next){ -- if(fcntl(irq->fd, F_SETOWN, pid) < 0){ -- int save_errno = errno; -- if(fcntl(irq->fd, F_GETOWN, 0) != pid){ -- /* XXX Just remove the irq rather than -- * print out an infinite stream of these -- */ -- printk("Failed to forward %d to pid %d, " -- "errno = %d\n", irq->fd, pid, -- save_errno); -- } -+ err = os_set_owner(irq->fd, pid); -+ if(err < 0){ -+ /* XXX Just remove the irq rather than -+ * print out an infinite stream of these -+ */ -+ printk("Failed to forward %d to pid %d, err = %d\n", -+ irq->fd, pid, -err); - } -+ - irq->pid = pid; - } - irq_unlock(flags); -diff -puN arch/um/kernel/ksyms.c~Main-uml-patch-no-skas arch/um/kernel/ksyms.c ---- uml-linux-2.6.7/arch/um/kernel/ksyms.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.529317016 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/ksyms.c 2004-06-29 21:02:55.728286768 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2001 - 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -8,7 +8,7 @@ - #include "linux/string.h" - #include "linux/smp_lock.h" - #include "linux/spinlock.h" --#include <linux/highmem.h> -+#include "linux/highmem.h" - #include "asm/current.h" - #include "asm/delay.h" - #include "asm/processor.h" -@@ -19,6 +19,7 @@ - #include "asm/tlbflush.h" - #include "kern_util.h" - #include "user_util.h" -+#include "mem_user.h" - #include "os.h" - #include "helper.h" - -@@ -34,34 +35,64 @@ EXPORT_SYMBOL(task_size); - EXPORT_SYMBOL(flush_tlb_range); - EXPORT_SYMBOL(host_task_size); - EXPORT_SYMBOL(arch_validate); -+EXPORT_SYMBOL(get_kmem_end); - --EXPORT_SYMBOL(region_pa); --EXPORT_SYMBOL(region_va); --EXPORT_SYMBOL(phys_mem_map); --EXPORT_SYMBOL(page_mem_map); - EXPORT_SYMBOL(page_to_phys); - EXPORT_SYMBOL(phys_to_page); - EXPORT_SYMBOL(high_physmem); - EXPORT_SYMBOL(empty_zero_page); - EXPORT_SYMBOL(um_virt_to_phys); -+EXPORT_SYMBOL(__virt_to_page); -+EXPORT_SYMBOL(to_phys); -+EXPORT_SYMBOL(to_virt); - EXPORT_SYMBOL(mode_tt); - EXPORT_SYMBOL(handle_page_fault); -+EXPORT_SYMBOL(find_iomem); - -+#ifdef CONFIG_MODE_TT -+EXPORT_SYMBOL(copy_from_user_tt); -+EXPORT_SYMBOL(copy_to_user_tt); -+#endif -+ -+#ifdef CONFIG_MODE_SKAS -+EXPORT_SYMBOL(copy_to_user_skas); -+EXPORT_SYMBOL(copy_from_user_skas); -+#endif -+ -+EXPORT_SYMBOL(os_stat_fd); -+EXPORT_SYMBOL(os_stat_file); -+EXPORT_SYMBOL(os_access); -+EXPORT_SYMBOL(os_print_error); -+EXPORT_SYMBOL(os_get_exec_close); -+EXPORT_SYMBOL(os_set_exec_close); - EXPORT_SYMBOL(os_getpid); - EXPORT_SYMBOL(os_open_file); - EXPORT_SYMBOL(os_read_file); - EXPORT_SYMBOL(os_write_file); - EXPORT_SYMBOL(os_seek_file); -+EXPORT_SYMBOL(os_lock_file); -+EXPORT_SYMBOL(os_ioctl_generic); - EXPORT_SYMBOL(os_pipe); - EXPORT_SYMBOL(os_file_type); -+EXPORT_SYMBOL(os_file_mode); -+EXPORT_SYMBOL(os_file_size); -+EXPORT_SYMBOL(os_flush_stdout); - EXPORT_SYMBOL(os_close_file); -+EXPORT_SYMBOL(os_set_fd_async); -+EXPORT_SYMBOL(os_set_fd_block); - EXPORT_SYMBOL(helper_wait); - EXPORT_SYMBOL(os_shutdown_socket); -+EXPORT_SYMBOL(os_create_unix_socket); - EXPORT_SYMBOL(os_connect_socket); -+EXPORT_SYMBOL(os_accept_connection); -+EXPORT_SYMBOL(os_rcv_fd); - EXPORT_SYMBOL(run_helper); - EXPORT_SYMBOL(start_thread); - EXPORT_SYMBOL(dump_thread); - -+EXPORT_SYMBOL(do_gettimeofday); -+EXPORT_SYMBOL(do_settimeofday); -+ - /* This is here because UML expands open to sys_open, not to a system - * call instruction. - */ -@@ -90,3 +121,13 @@ EXPORT_SYMBOL(kunmap_atomic); - EXPORT_SYMBOL(kmap_atomic_to_page); - #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 -puN arch/um/kernel/Makefile~Main-uml-patch-no-skas arch/um/kernel/Makefile ---- uml-linux-2.6.7/arch/um/kernel/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.530316864 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/Makefile 2004-06-29 21:02:55.728286768 +0200 -@@ -7,11 +7,11 @@ extra-y := vmlinux.lds.s - - obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \ - helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \ -- process.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 \ -- syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \ -- time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \ -- umid.o user_syms.o user_util.o -+ physmem.o process.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 syscall_user.o sysrq.o sys_call_table.o tempfile.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_kern.o initrd_user.o - obj-$(CONFIG_GPROF) += gprof_syms.o -@@ -24,43 +24,27 @@ obj-$(CONFIG_MODE_SKAS) += skas/ - user-objs-$(CONFIG_TTY_LOG) += tty_log.o - - USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \ -- process.o tempfile.o time.o tty_log.o umid.o user_util.o user_syms.o -+ process.o tempfile.o time.o tty_log.o umid.o user_util.o - USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) - --DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__ --DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__ -- -- --CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \ -- -I/usr/include -I../include -- - CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS)) - --$(USER_OBJS) : %.o: %.c -- $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -- - # This has to be separate because it needs be compiled with frame pointers - # regardless of how the rest of the kernel is built. - - $(obj)/frame.o: $(src)/frame.c - $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $< - --QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }' -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< - --$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config -- $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@ -+QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }' - - $(obj)/config.o : $(obj)/config.c - --clean: -- rm -f config.c -- for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done -- --modules: -- --fastdep: -- --dep: -- --archmrproper: clean -+quiet_cmd_quote = QUOTE $@ -+cmd_quote = $(PERL) -e $(QUOTE) < $< > $@ - -+targets += config.c -+$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config FORCE -+ $(call if_changed,quote) -diff -puN arch/um/kernel/mem.c~Main-uml-patch-no-skas arch/um/kernel/mem.c ---- uml-linux-2.6.7/arch/um/kernel/mem.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.532316560 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/mem.c 2004-06-29 21:02:55.729286616 +0200 -@@ -1,74 +1,66 @@ - /* -- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - --#include "linux/config.h" --#include "linux/module.h" --#include "linux/types.h" -+#include "linux/stddef.h" -+#include "linux/kernel.h" - #include "linux/mm.h" --#include "linux/fs.h" --#include "linux/init.h" - #include "linux/bootmem.h" - #include "linux/swap.h" --#include "linux/slab.h" --#include "linux/vmalloc.h" - #include "linux/highmem.h" -+#include "linux/gfp.h" - #include "asm/page.h" --#include "asm/pgtable.h" -+#include "asm/fixmap.h" - #include "asm/pgalloc.h" --#include "asm/bitops.h" --#include "asm/uaccess.h" --#include "asm/tlb.h" - #include "user_util.h" - #include "kern_util.h" --#include "mem_user.h" --#include "mem.h" - #include "kern.h" --#include "init.h" --#include "os.h" --#include "mode_kern.h" -+#include "mem_user.h" - #include "uml_uaccess.h" -+#include "os.h" -+ -+extern char __binary_start; - - /* Changed during early boot */ --pgd_t swapper_pg_dir[1024]; --unsigned long high_physmem; --unsigned long vm_start; --unsigned long vm_end; --unsigned long highmem; - unsigned long *empty_zero_page = NULL; - unsigned long *empty_bad_page = NULL; -- --/* Not modified */ --const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n"; -- --extern char __init_begin, __init_end; --extern long physmem_size; -- --/* Not changed by UML */ --DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -- --/* Changed during early boot */ -+pgd_t swapper_pg_dir[1024]; -+unsigned long highmem; - int kmalloc_ok = 0; - --#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1) --struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL }; --#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1) -- --/* Changed during early boot */ - static unsigned long brk_end; - -+void unmap_physmem(void) -+{ -+ os_unmap_memory((void *) brk_end, uml_reserved - brk_end); -+} -+ - static void map_cb(void *unused) - { - map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); - } - --void unmap_physmem(void) -+#ifdef CONFIG_HIGHMEM -+static void setup_highmem(unsigned long highmem_start, -+ unsigned long highmem_len) - { -- os_unmap_memory((void *) brk_end, uml_reserved - brk_end); --} -+ struct page *page; -+ unsigned long highmem_pfn; -+ int i; - --extern char __binary_start; -+ highmem_start_page = virt_to_page(highmem_start); -+ -+ highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; -+ for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){ -+ page = &mem_map[highmem_pfn + i]; -+ ClearPageReserved(page); -+ set_bit(PG_highmem, &page->flags); -+ set_page_count(page, 1); -+ __free_page(page); -+ } -+} -+#endif - - void mem_init(void) - { -@@ -103,50 +95,15 @@ void mem_init(void) - totalhigh_pages = highmem >> PAGE_SHIFT; - totalram_pages += totalhigh_pages; - num_physpages = totalram_pages; -- max_mapnr = totalram_pages; - max_pfn = totalram_pages; - printk(KERN_INFO "Memory: %luk available\n", - (unsigned long) nr_free_pages() << (PAGE_SHIFT-10)); - kmalloc_ok = 1; --} -- --/* Changed during early boot */ --static unsigned long kmem_top = 0; -- --unsigned long get_kmem_end(void) --{ -- if(kmem_top == 0) -- kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas); -- return(kmem_top); --} -- --void set_kmem_end(unsigned long new) --{ -- kmem_top = new; --} - - #ifdef CONFIG_HIGHMEM --/* Changed during early boot */ --pte_t *kmap_pte; --pgprot_t kmap_prot; -- --EXPORT_SYMBOL(kmap_prot); --EXPORT_SYMBOL(kmap_pte); -- --#define kmap_get_fixmap_pte(vaddr) \ -- pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) -- --void __init kmap_init(void) --{ -- unsigned long kmap_vstart; -- -- /* cache the first kmap pte */ -- kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); -- kmap_pte = kmap_get_fixmap_pte(kmap_vstart); -- -- kmap_prot = PAGE_KERNEL; -+ setup_highmem(end_iomem, highmem); -+#endif - } --#endif /* CONFIG_HIGHMEM */ - - static void __init fixrange_init(unsigned long start, unsigned long end, - pgd_t *pgd_base) -@@ -178,76 +135,24 @@ static void __init fixrange_init(unsigne - } - } - --int init_maps(struct mem_region *region) --{ -- struct page *p, *map; -- int i, n, len; -- -- if(region == &physmem_region){ -- region->mem_map = mem_map; -- return(0); -- } -- else if(region->mem_map != NULL) return(0); -- -- n = region->len >> PAGE_SHIFT; -- len = n * sizeof(struct page); -- if(kmalloc_ok){ -- map = kmalloc(len, GFP_KERNEL); -- if(map == NULL) map = vmalloc(len); -- } -- else map = alloc_bootmem_low_pages(len); -- -- if(map == NULL) -- return(-ENOMEM); -- for(i = 0; i < n; i++){ -- p = &map[i]; -- set_page_count(p, 0); -- SetPageReserved(p); -- INIT_LIST_HEAD(&p->list); -- } -- region->mem_map = map; -- return(0); --} -+#if CONFIG_HIGHMEM -+pte_t *kmap_pte; -+pgprot_t kmap_prot; - --DECLARE_MUTEX(regions_sem); -+#define kmap_get_fixmap_pte(vaddr) \ -+ pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) - --static int setup_one_range(int fd, char *driver, unsigned long start, -- unsigned long pfn, int len, -- struct mem_region *region) -+void __init kmap_init(void) - { -- int i; -- -- down(®ions_sem); -- for(i = 0; i < NREGIONS; i++){ -- if(regions[i] == NULL) break; -- } -- if(i == NREGIONS){ -- printk("setup_range : no free regions\n"); -- i = -1; -- goto out; -- } -- -- if(fd == -1) -- fd = create_mem_file(len); -+ unsigned long kmap_vstart; - -- if(region == NULL){ -- region = alloc_bootmem_low_pages(sizeof(*region)); -- if(region == NULL) -- panic("Failed to allocating mem_region"); -- } -+ /* cache the first kmap pte */ -+ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); -+ kmap_pte = kmap_get_fixmap_pte(kmap_vstart); - -- *region = ((struct mem_region) { .driver = driver, -- .start_pfn = pfn, -- .start = start, -- .len = len, -- .fd = fd } ); -- regions[i] = region; -- out: -- up(®ions_sem); -- return(i); -+ kmap_prot = PAGE_KERNEL; - } - --#ifdef CONFIG_HIGHMEM - static void init_highmem(void) - { - pgd_t *pgd; -@@ -268,63 +173,20 @@ static void init_highmem(void) - - kmap_init(); - } -- --void setup_highmem(unsigned long len) --{ -- struct mem_region *region; -- struct page *page, *map; -- unsigned long phys; -- int i, cur, index; -- -- phys = physmem_size; -- do { -- cur = min(len, (unsigned long) REGION_SIZE); -- i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur, -- NULL); -- if(i == -1){ -- printk("setup_highmem - setup_one_range failed\n"); -- return; -- } -- region = regions[i]; -- index = phys / PAGE_SIZE; -- region->mem_map = &mem_map[index]; -- -- map = region->mem_map; -- for(i = 0; i < (cur >> PAGE_SHIFT); i++){ -- page = &map[i]; -- ClearPageReserved(page); -- set_bit(PG_highmem, &page->flags); -- set_page_count(page, 1); -- __free_page(page); -- } -- phys += cur; -- len -= cur; -- } while(len > 0); --} --#endif -+#endif /* CONFIG_HIGHMEM */ - - void paging_init(void) - { -- struct mem_region *region; -- unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr; -- int i, index; -+ unsigned long zones_size[MAX_NR_ZONES], vaddr; -+ int i; - - empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); - empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); - for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) - zones_size[i] = 0; -- zones_size[0] = (high_physmem >> PAGE_SHIFT) - -- (uml_physmem >> PAGE_SHIFT); -+ zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT); - zones_size[2] = highmem >> PAGE_SHIFT; - free_area_init(zones_size); -- start = phys_region_index(__pa(uml_physmem)); -- end = phys_region_index(__pa(high_physmem - 1)); -- for(i = start; i <= end; i++){ -- region = regions[i]; -- index = (region->start - uml_physmem) / PAGE_SIZE; -- region->mem_map = &mem_map[index]; -- if(i > start) free_bootmem(__pa(region->start), region->len); -- } - - /* - * Fixed mappings, only the page table structure has to be -@@ -335,15 +197,33 @@ void paging_init(void) - - #ifdef CONFIG_HIGHMEM - init_highmem(); -- setup_highmem(highmem); - #endif - } - --pte_t __bad_page(void) -+struct page *arch_validate(struct page *page, int mask, int order) - { -- clear_page(empty_bad_page); -- return pte_mkdirty(mk_pte((struct page *) empty_bad_page, -- PAGE_SHARED)); -+ unsigned long addr, zero = 0; -+ int i; -+ -+ again: -+ if(page == NULL) return(page); -+ if(PageHighMem(page)) return(page); -+ -+ addr = (unsigned long) page_address(page); -+ for(i = 0; i < (1 << order); i++){ -+ current->thread.fault_addr = (void *) addr; -+ if(__do_copy_to_user((void *) addr, &zero, -+ sizeof(zero), -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)){ -+ if(!(mask & __GFP_WAIT)) return(NULL); -+ else break; -+ } -+ addr += PAGE_SIZE; -+ } -+ if(i == (1 << order)) return(page); -+ page = alloc_pages(mask, order); -+ goto again; - } - - /* This can't do anything because nothing in the kernel image can be freed -@@ -401,395 +281,6 @@ void show_mem(void) - printk("%d pages swap cached\n", cached); - } - --static int __init uml_mem_setup(char *line, int *add) --{ -- char *retptr; -- physmem_size = memparse(line,&retptr); -- return 0; --} --__uml_setup("mem=", uml_mem_setup, --"mem=<Amount of desired ram>\n" --" This controls how much \"physical\" memory the kernel allocates\n" --" for the system. The size is specified as a number followed by\n" --" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n" --" This is not related to the amount of memory in the physical\n" --" machine. It can be more, and the excess, if it's ever used, will\n" --" just be swapped out.\n Example: mem=64M\n\n" --); -- --struct page *arch_validate(struct page *page, int mask, int order) --{ -- unsigned long addr, zero = 0; -- int i; -- -- again: -- if(page == NULL) return(page); -- if(PageHighMem(page)) return(page); -- -- addr = (unsigned long) page_address(page); -- for(i = 0; i < (1 << order); i++){ -- current->thread.fault_addr = (void *) addr; -- if(__do_copy_to_user((void *) addr, &zero, -- sizeof(zero), -- ¤t->thread.fault_addr, -- ¤t->thread.fault_catcher)){ -- if(!(mask & __GFP_WAIT)) return(NULL); -- else break; -- } -- addr += PAGE_SIZE; -- } -- if(i == (1 << order)) return(page); -- page = alloc_pages(mask, order); -- goto again; --} -- --DECLARE_MUTEX(vm_reserved_sem); --static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved); -- --/* Static structures, linked in to the list in early boot */ --static struct vm_reserved head = { -- .list = LIST_HEAD_INIT(head.list), -- .start = 0, -- .end = 0xffffffff --}; -- --static struct vm_reserved tail = { -- .list = LIST_HEAD_INIT(tail.list), -- .start = 0, -- .end = 0xffffffff --}; -- --void set_usable_vm(unsigned long start, unsigned long end) --{ -- list_add(&head.list, &vm_reserved); -- list_add(&tail.list, &head.list); -- head.end = start; -- tail.start = end; --} -- --int reserve_vm(unsigned long start, unsigned long end, void *e) -- --{ -- struct vm_reserved *entry = e, *reserved, *prev; -- struct list_head *ele; -- int err; -- -- down(&vm_reserved_sem); -- list_for_each(ele, &vm_reserved){ -- reserved = list_entry(ele, struct vm_reserved, list); -- if(reserved->start >= end) goto found; -- } -- panic("Reserved vm out of range"); -- found: -- prev = list_entry(ele->prev, struct vm_reserved, list); -- if(prev->end > start) -- panic("Can't reserve vm"); -- if(entry == NULL) -- entry = kmalloc(sizeof(*entry), GFP_KERNEL); -- if(entry == NULL){ -- printk("reserve_vm : Failed to allocate entry\n"); -- err = -ENOMEM; -- goto out; -- } -- *entry = ((struct vm_reserved) -- { .list = LIST_HEAD_INIT(entry->list), -- .start = start, -- .end = end }); -- list_add(&entry->list, &prev->list); -- err = 0; -- out: -- up(&vm_reserved_sem); -- return(0); --} -- --unsigned long get_vm(unsigned long len) --{ -- struct vm_reserved *this, *next; -- struct list_head *ele; -- unsigned long start; -- int err; -- -- down(&vm_reserved_sem); -- list_for_each(ele, &vm_reserved){ -- this = list_entry(ele, struct vm_reserved, list); -- next = list_entry(ele->next, struct vm_reserved, list); -- if((this->start < next->start) && -- (this->end + len + PAGE_SIZE <= next->start)) -- goto found; -- } -- up(&vm_reserved_sem); -- return(0); -- found: -- up(&vm_reserved_sem); -- start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE; -- err = reserve_vm(start, start + len, NULL); -- if(err) return(0); -- return(start); --} -- --int nregions(void) --{ -- return(NREGIONS); --} -- --void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn, -- unsigned long len, int need_vm, struct mem_region *region, -- void *reserved) --{ -- int i, cur; -- -- do { -- cur = min(len, (unsigned long) REGION_SIZE); -- i = setup_one_range(fd, driver, start, pfn, cur, region); -- region = regions[i]; -- if(need_vm && setup_region(region, reserved)){ -- kfree(region); -- regions[i] = NULL; -- return; -- } -- start += cur; -- if(pfn != -1) pfn += cur; -- len -= cur; -- } while(len > 0); --} -- --struct iomem { -- char *name; -- int fd; -- unsigned long size; --}; -- --/* iomem regions can only be added on the command line at the moment. -- * Locking will be needed when they can be added via mconsole. -- */ -- --struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = -- { .name = NULL, -- .fd = -1, -- .size = 0 } }; -- --int num_iomem_regions = 0; -- --void add_iomem(char *name, int fd, unsigned long size) --{ -- if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0])) -- return; -- size = (size + PAGE_SIZE - 1) & PAGE_MASK; -- iomem_regions[num_iomem_regions++] = -- ((struct iomem) { .name = name, -- .fd = fd, -- .size = size } ); --} -- --int setup_iomem(void) --{ -- struct iomem *iomem; -- int i; -- -- for(i = 0; i < num_iomem_regions; i++){ -- iomem = &iomem_regions[i]; -- setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1, -- NULL, NULL); -- } -- return(0); --} -- --__initcall(setup_iomem); -- --#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) --#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -- --/* Changed during early boot */ --static struct mem_region physmem_region; --static struct vm_reserved physmem_reserved; -- --void setup_physmem(unsigned long start, unsigned long reserve_end, -- unsigned long len) --{ -- struct mem_region *region = &physmem_region; -- struct vm_reserved *reserved = &physmem_reserved; -- unsigned long cur, pfn = 0; -- int do_free = 1, bootmap_size; -- -- do { -- cur = min(len, (unsigned long) REGION_SIZE); -- if(region == NULL) -- region = alloc_bootmem_low_pages(sizeof(*region)); -- if(reserved == NULL) -- reserved = alloc_bootmem_low_pages(sizeof(*reserved)); -- if((region == NULL) || (reserved == NULL)) -- panic("Couldn't allocate physmem region or vm " -- "reservation\n"); -- setup_range(-1, NULL, start, pfn, cur, 1, region, reserved); -- -- if(do_free){ -- unsigned long reserve = reserve_end - start; -- int pfn = PFN_UP(__pa(reserve_end)); -- int delta = (len - reserve) >> PAGE_SHIFT; -- -- bootmap_size = init_bootmem(pfn, pfn + delta); -- free_bootmem(__pa(reserve_end) + bootmap_size, -- cur - bootmap_size - reserve); -- do_free = 0; -- } -- start += cur; -- pfn += cur >> PAGE_SHIFT; -- len -= cur; -- region = NULL; -- reserved = NULL; -- } while(len > 0); --} -- --struct mem_region *phys_region(unsigned long phys) --{ -- unsigned int n = phys_region_index(phys); -- -- if(regions[n] == NULL) -- panic("Physical address in uninitialized region"); -- return(regions[n]); --} -- --unsigned long phys_offset(unsigned long phys) --{ -- return(phys_addr(phys)); --} -- --struct page *phys_mem_map(unsigned long phys) --{ -- return((struct page *) phys_region(phys)->mem_map); --} -- --struct page *pte_mem_map(pte_t pte) --{ -- return(phys_mem_map(pte_val(pte))); --} -- --struct mem_region *page_region(struct page *page, int *index_out) --{ -- int i; -- struct mem_region *region; -- struct page *map; -- -- for(i = 0; i < NREGIONS; i++){ -- region = regions[i]; -- if(region == NULL) continue; -- map = region->mem_map; -- if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){ -- if(index_out != NULL) *index_out = i; -- return(region); -- } -- } -- panic("No region found for page"); -- return(NULL); --} -- --unsigned long page_to_pfn(struct page *page) --{ -- struct mem_region *region = page_region(page, NULL); -- -- return(region->start_pfn + (page - (struct page *) region->mem_map)); --} -- --struct mem_region *pfn_to_region(unsigned long pfn, int *index_out) --{ -- struct mem_region *region; -- int i; -- -- for(i = 0; i < NREGIONS; i++){ -- region = regions[i]; -- if(region == NULL) -- continue; -- -- if((region->start_pfn <= pfn) && -- (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){ -- if(index_out != NULL) -- *index_out = i; -- return(region); -- } -- } -- return(NULL); --} -- --struct page *pfn_to_page(unsigned long pfn) --{ -- struct mem_region *region = pfn_to_region(pfn, NULL); -- struct page *mem_map = (struct page *) region->mem_map; -- -- return(&mem_map[pfn - region->start_pfn]); --} -- --unsigned long phys_to_pfn(unsigned long p) --{ -- struct mem_region *region = regions[phys_region_index(p)]; -- -- return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT)); --} -- --unsigned long pfn_to_phys(unsigned long pfn) --{ -- int n; -- struct mem_region *region = pfn_to_region(pfn, &n); -- -- return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n)); --} -- --struct page *page_mem_map(struct page *page) --{ -- return((struct page *) page_region(page, NULL)->mem_map); --} -- --extern unsigned long region_pa(void *virt) --{ -- struct mem_region *region; -- unsigned long addr = (unsigned long) virt; -- int i; -- -- for(i = 0; i < NREGIONS; i++){ -- region = regions[i]; -- if(region == NULL) continue; -- if((region->start <= addr) && -- (addr <= region->start + region->len)) -- return(mk_phys(addr - region->start, i)); -- } -- panic("region_pa : no region for virtual address"); -- return(0); --} -- --extern void *region_va(unsigned long phys) --{ -- return((void *) (phys_region(phys)->start + phys_addr(phys))); --} -- --unsigned long page_to_phys(struct page *page) --{ -- int n; -- struct mem_region *region = page_region(page, &n); -- struct page *map = region->mem_map; -- return(mk_phys((page - map) << PAGE_SHIFT, n)); --} -- --struct page *phys_to_page(unsigned long phys) --{ -- struct page *mem_map; -- -- mem_map = phys_mem_map(phys); -- return(mem_map + (phys_offset(phys) >> PAGE_SHIFT)); --} -- --static int setup_mem_maps(void) --{ -- struct mem_region *region; -- int i; -- -- for(i = 0; i < NREGIONS; i++){ -- region = regions[i]; -- if((region != NULL) && (region->fd > 0)) init_maps(region); -- } -- return(0); --} -- --__initcall(setup_mem_maps); -- - /* - * Allocate and free page tables. - */ -diff -puN arch/um/kernel/mem_user.c~Main-uml-patch-no-skas arch/um/kernel/mem_user.c ---- uml-linux-2.6.7/arch/um/kernel/mem_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.533316408 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/mem_user.c 2004-06-29 21:02:55.729286616 +0200 -@@ -34,10 +34,9 @@ - #include <stddef.h> - #include <stdarg.h> - #include <unistd.h> --#include <fcntl.h> - #include <errno.h> - #include <string.h> --#include <sys/stat.h> -+#include <fcntl.h> - #include <sys/types.h> - #include <sys/mman.h> - #include "kern_util.h" -@@ -47,105 +46,145 @@ - #include "init.h" - #include "os.h" - #include "tempfile.h" -+#include "kern_constants.h" - - extern struct mem_region physmem_region; - - #define TEMPNAME_TEMPLATE "vm_file-XXXXXX" - --int create_mem_file(unsigned long len) -+static int create_tmp_file(unsigned long len) - { -- int fd; -+ int fd, err; - char zero; - - fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1); -- if (fchmod(fd, 0777) < 0){ -- perror("fchmod"); -+ 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); - } -- if(os_seek_file(fd, len) < 0){ -- perror("lseek"); -+ err = os_seek_file(fd, len); -+ if(err < 0){ -+ os_print_error(err, "os_seek_file"); - exit(1); - } - zero = 0; -- if(write(fd, &zero, 1) != 1){ -- perror("write"); -+ err = os_write_file(fd, &zero, 1); -+ if(err != 1){ -+ os_print_error(err, "os_write_file"); - exit(1); - } -- if(fcntl(fd, F_SETFD, 1) != 0) -- perror("Setting FD_CLOEXEC failed"); -+ - return(fd); - } - --int setup_region(struct mem_region *region, void *entry) -+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 *loc, *start; -- char *driver; -- int err, offset; -- -- if(region->start != -1){ -- err = reserve_vm(region->start, -- region->start + region->len, entry); -- if(err){ -- printk("setup_region : failed to reserve " -- "0x%x - 0x%x for driver '%s'\n", -- region->start, -- region->start + region->len, -- region->driver); -- return(-1); -- } -- } -- else region->start = get_vm(region->len); -- if(region->start == 0){ -- if(region->driver == NULL) driver = "physmem"; -- else driver = region->driver; -- printk("setup_region : failed to find vm for " -- "driver '%s' (length %d)\n", driver, region->len); -- return(-1); -- } -- if(region->start == uml_physmem){ -- start = (void *) uml_reserved; -- offset = uml_reserved - uml_physmem; -- } -- else { -- start = (void *) region->start; -- offset = 0; -- } -- -- loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, -- MAP_SHARED | MAP_FIXED, region->fd, offset); -- if(loc != start){ -- perror("Mapping memory"); -+ void *addr; -+ int fd; -+ -+ fd = open("/dev/anon", O_RDWR); -+ if(fd < 0) { -+ os_print_error(fd, "opening /dev/anon"); - exit(1); - } -- return(0); -+ -+ addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0); -+ if(addr == MAP_FAILED){ -+ os_print_error((int) addr, "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 stat buf; -+ struct iomem_region *new; -+ struct uml_stat buf; - char *file, *driver; -- int fd; -+ int fd, err; - - driver = str; - file = strchr(str,','); - if(file == NULL){ -- printk("parse_iomem : failed to parse iomem\n"); -- return(1); -+ 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){ -- printk("parse_iomem - Couldn't open io file, errno = %d\n", -- errno); -- return(1); -- } -- if(fstat(fd, &buf) < 0) { -- printk("parse_iomem - cannot fstat file, errno = %d\n", errno); -- return(1); -+ os_print_error(fd, "parse_iomem - Couldn't open io file"); -+ goto out; - } -- add_iomem(driver, fd, buf.st_size); -+ -+ 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; -+ } -+ -+ *new = ((struct iomem_region) { .next = iomem_regions, -+ .driver = driver, -+ .fd = fd, -+ .size = buf.ust_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); - } - - __uml_setup("iomem=", parse_iomem, -@@ -153,73 +192,20 @@ __uml_setup("iomem=", parse_iomem, - " Configure <file> as an IO memory region named <name>.\n\n" - ); - --#ifdef notdef --int logging = 0; --int logging_fd = -1; -- --int logging_line = 0; --char logging_buf[256]; -- --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_rdrw(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 -- --int map_memory(unsigned long virt, unsigned long phys, unsigned long len, -- int r, int w, int x) --{ -- struct mem_region *region = phys_region(phys); -- -- return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len, -- r, w, x)); --} -- - int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, - int must_succeed) - { -- if(os_protect_memory((void *) addr, len, r, w, x) < 0){ -+ int err; -+ -+ err = os_protect_memory((void *) addr, len, r, w, x); -+ if(err < 0){ - if(must_succeed) -- panic("protect failed, errno = %d", errno); -- else return(-errno); -+ panic("protect failed, err = %d", -err); -+ else return(err); - } - return(0); - } - --unsigned long find_iomem(char *driver, unsigned long *len_out) --{ -- struct mem_region *region; -- int i, n; -- -- n = nregions(); -- for(i = 0; i < n; i++){ -- region = regions[i]; -- if(region == NULL) continue; -- if((region->driver != NULL) && -- !strcmp(region->driver, driver)){ -- *len_out = region->len; -- return(region->start); -- } -- } -- *len_out = 0; -- return 0; --} -- - /* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically -diff -puN /dev/null arch/um/kernel/physmem.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/physmem.c 2004-06-29 21:02:55.730286464 +0200 -@@ -0,0 +1,468 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/mm.h" -+#include "linux/ghash.h" -+#include "linux/slab.h" -+#include "linux/vmalloc.h" -+#include "linux/bootmem.h" -+#include "asm/types.h" -+#include "asm/pgtable.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "mode_kern.h" -+#include "mem.h" -+#include "mem_user.h" -+#include "os.h" -+#include "kern.h" -+#include "init.h" -+ -+#if 0 -+static pgd_t physmem_pgd[PTRS_PER_PGD]; -+ -+static struct phys_desc *lookup_mapping(void *addr) -+{ -+ pgd = &physmem_pgd[pgd_index(addr)]; -+ if(pgd_none(pgd)) -+ return(NULL); -+ -+ pmd = pmd_offset(pgd, addr); -+ if(pmd_none(pmd)) -+ return(NULL); -+ -+ pte = pte_offset_kernel(pmd, addr); -+ return((struct phys_desc *) pte_val(pte)); -+} -+ -+static struct add_mapping(void *addr, struct phys_desc *new) -+{ -+} -+#endif -+ -+#define PHYS_HASHSIZE (8192) -+ -+struct phys_desc; -+ -+DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc); -+ -+struct phys_desc { -+ struct virtmem_ptrs virt_ptrs; -+ int fd; -+ __u64 offset; -+ void *virt; -+ unsigned long phys; -+ struct list_head list; -+}; -+ -+struct virtmem_table virtmem_hash; -+ -+static int virt_cmp(void *virt1, void *virt2) -+{ -+ return(virt1 != virt2); -+} -+ -+static int virt_hash(void *virt) -+{ -+ unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT; -+ return(addr % PHYS_HASHSIZE); -+} -+ -+DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, -+ virt_hash); -+ -+LIST_HEAD(descriptor_mappings); -+ -+struct desc_mapping { -+ int fd; -+ struct list_head list; -+ struct list_head pages; -+}; -+ -+static struct desc_mapping *find_mapping(int fd) -+{ -+ struct desc_mapping *desc; -+ struct list_head *ele; -+ -+ list_for_each(ele, &descriptor_mappings){ -+ desc = list_entry(ele, struct desc_mapping, list); -+ if(desc->fd == fd) -+ return(desc); -+ } -+ -+ return(NULL); -+} -+ -+static struct desc_mapping *descriptor_mapping(int fd) -+{ -+ struct desc_mapping *desc; -+ -+ desc = find_mapping(fd); -+ if(desc != NULL) -+ return(desc); -+ -+ desc = kmalloc(sizeof(*desc), GFP_ATOMIC); -+ if(desc == NULL) -+ return(NULL); -+ -+ *desc = ((struct desc_mapping) -+ { .fd = fd, -+ .list = LIST_HEAD_INIT(desc->list), -+ .pages = LIST_HEAD_INIT(desc->pages) }); -+ list_add(&desc->list, &descriptor_mappings); -+ -+ return(desc); -+} -+ -+int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) -+{ -+ struct desc_mapping *fd_maps; -+ struct phys_desc *desc; -+ unsigned long phys; -+ int err; -+ -+ fd_maps = descriptor_mapping(fd); -+ if(fd_maps == NULL) -+ return(-ENOMEM); -+ -+ phys = __pa(virt); -+ if(find_virtmem_hash(&virtmem_hash, virt) != NULL) -+ panic("Address 0x%p is already substituted\n", virt); -+ -+ err = -ENOMEM; -+ desc = kmalloc(sizeof(*desc), GFP_ATOMIC); -+ if(desc == NULL) -+ goto out; -+ -+ *desc = ((struct phys_desc) -+ { .virt_ptrs = { NULL, NULL }, -+ .fd = fd, -+ .offset = offset, -+ .virt = virt, -+ .phys = __pa(virt), -+ .list = LIST_HEAD_INIT(desc->list) }); -+ insert_virtmem_hash(&virtmem_hash, desc); -+ -+ list_add(&desc->list, &fd_maps->pages); -+ -+ virt = (void *) ((unsigned long) virt & PAGE_MASK); -+ err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0); -+ if(!err) -+ goto out; -+ -+ remove_virtmem_hash(&virtmem_hash, desc); -+ kfree(desc); -+ out: -+ return(err); -+} -+ -+static int physmem_fd = -1; -+ -+static void remove_mapping(struct phys_desc *desc) -+{ -+ void *virt = desc->virt; -+ int err; -+ -+ remove_virtmem_hash(&virtmem_hash, desc); -+ list_del(&desc->list); -+ kfree(desc); -+ -+ err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0); -+ if(err) -+ panic("Failed to unmap block device page from physical memory, " -+ "errno = %d", -err); -+} -+ -+int physmem_remove_mapping(void *virt) -+{ -+ struct phys_desc *desc; -+ -+ virt = (void *) ((unsigned long) virt & PAGE_MASK); -+ desc = find_virtmem_hash(&virtmem_hash, virt); -+ if(desc == NULL) -+ return(0); -+ -+ remove_mapping(desc); -+ return(1); -+} -+ -+void physmem_forget_descriptor(int fd) -+{ -+ struct desc_mapping *desc; -+ struct phys_desc *page; -+ struct list_head *ele, *next; -+ __u64 offset; -+ void *addr; -+ int err; -+ -+ desc = find_mapping(fd); -+ if(desc == NULL) -+ return; -+ -+ list_for_each_safe(ele, next, &desc->pages){ -+ page = list_entry(ele, struct phys_desc, list); -+ offset = page->offset; -+ addr = page->virt; -+ remove_mapping(page); -+ err = os_seek_file(fd, offset); -+ if(err) -+ panic("physmem_forget_descriptor - failed to seek " -+ "to %lld in fd %d, error = %d\n", -+ offset, fd, -err); -+ err = os_read_file(fd, addr, PAGE_SIZE); -+ if(err < 0) -+ panic("physmem_forget_descriptor - failed to read " -+ "from fd %d to 0x%p, error = %d\n", -+ fd, addr, -err); -+ } -+ -+ list_del(&desc->list); -+ kfree(desc); -+} -+ -+void arch_free_page(struct page *page, int order) -+{ -+ void *virt; -+ int i; -+ -+ for(i = 0; i < (1 << order); i++){ -+ virt = __va(page_to_phys(page + i)); -+ physmem_remove_mapping(virt); -+ } -+} -+ -+int is_remapped(void *virt) -+{ -+ return(find_virtmem_hash(&virtmem_hash, virt) != NULL); -+} -+ -+/* Changed during early boot */ -+unsigned long high_physmem; -+ -+extern unsigned long physmem_size; -+ -+void *to_virt(unsigned long phys) -+{ -+ return((void *) uml_physmem + phys); -+} -+ -+unsigned long to_phys(void *virt) -+{ -+ return(((unsigned long) virt) - uml_physmem); -+} -+ -+int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem) -+{ -+ struct page *p, *map; -+ unsigned long phys_len, phys_pages, highmem_len, highmem_pages; -+ unsigned long iomem_len, iomem_pages, total_len, total_pages; -+ int i; -+ -+ phys_pages = physmem >> PAGE_SHIFT; -+ phys_len = phys_pages * sizeof(struct page); -+ -+ iomem_pages = iomem >> PAGE_SHIFT; -+ iomem_len = iomem_pages * sizeof(struct page); -+ -+ highmem_pages = highmem >> PAGE_SHIFT; -+ highmem_len = highmem_pages * sizeof(struct page); -+ -+ total_pages = phys_pages + iomem_pages + highmem_pages; -+ total_len = phys_len + iomem_pages + highmem_len; -+ -+ if(kmalloc_ok){ -+ map = kmalloc(total_len, GFP_KERNEL); -+ if(map == NULL) -+ map = vmalloc(total_len); -+ } -+ else map = alloc_bootmem_low_pages(total_len); -+ -+ if(map == NULL) -+ return(-ENOMEM); -+ -+ for(i = 0; i < total_pages; i++){ -+ p = &map[i]; -+ set_page_count(p, 0); -+ SetPageReserved(p); -+ INIT_LIST_HEAD(&p->lru); -+ } -+ -+ mem_map = map; -+ max_mapnr = total_pages; -+ return(0); -+} -+ -+struct page *phys_to_page(const unsigned long phys) -+{ -+ return(&mem_map[phys >> PAGE_SHIFT]); -+} -+ -+struct page *__virt_to_page(const unsigned long virt) -+{ -+ return(&mem_map[__pa(virt) >> PAGE_SHIFT]); -+} -+ -+unsigned long page_to_phys(struct page *page) -+{ -+ return((page - mem_map) << PAGE_SHIFT); -+} -+ -+pte_t mk_pte(struct page *page, pgprot_t pgprot) -+{ -+ pte_t pte; -+ -+ pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot); -+ if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte)); -+ return(pte); -+} -+ -+/* Changed during early boot */ -+static unsigned long kmem_top = 0; -+ -+unsigned long get_kmem_end(void) -+{ -+ if(kmem_top == 0) -+ kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas); -+ return(kmem_top); -+} -+ -+void map_memory(unsigned long virt, unsigned long phys, unsigned long len, -+ int r, int w, int x) -+{ -+ __u64 offset; -+ int fd, err; -+ -+ fd = phys_mapping(phys, &offset); -+ err = os_map_memory((void *) virt, fd, offset, len, r, w, x); -+ if(err) -+ panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, " -+ "err = %d\n", virt, fd, offset, len, r, w, x, err); -+} -+ -+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -+ -+void setup_physmem(unsigned long start, unsigned long reserve_end, -+ unsigned long len, unsigned long highmem) -+{ -+ unsigned long reserve = reserve_end - start; -+ int pfn = PFN_UP(__pa(reserve_end)); -+ int delta = (len - reserve) >> PAGE_SHIFT; -+ int err, offset, bootmap_size; -+ -+ physmem_fd = create_mem_file(len + highmem); -+ -+ offset = uml_reserved - uml_physmem; -+ err = os_map_memory((void *) uml_reserved, physmem_fd, offset, -+ len - offset, 1, 1, 0); -+ if(err < 0){ -+ os_print_error(err, "Mapping memory"); -+ exit(1); -+ } -+ -+ bootmap_size = init_bootmem(pfn, pfn + delta); -+ free_bootmem(__pa(reserve_end) + bootmap_size, -+ len - bootmap_size - reserve); -+} -+ -+int phys_mapping(unsigned long phys, __u64 *offset_out) -+{ -+ struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, -+ __va(phys & PAGE_MASK)); -+ int fd = -1; -+ -+ if(desc != NULL){ -+ fd = desc->fd; -+ *offset_out = desc->offset; -+ } -+ else if(phys < physmem_size){ -+ fd = physmem_fd; -+ *offset_out = phys; -+ } -+ else if(phys < __pa(end_iomem)){ -+ struct iomem_region *region = iomem_regions; -+ -+ while(region != NULL){ -+ if((phys >= region->phys) && -+ (phys < region->phys + region->size)){ -+ fd = region->fd; -+ *offset_out = phys - region->phys; -+ break; -+ } -+ region = region->next; -+ } -+ } -+ else if(phys < __pa(end_iomem) + highmem){ -+ fd = physmem_fd; -+ *offset_out = phys - iomem_size; -+ } -+ -+ return(fd); -+} -+ -+static int __init uml_mem_setup(char *line, int *add) -+{ -+ char *retptr; -+ physmem_size = memparse(line,&retptr); -+ return 0; -+} -+__uml_setup("mem=", uml_mem_setup, -+"mem=<Amount of desired ram>\n" -+" This controls how much \"physical\" memory the kernel allocates\n" -+" for the system. The size is specified as a number followed by\n" -+" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n" -+" This is not related to the amount of memory in the host. It can\n" -+" be more, and the excess, if it's ever used, will just be swapped out.\n" -+" Example: mem=64M\n\n" -+); -+ -+unsigned long find_iomem(char *driver, unsigned long *len_out) -+{ -+ struct iomem_region *region = iomem_regions; -+ -+ while(region != NULL){ -+ if(!strcmp(region->driver, driver)){ -+ *len_out = region->size; -+ return(region->virt); -+ } -+ } -+ -+ return(0); -+} -+ -+int setup_iomem(void) -+{ -+ struct iomem_region *region = iomem_regions; -+ unsigned long iomem_start = high_physmem + PAGE_SIZE; -+ int err; -+ -+ while(region != NULL){ -+ err = os_map_memory((void *) iomem_start, region->fd, 0, -+ region->size, 1, 1, 0); -+ if(err) -+ printk("Mapping iomem region for driver '%s' failed, " -+ "errno = %d\n", region->driver, -err); -+ else { -+ region->virt = iomem_start; -+ region->phys = __pa(region->virt); -+ } -+ -+ iomem_start += region->size + PAGE_SIZE; -+ region = region->next; -+ } -+ -+ return(0); -+} -+ -+__initcall(setup_iomem); -+ -+/* -+ * 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 -puN arch/um/kernel/process.c~Main-uml-patch-no-skas arch/um/kernel/process.c ---- uml-linux-2.6.7/arch/um/kernel/process.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.534316256 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/process.c 2004-06-29 21:02:55.731286312 +0200 -@@ -9,12 +9,10 @@ - #include <sched.h> - #include <errno.h> - #include <stdarg.h> --#include <fcntl.h> - #include <stdlib.h> - #include <setjmp.h> - #include <sys/time.h> - #include <sys/ptrace.h> --#include <sys/ioctl.h> - #include <sys/wait.h> - #include <sys/mman.h> - #include <asm/ptrace.h> -@@ -58,7 +56,11 @@ void init_new_thread_signals(int altstac - { - int flags = altstack ? SA_ONSTACK : 0; - -- set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags, -+ /* NODEFER is set here because SEGV isn't turned back on when the -+ * handler is ready to receive signals. This causes any segfault -+ * during a copy_user to kill the process because the fault is blocked. -+ */ -+ set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); - set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -@@ -72,7 +74,6 @@ void init_new_thread_signals(int altstac - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); - set_handler(SIGUSR2, (__sighandler_t) sig_handler, - SA_NOMASK | flags, -1); -- (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0); - signal(SIGHUP, SIG_IGN); - - init_irq_signals(altstack); -@@ -123,11 +124,12 @@ int start_fork_tramp(void *thread_arg, u - /* Start the process and wait for it to kill itself */ - new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg); - if(new_pid < 0) return(-errno); -- while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ; -+ while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ; - if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", - errno); - if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL)) -- panic("outer trampoline didn't exit with SIGKILL"); -+ panic("outer trampoline didn't exit with SIGKILL, " -+ "status = %d", status); - - return(arg.pid); - } -@@ -138,7 +140,7 @@ void suspend_new_thread(int fd) - - os_stop_process(os_getpid()); - -- if(read(fd, &c, sizeof(c)) != sizeof(c)) -+ if(os_read_file(fd, &c, sizeof(c)) != sizeof(c)) - panic("read failed in suspend_new_thread"); - } - -@@ -233,7 +235,7 @@ int run_kernel_thread(int (*fn)(void *), - int n; - - *jmp_ptr = &buf; -- n = setjmp(buf); -+ n = sigsetjmp(buf, 1); - if(n != 0) - return(n); - (*fn)(arg); -@@ -273,7 +275,7 @@ int can_do_skas(void) - stop_ptraced_child(pid, stack, 1); - - printf("Checking for /proc/mm..."); -- if(access("/proc/mm", W_OK)){ -+ if(os_access("/proc/mm", OS_ACC_W_OK) < 0){ - printf("not found\n"); - ret = 0; - } -diff -puN arch/um/kernel/process_kern.c~Main-uml-patch-no-skas arch/um/kernel/process_kern.c ---- uml-linux-2.6.7/arch/um/kernel/process_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.535316104 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/process_kern.c 2004-06-29 21:02:55.731286312 +0200 -@@ -16,6 +16,7 @@ - #include "linux/module.h" - #include "linux/init.h" - #include "linux/capability.h" -+#include "linux/spinlock.h" - #include "asm/unistd.h" - #include "asm/mman.h" - #include "asm/segment.h" -@@ -23,7 +24,6 @@ - #include "asm/pgtable.h" - #include "asm/processor.h" - #include "asm/tlbflush.h" --#include "asm/spinlock.h" - #include "asm/uaccess.h" - #include "asm/user.h" - #include "user_util.h" -@@ -52,17 +52,12 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [ - - struct task_struct *get_task(int pid, int require) - { -- struct task_struct *task, *ret; -+ struct task_struct *ret; - -- ret = NULL; - read_lock(&tasklist_lock); -- for_each_process(task){ -- if(task->pid == pid){ -- ret = task; -- break; -- } -- } -+ ret = find_task_by_pid(pid); - read_unlock(&tasklist_lock); -+ - if(require && (ret == NULL)) panic("get_task couldn't find a task\n"); - return(ret); - } -@@ -95,7 +90,8 @@ unsigned long alloc_stack(int order, int - int flags = GFP_KERNEL; - - if(atomic) flags |= GFP_ATOMIC; -- if((page = __get_free_pages(flags, order)) == 0) -+ page = __get_free_pages(flags, order); -+ if(page == 0) - return(0); - stack_protections(page); - return(page); -@@ -103,13 +99,15 @@ unsigned long alloc_stack(int order, int - - int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) - { -- struct task_struct *p; -+ int pid; - - current->thread.request.u.thread.proc = fn; - current->thread.request.u.thread.arg = arg; -- p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL); -- if(IS_ERR(p)) panic("do_fork failed in kernel_thread"); -- return(p->pid); -+ pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL, -+ NULL); -+ if(pid < 0) -+ panic("do_fork failed in kernel_thread, errno = %d", pid); -+ return(pid); - } - - void switch_mm(struct mm_struct *prev, struct mm_struct *next, -@@ -129,7 +127,7 @@ void set_current(void *t) - { external_pid(task), task }); - } - --void *switch_to(void *prev, void *next, void *last) -+void *_switch_to(void *prev, void *next, void *last) - { - return(CHOOSE_MODE(switch_to_tt(prev, next), - switch_to_skas(prev, next))); -@@ -149,7 +147,7 @@ void release_thread(struct task_struct * - void exit_thread(void) - { - CHOOSE_MODE(exit_thread_tt(), exit_thread_skas()); -- unprotect_stack((unsigned long) current->thread_info); -+ unprotect_stack((unsigned long) current_thread); - } - - void *get_current(void) -@@ -157,6 +155,10 @@ void *get_current(void) - return(current); - } - -+void prepare_to_copy(struct task_struct *tsk) -+{ -+} -+ - int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct * p, - struct pt_regs *regs) -@@ -190,7 +192,7 @@ int current_pid(void) - - void default_idle(void) - { -- idle_timer(); -+ uml_idle_timer(); - - atomic_inc(&init_mm.mm_count); - current->mm = &init_mm; -@@ -367,10 +369,15 @@ int clear_user_proc(void *buf, int size) - return(clear_user(buf, size)); - } - -+int strlen_user_proc(char *str) -+{ -+ return(strlen_user(str)); -+} -+ - int smp_sigio_handler(void) - { - #ifdef CONFIG_SMP -- int cpu = current->thread_info->cpu; -+ int cpu = current_thread->cpu; - IPI_handler(cpu); - if(cpu != 0) - return(1); -@@ -385,7 +392,7 @@ int um_in_interrupt(void) - - int cpu(void) - { -- return(current->thread_info->cpu); -+ return(current_thread->cpu); - } - - /* -diff -puN arch/um/kernel/ptrace.c~Main-uml-patch-no-skas arch/um/kernel/ptrace.c ---- uml-linux-2.6.7/arch/um/kernel/ptrace.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.536315952 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/ptrace.c 2004-06-29 21:02:55.731286312 +0200 -@@ -24,11 +24,6 @@ void ptrace_disable(struct task_struct * - { - } - --extern long do_mmap2(struct task_struct *task, unsigned long addr, -- unsigned long len, unsigned long prot, -- unsigned long flags, unsigned long fd, -- unsigned long pgoff); -- - int sys_ptrace(long request, long pid, long addr, long data) - { - struct task_struct *child; -@@ -302,8 +297,17 @@ int sys_ptrace(long request, long pid, l - return ret; - } - --void syscall_trace(void) -+void syscall_trace(union uml_pt_regs *regs, int entryexit) - { -+ if (unlikely(current->audit_context)) { -+ if (!entryexit) -+ audit_syscall_entry(current, regs->orig_eax, -+ regs->ebx, regs->ecx, -+ regs->edx, regs->esi); -+ else -+ audit_syscall_exit(current, regs->eax); -+ } -+ - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - if (!(current->ptrace & PT_PTRACED)) -@@ -311,11 +315,8 @@ void syscall_trace(void) - - /* the 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ -- current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) -- ? 0x80 : 0); -- current->state = TASK_STOPPED; -- notify_parent(current, SIGCHLD); -- schedule(); -+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) -+ ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do -diff -puN arch/um/kernel/reboot.c~Main-uml-patch-no-skas arch/um/kernel/reboot.c ---- uml-linux-2.6.7/arch/um/kernel/reboot.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.537315800 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/reboot.c 2004-06-29 21:02:55.732286160 +0200 -@@ -15,6 +15,7 @@ - #ifdef CONFIG_SMP - static void kill_idlers(int me) - { -+#ifdef CONFIG_MODE_TT - struct task_struct *p; - int i; - -@@ -23,6 +24,7 @@ static void kill_idlers(int me) - if((p != NULL) && (p->thread.mode.tt.extern_pid != me)) - os_kill_process(p->thread.mode.tt.extern_pid, 0); - } -+#endif - } - #endif - -diff -puN arch/um/kernel/sigio_kern.c~Main-uml-patch-no-skas arch/um/kernel/sigio_kern.c ---- uml-linux-2.6.7/arch/um/kernel/sigio_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.539315496 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/sigio_kern.c 2004-06-29 21:02:55.732286160 +0200 -@@ -6,18 +6,21 @@ - #include "linux/kernel.h" - #include "linux/list.h" - #include "linux/slab.h" --#include "asm/irq.h" -+#include "linux/signal.h" -+#include "linux/interrupt.h" - #include "init.h" - #include "sigio.h" - #include "irq_user.h" -+#include "irq_kern.h" - - /* Protected by sigio_lock() called from write_sigio_workaround */ - static int sigio_irq_fd = -1; - --void sigio_interrupt(int irq, void *data, struct pt_regs *unused) -+irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused) - { - read_sigio_fd(sigio_irq_fd); - reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); -+ return(IRQ_HANDLED); - } - - int write_sigio_irq(int fd) -diff -puN arch/um/kernel/sigio_user.c~Main-uml-patch-no-skas arch/um/kernel/sigio_user.c ---- uml-linux-2.6.7/arch/um/kernel/sigio_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.540315344 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/sigio_user.c 2004-06-29 21:02:55.733286008 +0200 -@@ -7,7 +7,6 @@ - #include <stdlib.h> - #include <termios.h> - #include <pty.h> --#include <fcntl.h> - #include <signal.h> - #include <errno.h> - #include <string.h> -@@ -26,7 +25,7 @@ int pty_output_sigio = 0; - int pty_close_sigio = 0; - - /* Used as a flag during SIGIO testing early in boot */ --static int got_sigio = 0; -+static volatile int got_sigio = 0; - - void __init handler(int sig) - { -@@ -45,7 +44,7 @@ static void openpty_cb(void *arg) - - info->err = 0; - if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) -- info->err = errno; -+ info->err = -errno; - } - - void __init check_one_sigio(void (*proc)(int, int)) -@@ -53,11 +52,11 @@ void __init check_one_sigio(void (*proc) - struct sigaction old, new; - struct termios tt; - struct openpty_arg pty = { .master = -1, .slave = -1 }; -- int master, slave, flags; -+ int master, slave, err; - - initial_thread_cb(openpty_cb, &pty); - if(pty.err){ -- printk("openpty failed, errno = %d\n", pty.err); -+ printk("openpty failed, errno = %d\n", -pty.err); - return; - } - -@@ -69,23 +68,16 @@ void __init check_one_sigio(void (*proc) - return; - } - -+ /* XXX These can fail with EINTR */ - if(tcgetattr(master, &tt) < 0) - panic("check_sigio : tcgetattr failed, errno = %d\n", errno); - cfmakeraw(&tt); - if(tcsetattr(master, TCSADRAIN, &tt) < 0) - panic("check_sigio : tcsetattr failed, errno = %d\n", errno); - -- if((flags = fcntl(master, F_GETFL)) < 0) -- panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno); -- -- if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || -- (fcntl(master, F_SETOWN, os_getpid()) < 0)) -- panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, " -- "errno = %d\n", errno); -- -- if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) -- panic("check_sigio : fcntl F_SETFL failed, errno = %d\n", -- errno); -+ err = os_sigio_async(master, slave); -+ if(err < 0) -+ panic("tty_fds : sigio_async failed, err = %d\n", -err); - - if(sigaction(SIGIO, NULL, &old) < 0) - panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); -@@ -97,8 +89,8 @@ void __init check_one_sigio(void (*proc) - got_sigio = 0; - (*proc)(master, slave); - -- close(master); -- close(slave); -+ os_close_file(master); -+ os_close_file(slave); - - if(sigaction(SIGIO, &old, NULL) < 0) - panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); -@@ -112,25 +104,25 @@ static void tty_output(int master, int s - printk("Checking that host ptys support output SIGIO..."); - - memset(buf, 0, sizeof(buf)); -- while(write(master, buf, sizeof(buf)) > 0) ; -+ -+ while(os_write_file(master, buf, sizeof(buf)) > 0) ; - if(errno != EAGAIN) - panic("check_sigio : write failed, errno = %d\n", errno); -- -- while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; -+ while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; - - if(got_sigio){ - printk("Yes\n"); - pty_output_sigio = 1; - } -- else if(errno == EAGAIN) printk("No, enabling workaround\n"); -- else panic("check_sigio : read failed, errno = %d\n", errno); -+ else if(n == -EAGAIN) printk("No, enabling workaround\n"); -+ else panic("check_sigio : read failed, err = %d\n", n); - } - - static void tty_close(int master, int slave) - { - printk("Checking that host ptys support SIGIO on close..."); - -- close(slave); -+ os_close_file(slave); - if(got_sigio){ - printk("Yes\n"); - pty_close_sigio = 1; -@@ -140,7 +132,8 @@ static void tty_close(int master, int sl - - void __init check_sigio(void) - { -- if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){ -+ if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && -+ (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ - printk("No pseudo-terminals available - skipping pty SIGIO " - "check\n"); - return; -@@ -201,11 +194,10 @@ static int write_sigio_thread(void *unus - p = &fds->poll[i]; - if(p->revents == 0) continue; - if(p->fd == sigio_private[1]){ -- n = read(sigio_private[1], &c, sizeof(c)); -+ n = os_read_file(sigio_private[1], &c, sizeof(c)); - if(n != sizeof(c)) - printk("write_sigio_thread : " -- "read failed, errno = %d\n", -- errno); -+ "read failed, err = %d\n", -n); - tmp = current_poll; - current_poll = next_poll; - next_poll = tmp; -@@ -218,10 +210,10 @@ static int write_sigio_thread(void *unus - (fds->used - i) * sizeof(*fds->poll)); - } - -- n = write(respond_fd, &c, sizeof(c)); -+ n = os_write_file(respond_fd, &c, sizeof(c)); - if(n != sizeof(c)) - printk("write_sigio_thread : write failed, " -- "errno = %d\n", errno); -+ "err = %d\n", -n); - } - } - } -@@ -252,15 +244,15 @@ static void update_thread(void) - char c; - - flags = set_signals(0); -- n = write(sigio_private[0], &c, sizeof(c)); -+ n = os_write_file(sigio_private[0], &c, sizeof(c)); - if(n != sizeof(c)){ -- printk("update_thread : write failed, errno = %d\n", errno); -+ printk("update_thread : write failed, err = %d\n", -n); - goto fail; - } - -- n = read(sigio_private[0], &c, sizeof(c)); -+ n = os_read_file(sigio_private[0], &c, sizeof(c)); - if(n != sizeof(c)){ -- printk("update_thread : read failed, errno = %d\n", errno); -+ printk("update_thread : read failed, err = %d\n", -n); - goto fail; - } - -@@ -271,10 +263,10 @@ static void update_thread(void) - if(write_sigio_pid != -1) - os_kill_process(write_sigio_pid, 1); - write_sigio_pid = -1; -- close(sigio_private[0]); -- close(sigio_private[1]); -- close(write_sigio_fds[0]); -- close(write_sigio_fds[1]); -+ os_close_file(sigio_private[0]); -+ os_close_file(sigio_private[1]); -+ os_close_file(write_sigio_fds[0]); -+ os_close_file(write_sigio_fds[1]); - sigio_unlock(); - set_signals(flags); - } -@@ -369,15 +361,15 @@ void write_sigio_workaround(void) - goto out; - - err = os_pipe(write_sigio_fds, 1, 1); -- if(err){ -+ if(err < 0){ - printk("write_sigio_workaround - os_pipe 1 failed, " -- "errno = %d\n", -err); -+ "err = %d\n", -err); - goto out; - } - err = os_pipe(sigio_private, 1, 1); -- if(err){ -+ if(err < 0){ - printk("write_sigio_workaround - os_pipe 2 failed, " -- "errno = %d\n", -err); -+ "err = %d\n", -err); - goto out_close1; - } - if(setup_initial_poll(sigio_private[1])) -@@ -399,11 +391,11 @@ void write_sigio_workaround(void) - os_kill_process(write_sigio_pid, 1); - write_sigio_pid = -1; - out_close2: -- close(sigio_private[0]); -- close(sigio_private[1]); -+ os_close_file(sigio_private[0]); -+ os_close_file(sigio_private[1]); - out_close1: -- close(write_sigio_fds[0]); -- close(write_sigio_fds[1]); -+ os_close_file(write_sigio_fds[0]); -+ os_close_file(write_sigio_fds[1]); - sigio_unlock(); - } - -@@ -412,10 +404,16 @@ int read_sigio_fd(int fd) - int n; - char c; - -- n = read(fd, &c, sizeof(c)); -+ n = os_read_file(fd, &c, sizeof(c)); - if(n != sizeof(c)){ -- printk("read_sigio_fd - read failed, errno = %d\n", errno); -- return(-errno); -+ if(n < 0) { -+ printk("read_sigio_fd - read failed, err = %d\n", -n); -+ return(n); -+ } -+ else { -+ printk("read_sigio_fd - short read, bytes = %d\n", n); -+ return(-EIO); -+ } - } - return(n); - } -diff -puN arch/um/kernel/signal_kern.c~Main-uml-patch-no-skas arch/um/kernel/signal_kern.c ---- uml-linux-2.6.7/arch/um/kernel/signal_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.541315192 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/signal_kern.c 2004-06-29 21:02:55.733286008 +0200 -@@ -36,7 +36,7 @@ static void force_segv(int sig) - if(sig == SIGSEGV){ - struct k_sigaction *ka; - -- ka = ¤t->sig->action[SIGSEGV - 1]; -+ ka = ¤t->sighand->action[SIGSEGV - 1]; - ka->sa.sa_handler = SIG_DFL; - } - force_sig(SIGSEGV, current); -@@ -60,10 +60,10 @@ static int handle_signal(struct pt_regs - int err, ret; - - ret = 0; -+ /* Always make any pending restarted system calls return -EINTR */ -+ current_thread_info()->restart_block.fn = do_no_restart_syscall; - switch(error){ - case -ERESTART_RESTARTBLOCK: -- current_thread_info()->restart_block.fn = -- do_no_restart_syscall; - case -ERESTARTNOHAND: - ret = -EINTR; - break; -@@ -142,7 +142,7 @@ static int kern_do_signal(struct pt_regs - return(0); - - /* Whee! Actually deliver the signal. */ -- ka = ¤t->sig->action[sig -1 ]; -+ ka = ¤t->sighand->action[sig -1 ]; - err = handle_signal(regs, sig, ka, &info, oldset, error); - if(!err) return(1); - -@@ -201,7 +201,7 @@ int sys_sigsuspend(int history0, int his - } - } - --int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize) -+int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize) - { - sigset_t saveset, newset; - -@@ -227,20 +227,59 @@ int sys_rt_sigsuspend(sigset_t *unewset, - } - } - -+int sys_sigaction(int sig, const struct old_sigaction __user *act, -+ struct old_sigaction __user *oact) -+{ -+ struct k_sigaction new_ka, old_ka; -+ int ret; -+ -+ if (act) { -+ old_sigset_t mask; -+ if (verify_area(VERIFY_READ, act, sizeof(*act)) || -+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) || -+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) -+ return -EFAULT; -+ __get_user(new_ka.sa.sa_flags, &act->sa_flags); -+ __get_user(mask, &act->sa_mask); -+ siginitset(&new_ka.sa.sa_mask, mask); -+ } -+ -+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); -+ -+ if (!ret && oact) { -+ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || -+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || -+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) -+ return -EFAULT; -+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags); -+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); -+ } -+ -+ return ret; -+} -+ -+int sys_sigaltstack(const stack_t *uss, stack_t *uoss) -+{ -+ return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs))); -+} -+ -+extern int userspace_pid[]; -+ - static int copy_sc_from_user(struct pt_regs *to, void *from, - struct arch_frame_data *arch) - { - int ret; - - ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch), -- copy_sc_from_user_skas(&to->regs, from)); -+ copy_sc_from_user_skas(userspace_pid[0], -+ &to->regs, from)); - return(ret); - } - - int sys_sigreturn(struct pt_regs regs) - { -- void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs)); -- void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs)); -+ void __user *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs)); -+ void __user *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs)); - int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); - - spin_lock_irq(¤t->sighand->siglock); -@@ -257,8 +296,8 @@ int sys_sigreturn(struct pt_regs regs) - - int sys_rt_sigreturn(struct pt_regs regs) - { -- struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs)); -- void *fp; -+ unsigned long sp = PT_REGS_SP(¤t->thread.regs); -+ struct ucontext __user *uc = sp_to_uc(sp); - int sig_size = _NSIG_WORDS * sizeof(unsigned long); - - spin_lock_irq(¤t->sighand->siglock); -@@ -266,7 +305,6 @@ int sys_rt_sigreturn(struct pt_regs regs - sigdelsetmask(¤t->blocked, ~_BLOCKABLE); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); -- fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext)); - copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, - &signal_frame_si.common.arch); - return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); -diff -puN arch/um/kernel/skas/include/mode.h~Main-uml-patch-no-skas arch/um/kernel/skas/include/mode.h ---- uml-linux-2.6.7/arch/um/kernel/skas/include/mode.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.542315040 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/mode.h 2004-06-29 21:02:55.733286008 +0200 -@@ -12,14 +12,16 @@ extern unsigned long exec_fpx_regs[]; - extern int have_fpx_regs; - - extern void user_time_init_skas(void); --extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr); --extern int copy_sc_to_user_skas(void *to_ptr, void *fp, -+extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, -+ void *from_ptr); -+extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, - union uml_pt_regs *regs, - unsigned long fault_addr, int fault_type); - extern void sig_handler_common_skas(int sig, void *sc_ptr); - extern void halt_skas(void); - extern void reboot_skas(void); - extern void kill_off_processes_skas(void); -+extern int is_skas_winch(int pid, int fd, void *data); - - #endif - -diff -puN arch/um/kernel/skas/include/skas.h~Main-uml-patch-no-skas arch/um/kernel/skas/include/skas.h ---- uml-linux-2.6.7/arch/um/kernel/skas/include/skas.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.543314888 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/skas.h 2004-06-29 21:02:55.733286008 +0200 -@@ -8,7 +8,7 @@ - - #include "sysdep/ptrace.h" - --extern int userspace_pid; -+extern int userspace_pid[]; - - extern void switch_threads(void *me, void *next); - extern void thread_wait(void *sw, void *fb); -@@ -32,7 +32,7 @@ extern int singlestepping_skas(void); - extern int new_mm(int from); - extern void save_registers(union uml_pt_regs *regs); - extern void restore_registers(union uml_pt_regs *regs); --extern void start_userspace(void); -+extern void start_userspace(int cpu); - extern void init_registers(int pid); - - #endif -diff -puN arch/um/kernel/skas/include/uaccess.h~Main-uml-patch-no-skas arch/um/kernel/skas/include/uaccess.h ---- uml-linux-2.6.7/arch/um/kernel/skas/include/uaccess.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.555313064 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/uaccess.h 2004-06-29 21:02:55.734285856 +0200 -@@ -6,20 +6,12 @@ - #ifndef __SKAS_UACCESS_H - #define __SKAS_UACCESS_H - --#include "linux/string.h" --#include "linux/sched.h" --#include "linux/err.h" --#include "asm/processor.h" --#include "asm/pgtable.h" - #include "asm/errno.h" --#include "asm/current.h" --#include "asm/a.out.h" --#include "kern_util.h" - - #define access_ok_skas(type, addr, size) \ - ((segment_eq(get_fs(), KERNEL_DS)) || \ - (((unsigned long) (addr) < TASK_SIZE) && \ -- ((unsigned long) (addr) + (size) < TASK_SIZE))) -+ ((unsigned long) (addr) + (size) <= TASK_SIZE))) - - static inline int verify_area_skas(int type, const void * addr, - unsigned long size) -@@ -27,197 +19,12 @@ static inline int verify_area_skas(int t - return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); - } - --static inline unsigned long maybe_map(unsigned long virt, int is_write) --{ -- pte_t pte; -- -- void *phys = um_virt_to_phys(current, virt, &pte); -- int dummy_code; -- -- if(IS_ERR(phys) || (is_write && !pte_write(pte))){ -- if(handle_page_fault(virt, 0, is_write, 0, &dummy_code)) -- return(0); -- phys = um_virt_to_phys(current, virt, NULL); -- } -- return((unsigned long) __va((unsigned long) phys)); --} -- --static inline int buffer_op(unsigned long addr, int len, -- int (*op)(unsigned long addr, int len, void *arg), -- void *arg) --{ -- int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len); -- int remain = len, n; -- -- n = (*op)(addr, size, arg); -- if(n != 0) -- return(n < 0 ? remain : 0); -- -- addr += size; -- remain -= size; -- if(remain == 0) -- return(0); -- -- while(addr < ((addr + remain) & PAGE_MASK)){ -- n = (*op)(addr, PAGE_SIZE, arg); -- if(n != 0) -- return(n < 0 ? remain : 0); -- -- addr += PAGE_SIZE; -- remain -= PAGE_SIZE; -- } -- if(remain == 0) -- return(0); -- -- n = (*op)(addr, remain, arg); -- if(n != 0) -- return(n < 0 ? remain : 0); -- return(0); --} -- --static inline int copy_chunk_from_user(unsigned long from, int len, void *arg) --{ -- unsigned long *to_ptr = arg, to = *to_ptr; -- -- from = maybe_map(from, 0); -- if(from == 0) -- return(-1); -- -- memcpy((void *) to, (void *) from, len); -- *to_ptr += len; -- return(0); --} -- --static inline int copy_from_user_skas(void *to, const void *from, int n) --{ -- if(segment_eq(get_fs(), KERNEL_DS)){ -- memcpy(to, from, n); -- return(0); -- } -- -- return(access_ok_skas(VERIFY_READ, from, n) ? -- buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) : -- n); --} -- --static inline int copy_chunk_to_user(unsigned long to, int len, void *arg) --{ -- unsigned long *from_ptr = arg, from = *from_ptr; -- -- to = maybe_map(to, 1); -- if(to == 0) -- return(-1); -- -- memcpy((void *) to, (void *) from, len); -- *from_ptr += len; -- return(0); --} -- --static inline int copy_to_user_skas(void *to, const void *from, int n) --{ -- if(segment_eq(get_fs(), KERNEL_DS)){ -- memcpy(to, from, n); -- return(0); -- } -- -- return(access_ok_skas(VERIFY_WRITE, to, n) ? -- buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) : -- n); --} -- --static inline int strncpy_chunk_from_user(unsigned long from, int len, -- void *arg) --{ -- char **to_ptr = arg, *to = *to_ptr; -- int n; -- -- from = maybe_map(from, 0); -- if(from == 0) -- return(-1); -- -- strncpy(to, (void *) from, len); -- n = strnlen(to, len); -- *to_ptr += n; -- -- if(n < len) -- return(1); -- return(0); --} -- --static inline int strncpy_from_user_skas(char *dst, const char *src, int count) --{ -- int n; -- char *ptr = dst; -- -- if(segment_eq(get_fs(), KERNEL_DS)){ -- strncpy(dst, src, count); -- return(strnlen(dst, count)); -- } -- -- if(!access_ok_skas(VERIFY_READ, src, 1)) -- return(-EFAULT); -- -- n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user, -- &ptr); -- if(n != 0) -- return(-EFAULT); -- return(strnlen(dst, count)); --} -- --static inline int clear_chunk(unsigned long addr, int len, void *unused) --{ -- addr = maybe_map(addr, 1); -- if(addr == 0) -- return(-1); -- -- memset((void *) addr, 0, len); -- return(0); --} -- --static inline int __clear_user_skas(void *mem, int len) --{ -- return(buffer_op((unsigned long) mem, len, clear_chunk, NULL)); --} -- --static inline int clear_user_skas(void *mem, int len) --{ -- if(segment_eq(get_fs(), KERNEL_DS)){ -- memset(mem, 0, len); -- return(0); -- } -- -- return(access_ok_skas(VERIFY_WRITE, mem, len) ? -- buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len); --} -- --static inline int strnlen_chunk(unsigned long str, int len, void *arg) --{ -- int *len_ptr = arg, n; -- -- str = maybe_map(str, 0); -- if(str == 0) -- return(-1); -- -- n = strnlen((void *) str, len); -- *len_ptr += n; -- -- if(n < len) -- return(1); -- return(0); --} -- --static inline int strnlen_user_skas(const void *str, int len) --{ -- int count = 0, n; -- -- if(segment_eq(get_fs(), KERNEL_DS)) -- return(strnlen(str, len) + 1); -- -- n = buffer_op((unsigned long) str, len, strnlen_chunk, &count); -- if(n == 0) -- return(count + 1); -- return(-EFAULT); --} -+extern int copy_from_user_skas(void *to, const void *from, int n); -+extern int copy_to_user_skas(void *to, const void *from, int n); -+extern int strncpy_from_user_skas(char *dst, const char *src, int count); -+extern int __clear_user_skas(void *mem, int len); -+extern int clear_user_skas(void *mem, int len); -+extern int strnlen_user_skas(const void *str, int len); - - #endif - -diff -puN arch/um/kernel/skas/Makefile~Main-uml-patch-no-skas arch/um/kernel/skas/Makefile ---- uml-linux-2.6.7/arch/um/kernel/skas/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.557312760 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/Makefile 2004-06-29 21:02:55.734285856 +0200 -@@ -5,20 +5,24 @@ - - obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \ - process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \ -- sys-$(SUBARCH)/ -+ uaccess.o sys-$(SUBARCH)/ -+ -+host-progs := util/mk_ptregs -+clean-files := include/skas_ptregs.h - - USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o - USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) - --include/skas_ptregs.h : util/mk_ptregs -- util/mk_ptregs > $@ -- --util/mk_ptregs : -- $(MAKE) -C util -+$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs -+ @echo -n ' Generating $@' -+ @$< > $@.tmp -+ @if [ -r $@ ] && cmp -s $@ $@.tmp; then \ -+ echo ' (unchanged)'; \ -+ rm -f $@.tmp; \ -+ else \ -+ echo ' (updated)'; \ -+ mv -f $@.tmp $@; \ -+ fi - - $(USER_OBJS) : %.o: %.c - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -- --clean : -- $(MAKE) -C util clean -- $(RM) -f include/skas_ptregs.h -diff -puN arch/um/kernel/skas/mem_user.c~Main-uml-patch-no-skas arch/um/kernel/skas/mem_user.c ---- uml-linux-2.6.7/arch/um/kernel/skas/mem_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.558312608 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/mem_user.c 2004-06-29 21:02:55.734285856 +0200 -@@ -7,6 +7,7 @@ - #include <sys/mman.h> - #include <sys/ptrace.h> - #include "mem_user.h" -+#include "mem.h" - #include "user.h" - #include "os.h" - #include "proc_mm.h" -@@ -15,12 +16,12 @@ void map(int fd, unsigned long virt, uns - int r, int w, int x) - { - struct proc_mm_op map; -- struct mem_region *region; -- int prot, n; -+ __u64 offset; -+ int prot, n, phys_fd; - - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); -- region = phys_region(phys); -+ phys_fd = phys_mapping(phys, &offset); - - map = ((struct proc_mm_op) { .op = MM_MMAP, - .u = -@@ -30,12 +31,12 @@ void map(int fd, unsigned long virt, uns - .prot = prot, - .flags = MAP_SHARED | - MAP_FIXED, -- .fd = region->fd, -- .offset = phys_offset(phys) -+ .fd = phys_fd, -+ .offset = offset - } } } ); - n = os_write_file(fd, &map, sizeof(map)); - if(n != sizeof(map)) -- printk("map : /proc/mm map failed, errno = %d\n", errno); -+ printk("map : /proc/mm map failed, err = %d\n", -n); - } - - int unmap(int fd, void *addr, int len) -@@ -49,8 +50,13 @@ int unmap(int fd, void *addr, int len) - { .addr = (unsigned long) addr, - .len = len } } } ); - n = os_write_file(fd, &unmap, sizeof(unmap)); -- if((n != 0) && (n != sizeof(unmap))) -- return(-errno); -+ if(n != sizeof(unmap)) { -+ if(n < 0) -+ return(n); -+ else if(n > 0) -+ return(-EIO); -+ } -+ - return(0); - } - -@@ -71,11 +77,15 @@ int protect(int fd, unsigned long addr, - .prot = prot } } } ); - - n = os_write_file(fd, &protect, sizeof(protect)); -- if((n != 0) && (n != sizeof(protect))){ -+ if(n != sizeof(protect)) { -+ if(n == 0) return(0); -+ - if(must_succeed) -- panic("protect failed, errno = %d", errno); -- return(-errno); -+ panic("protect failed, err = %d", -n); -+ -+ return(-EIO); - } -+ - return(0); - } - -diff -puN arch/um/kernel/skas/mmu.c~Main-uml-patch-no-skas arch/um/kernel/skas/mmu.c ---- uml-linux-2.6.7/arch/um/kernel/skas/mmu.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.559312456 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/mmu.c 2004-06-29 21:02:55.735285704 +0200 -@@ -22,9 +22,11 @@ int init_new_context_skas(struct task_st - else from = -1; - - mm->context.skas.mm_fd = new_mm(from); -- if(mm->context.skas.mm_fd < 0) -- panic("init_new_context_skas - new_mm failed, errno = %d\n", -- mm->context.skas.mm_fd); -+ if(mm->context.skas.mm_fd < 0){ -+ printk("init_new_context_skas - new_mm failed, errno = %d\n", -+ mm->context.skas.mm_fd); -+ return(mm->context.skas.mm_fd); -+ } - - return(0); - } -diff -puN arch/um/kernel/skas/process.c~Main-uml-patch-no-skas arch/um/kernel/skas/process.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.560312304 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c 2004-06-29 21:02:55.735285704 +0200 -@@ -4,6 +4,7 @@ - */ - - #include <stdlib.h> -+#include <unistd.h> - #include <errno.h> - #include <signal.h> - #include <setjmp.h> -@@ -24,6 +25,19 @@ - #include "os.h" - #include "proc_mm.h" - #include "skas_ptrace.h" -+#include "chan_user.h" -+#include "signal_user.h" -+ -+int is_skas_winch(int pid, int fd, void *data) -+{ -+ if(pid != getpid()) -+ return(0); -+ -+ register_winch_irq(-1, fd, -1, data); -+ return(1); -+} -+ -+/* These are set once at boot time and not changed thereafter */ - - unsigned long exec_regs[FRAME_SIZE]; - unsigned long exec_fp_regs[HOST_FP_SIZE]; -@@ -48,11 +62,11 @@ static void handle_trap(int pid, union u - int err, syscall_nr, status; - - syscall_nr = PT_SYSCALL_NR(regs->skas.regs); -+ UPT_SYSCALL_NR(regs) = syscall_nr; - if(syscall_nr < 1){ - relay_signal(SIGTRAP, regs); - return; - } -- UPT_SYSCALL_NR(regs) = syscall_nr; - - err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); - if(err < 0) -@@ -72,8 +86,6 @@ static void handle_trap(int pid, union u - handle_syscall(regs); - } - --int userspace_pid; -- - static int userspace_tramp(void *arg) - { - init_new_thread_signals(0); -@@ -83,7 +95,11 @@ static int userspace_tramp(void *arg) - return(0); - } - --void start_userspace(void) -+/* Each element set once, and only accessed by a single processor anyway */ -+#define NR_CPUS 1 -+int userspace_pid[NR_CPUS]; -+ -+void start_userspace(int cpu) - { - void *stack; - unsigned long sp; -@@ -114,21 +130,21 @@ void start_userspace(void) - if(munmap(stack, PAGE_SIZE) < 0) - panic("start_userspace : munmap failed, errno = %d\n", errno); - -- userspace_pid = pid; -+ userspace_pid[cpu] = pid; - } - - void userspace(union uml_pt_regs *regs) - { -- int err, status, op; -+ int err, status, op, pid = userspace_pid[0]; - - restore_registers(regs); - -- err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0); -+ err = ptrace(PTRACE_SYSCALL, pid, 0, 0); - if(err) - panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", - errno); - while(1){ -- err = waitpid(userspace_pid, &status, WUNTRACED); -+ err = waitpid(pid, &status, WUNTRACED); - if(err < 0) - panic("userspace - waitpid failed, errno = %d\n", - errno); -@@ -139,16 +155,17 @@ void userspace(union uml_pt_regs *regs) - if(WIFSTOPPED(status)){ - switch(WSTOPSIG(status)){ - case SIGSEGV: -- handle_segv(userspace_pid); -+ handle_segv(pid); - break; - case SIGTRAP: -- handle_trap(userspace_pid, regs); -+ handle_trap(pid, regs); - break; - case SIGIO: - case SIGVTALRM: - case SIGILL: - case SIGBUS: - case SIGFPE: -+ case SIGWINCH: - user_signal(WSTOPSIG(status), regs); - break; - default: -@@ -162,7 +179,7 @@ void userspace(union uml_pt_regs *regs) - - op = singlestepping_skas() ? PTRACE_SINGLESTEP : - PTRACE_SYSCALL; -- err = ptrace(op, userspace_pid, 0, 0); -+ err = ptrace(op, pid, 0, 0); - if(err) - panic("userspace - PTRACE_SYSCALL failed, " - "errno = %d\n", errno); -@@ -172,13 +189,25 @@ void userspace(union uml_pt_regs *regs) - void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, - void (*handler)(int)) - { -+ unsigned long flags; - jmp_buf switch_buf, fork_buf; - - *switch_buf_ptr = &switch_buf; - *fork_buf_ptr = &fork_buf; - -- if(setjmp(fork_buf) == 0) -+ /* Somewhat subtle - siglongjmp restores the signal mask before doing -+ * the longjmp. This means that when jumping from one stack to another -+ * when the target stack has interrupts enabled, an interrupt may occur -+ * on the source stack. This is bad when starting up a process because -+ * it's not supposed to get timer ticks until it has been scheduled. -+ * So, we disable interrupts around the sigsetjmp to ensure that -+ * they can't happen until we get back here where they are safe. -+ */ -+ flags = get_signals(); -+ block_signals(); -+ if(sigsetjmp(fork_buf, 1) == 0) - new_thread_proc(stack, handler); -+ set_signals(flags); - - remove_sigstack(); - } -@@ -189,16 +218,16 @@ void thread_wait(void *sw, void *fb) - - *switch_buf = &buf; - fork_buf = fb; -- if(setjmp(buf) == 0) -- longjmp(*fork_buf, 1); -+ if(sigsetjmp(buf, 1) == 0) -+ siglongjmp(*fork_buf, 1); - } - --static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs, -- unsigned long *fp_regs) -+static int move_registers(int pid, int int_op, int fp_op, -+ union uml_pt_regs *regs, unsigned long *fp_regs) - { -- if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0) -+ if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) - return(-errno); -- if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0) -+ if(ptrace(fp_op, pid, 0, fp_regs) < 0) - return(-errno); - return(0); - } -@@ -217,10 +246,11 @@ void save_registers(union uml_pt_regs *r - fp_regs = regs->skas.fp; - } - -- err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs); -+ err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, -+ fp_regs); - if(err) - panic("save_registers - saving registers failed, errno = %d\n", -- err); -+ -err); - } - - void restore_registers(union uml_pt_regs *regs) -@@ -237,10 +267,11 @@ void restore_registers(union uml_pt_regs - fp_regs = regs->skas.fp; - } - -- err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs); -+ err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, -+ fp_regs); - if(err) - panic("restore_registers - saving registers failed, " -- "errno = %d\n", err); -+ "errno = %d\n", -err); - } - - void switch_threads(void *me, void *next) -@@ -248,8 +279,8 @@ void switch_threads(void *me, void *next - jmp_buf my_buf, **me_ptr = me, *next_buf = next; - - *me_ptr = &my_buf; -- if(setjmp(my_buf) == 0) -- longjmp(*next_buf, 1); -+ if(sigsetjmp(my_buf, 1) == 0) -+ siglongjmp(*next_buf, 1); - } - - static jmp_buf initial_jmpbuf; -@@ -265,14 +296,14 @@ int start_idle_thread(void *stack, void - int n; - - *fork_buf_ptr = &initial_jmpbuf; -- n = setjmp(initial_jmpbuf); -+ n = sigsetjmp(initial_jmpbuf, 1); - if(n == 0) - new_thread_proc((void *) stack, new_thread_handler); - else if(n == 1) - remove_sigstack(); - else if(n == 2){ - (*cb_proc)(cb_arg); -- longjmp(*cb_back, 1); -+ siglongjmp(*cb_back, 1); - } - else if(n == 3){ - kmalloc_ok = 0; -@@ -282,7 +313,7 @@ int start_idle_thread(void *stack, void - kmalloc_ok = 0; - return(1); - } -- longjmp(**switch_buf, 1); -+ siglongjmp(**switch_buf, 1); - } - - void remove_sigstack(void) -@@ -304,8 +335,8 @@ void initial_thread_cb_skas(void (*proc) - cb_back = &here; - - block_signals(); -- if(setjmp(here) == 0) -- longjmp(initial_jmpbuf, 2); -+ if(sigsetjmp(here, 1) == 0) -+ siglongjmp(initial_jmpbuf, 2); - unblock_signals(); - - cb_proc = NULL; -@@ -316,22 +347,23 @@ void initial_thread_cb_skas(void (*proc) - void halt_skas(void) - { - block_signals(); -- longjmp(initial_jmpbuf, 3); -+ siglongjmp(initial_jmpbuf, 3); - } - - void reboot_skas(void) - { - block_signals(); -- longjmp(initial_jmpbuf, 4); -+ siglongjmp(initial_jmpbuf, 4); - } - - int new_mm(int from) - { - struct proc_mm_op copy; -- int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0); -+ int n, fd = os_open_file("/proc/mm", -+ of_cloexec(of_write(OPENFLAGS())), 0); - - if(fd < 0) -- return(-errno); -+ return(fd); - - if(from != -1){ - copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, -@@ -340,8 +372,9 @@ int new_mm(int from) - n = os_write_file(fd, ©, sizeof(copy)); - if(n != sizeof(copy)) - printk("new_mm : /proc/mm copy_segments failed, " -- "errno = %d\n", errno); -+ "err = %d\n", -n); - } -+ - return(fd); - } - -@@ -349,7 +382,8 @@ void switch_mm_skas(int mm_fd) - { - int err; - -- err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd); -+#warning need cpu pid in switch_mm_skas -+ err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd); - if(err) - panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n", - errno); -@@ -357,7 +391,8 @@ void switch_mm_skas(int mm_fd) - - void kill_off_processes_skas(void) - { -- os_kill_process(userspace_pid, 1); -+#warning need to loop over userspace_pids in kill_off_processes_skas -+ os_kill_process(userspace_pid[0], 1); - } - - void init_registers(int pid) -diff -puN arch/um/kernel/skas/process_kern.c~Main-uml-patch-no-skas arch/um/kernel/skas/process_kern.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.561312152 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c 2004-06-29 21:02:55.736285552 +0200 -@@ -61,11 +61,13 @@ void new_thread_handler(int sig) - thread_wait(¤t->thread.mode.skas.switch_buf, - current->thread.mode.skas.fork_buf); - --#ifdef CONFIG_SMP -- schedule_tail(NULL); --#endif -+ if(current->thread.prev_sched != NULL) -+ schedule_tail(current->thread.prev_sched); - current->thread.prev_sched = NULL; - -+ /* The return value is 1 if the kernel thread execs a process, -+ * 0 if it just exits -+ */ - n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); - if(n == 1) - userspace(¤t->thread.regs.regs); -@@ -93,11 +95,11 @@ void fork_handler(int sig) - current->thread.mode.skas.fork_buf); - - force_flush_all(); --#ifdef CONFIG_SMP -+ if(current->thread.prev_sched == NULL) -+ panic("blech"); -+ - schedule_tail(current->thread.prev_sched); --#endif - current->thread.prev_sched = NULL; -- unblock_signals(); - - userspace(¤t->thread.regs.regs); - } -@@ -136,7 +138,7 @@ int copy_thread_skas(int nr, unsigned lo - - void init_idle_skas(void) - { -- cpu_tasks[current->thread_info->cpu].pid = os_getpid(); -+ cpu_tasks[current_thread->cpu].pid = os_getpid(); - default_idle(); - } - -@@ -160,11 +162,11 @@ static int start_kernel_proc(void *unuse - - int start_uml_skas(void) - { -- start_userspace(); -+ start_userspace(0); - capture_signal_stack(); -+ uml_idle_timer(); - - init_new_thread_signals(1); -- idle_timer(); - - init_task.thread.request.u.thread.proc = start_kernel_proc; - init_task.thread.request.u.thread.arg = NULL; -@@ -175,12 +177,14 @@ int start_uml_skas(void) - - int external_pid_skas(struct task_struct *task) - { -- return(userspace_pid); -+#warning Need to look up userspace_pid by cpu -+ return(userspace_pid[0]); - } - - int thread_pid_skas(struct task_struct *task) - { -- return(userspace_pid); -+#warning Need to look up userspace_pid by cpu -+ return(userspace_pid[0]); - } - - /* -diff -puN arch/um/kernel/skas/syscall_kern.c~Main-uml-patch-no-skas arch/um/kernel/skas/syscall_kern.c ---- uml-linux-2.6.7/arch/um/kernel/skas/syscall_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.562312000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/syscall_kern.c 2004-06-29 21:02:55.736285552 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -diff -puN arch/um/kernel/skas/syscall_user.c~Main-uml-patch-no-skas arch/um/kernel/skas/syscall_user.c ---- uml-linux-2.6.7/arch/um/kernel/skas/syscall_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.563311848 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/syscall_user.c 2004-06-29 21:02:55.736285552 +0200 -@@ -22,7 +22,7 @@ void handle_syscall(union uml_pt_regs *r - - index = record_syscall_start(UPT_SYSCALL_NR(regs)); - -- syscall_trace(); -+ syscall_trace(regs, 1); - result = execute_syscall(regs); - - REGS_SET_SYSCALL_RETURN(regs->skas.regs, result); -@@ -30,7 +30,7 @@ void handle_syscall(union uml_pt_regs *r - (result == -ERESTARTNOINTR)) - do_signal(result); - -- syscall_trace(); -+ syscall_trace(regs, 0); - record_syscall_end(index, result); - } - -diff -puN arch/um/kernel/skas/sys-i386/Makefile~Main-uml-patch-no-skas arch/um/kernel/skas/sys-i386/Makefile ---- uml-linux-2.6.7/arch/um/kernel/skas/sys-i386/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.564311696 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/sys-i386/Makefile 2004-06-29 21:02:55.736285552 +0200 -@@ -10,5 +10,3 @@ USER_OBJS := $(foreach file,$(USER_OBJS) - - $(USER_OBJS) : %.o: %.c - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -- --clean : -diff -puN arch/um/kernel/skas/sys-i386/sigcontext.c~Main-uml-patch-no-skas arch/um/kernel/skas/sys-i386/sigcontext.c ---- uml-linux-2.6.7/arch/um/kernel/skas/sys-i386/sigcontext.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.566311392 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-06-29 21:02:55.737285400 +0200 -@@ -12,10 +12,9 @@ - #include "kern_util.h" - #include "user.h" - #include "sigcontext.h" -+#include "mode.h" - --extern int userspace_pid; -- --int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr) -+int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr) - { - struct sigcontext sc, *from = from_ptr; - unsigned long fpregs[FP_FRAME_SIZE]; -@@ -41,13 +40,12 @@ int copy_sc_from_user_skas(union uml_pt_ - regs->skas.regs[EIP] = sc.eip; - regs->skas.regs[CS] = sc.cs; - regs->skas.regs[EFL] = sc.eflags; -- regs->skas.regs[UESP] = sc.esp_at_signal; - regs->skas.regs[SS] = sc.ss; - regs->skas.fault_addr = sc.cr2; - regs->skas.fault_type = FAULT_WRITE(sc.err); - regs->skas.trap_type = sc.trapno; - -- err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs); -+ err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs); - if(err < 0){ - printk("copy_sc_to_user - PTRACE_SETFPREGS failed, " - "errno = %d\n", errno); -@@ -57,8 +55,9 @@ int copy_sc_from_user_skas(union uml_pt_ - return(0); - } - --int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs, -- unsigned long fault_addr, int fault_type) -+int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, -+ union uml_pt_regs *regs, unsigned long fault_addr, -+ int fault_type) - { - struct sigcontext sc, *to = to_ptr; - struct _fpstate *to_fp; -@@ -86,7 +85,7 @@ int copy_sc_to_user_skas(void *to_ptr, v - sc.err = TO_SC_ERR(fault_type); - sc.trapno = regs->skas.trap_type; - -- err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs); -+ err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs); - if(err < 0){ - printk("copy_sc_to_user - PTRACE_GETFPREGS failed, " - "errno = %d\n", errno); -diff -puN arch/um/kernel/skas/trap_user.c~Main-uml-patch-no-skas arch/um/kernel/skas/trap_user.c ---- uml-linux-2.6.7/arch/um/kernel/skas/trap_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.567311240 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/trap_user.c 2004-06-29 21:02:55.737285400 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -35,14 +35,10 @@ void sig_handler_common_skas(int sig, vo - errno = save_errno; - } - --extern int missed_ticks[]; -- - void user_signal(int sig, union uml_pt_regs *regs) - { - struct signal_info *info; - -- if(sig == SIGVTALRM) -- missed_ticks[cpu()]++; - regs->skas.is_user = 1; - regs->skas.fault_addr = 0; - regs->skas.fault_type = 0; -diff -puN /dev/null arch/um/kernel/skas/uaccess.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/uaccess.c 2004-06-29 21:02:55.737285400 +0200 -@@ -0,0 +1,219 @@ -+/* -+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/stddef.h" -+#include "linux/kernel.h" -+#include "linux/string.h" -+#include "linux/fs.h" -+#include "linux/highmem.h" -+#include "asm/page.h" -+#include "asm/pgtable.h" -+#include "asm/uaccess.h" -+#include "kern_util.h" -+ -+extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, -+ pte_t *pte_out); -+ -+static unsigned long maybe_map(unsigned long virt, int is_write) -+{ -+ pte_t pte; -+ int err; -+ -+ void *phys = um_virt_to_phys(current, virt, &pte); -+ int dummy_code; -+ -+ if(IS_ERR(phys) || (is_write && !pte_write(pte))){ -+ err = handle_page_fault(virt, 0, is_write, 0, &dummy_code); -+ if(err) -+ return(0); -+ phys = um_virt_to_phys(current, virt, NULL); -+ } -+ return((unsigned long) phys); -+} -+ -+static int do_op(unsigned long addr, int len, int is_write, -+ int (*op)(unsigned long addr, int len, void *arg), void *arg) -+{ -+ struct page *page; -+ int n; -+ -+ addr = maybe_map(addr, is_write); -+ if(addr == -1) -+ return(-1); -+ -+ page = phys_to_page(addr); -+ addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); -+ n = (*op)(addr, len, arg); -+ kunmap(page); -+ -+ return(n); -+} -+ -+static int buffer_op(unsigned long addr, int len, int is_write, -+ int (*op)(unsigned long addr, int len, void *arg), -+ void *arg) -+{ -+ int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len); -+ int remain = len, n; -+ -+ n = do_op(addr, size, is_write, op, arg); -+ if(n != 0) -+ return(n < 0 ? remain : 0); -+ -+ addr += size; -+ remain -= size; -+ if(remain == 0) -+ return(0); -+ -+ while(addr < ((addr + remain) & PAGE_MASK)){ -+ n = do_op(addr, PAGE_SIZE, is_write, op, arg); -+ if(n != 0) -+ return(n < 0 ? remain : 0); -+ -+ addr += PAGE_SIZE; -+ remain -= PAGE_SIZE; -+ } -+ if(remain == 0) -+ return(0); -+ -+ n = do_op(addr, remain, is_write, op, arg); -+ if(n != 0) -+ return(n < 0 ? remain : 0); -+ return(0); -+} -+ -+static int copy_chunk_from_user(unsigned long from, int len, void *arg) -+{ -+ unsigned long *to_ptr = arg, to = *to_ptr; -+ -+ memcpy((void *) to, (void *) from, len); -+ *to_ptr += len; -+ return(0); -+} -+ -+int copy_from_user_skas(void *to, const void *from, int n) -+{ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ memcpy(to, from, n); -+ return(0); -+ } -+ -+ return(access_ok_skas(VERIFY_READ, from, n) ? -+ buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): -+ n); -+} -+ -+static int copy_chunk_to_user(unsigned long to, int len, void *arg) -+{ -+ unsigned long *from_ptr = arg, from = *from_ptr; -+ -+ memcpy((void *) to, (void *) from, len); -+ *from_ptr += len; -+ return(0); -+} -+ -+int copy_to_user_skas(void *to, const void *from, int n) -+{ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ memcpy(to, from, n); -+ return(0); -+ } -+ -+ return(access_ok_skas(VERIFY_WRITE, to, n) ? -+ buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : -+ n); -+} -+ -+static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) -+{ -+ char **to_ptr = arg, *to = *to_ptr; -+ int n; -+ -+ strncpy(to, (void *) from, len); -+ n = strnlen(to, len); -+ *to_ptr += n; -+ -+ if(n < len) -+ return(1); -+ return(0); -+} -+ -+int strncpy_from_user_skas(char *dst, const char *src, int count) -+{ -+ int n; -+ char *ptr = dst; -+ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ strncpy(dst, src, count); -+ return(strnlen(dst, count)); -+ } -+ -+ if(!access_ok_skas(VERIFY_READ, src, 1)) -+ return(-EFAULT); -+ -+ n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, -+ &ptr); -+ if(n != 0) -+ return(-EFAULT); -+ return(strnlen(dst, count)); -+} -+ -+static int clear_chunk(unsigned long addr, int len, void *unused) -+{ -+ memset((void *) addr, 0, len); -+ return(0); -+} -+ -+int __clear_user_skas(void *mem, int len) -+{ -+ return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL)); -+} -+ -+int clear_user_skas(void *mem, int len) -+{ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ memset(mem, 0, len); -+ return(0); -+ } -+ -+ return(access_ok_skas(VERIFY_WRITE, mem, len) ? -+ buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len); -+} -+ -+static int strnlen_chunk(unsigned long str, int len, void *arg) -+{ -+ int *len_ptr = arg, n; -+ -+ n = strnlen((void *) str, len); -+ *len_ptr += n; -+ -+ if(n < len) -+ return(1); -+ return(0); -+} -+ -+int strnlen_user_skas(const void *str, int len) -+{ -+ int count = 0, n; -+ -+ if(segment_eq(get_fs(), KERNEL_DS)) -+ return(strnlen(str, len) + 1); -+ -+ n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); -+ if(n == 0) -+ return(count + 1); -+ return(-EFAULT); -+} -+ -+/* -+ * 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 -puN arch/um/kernel/skas/util/Makefile~Main-uml-patch-no-skas arch/um/kernel/skas/util/Makefile ---- uml-linux-2.6.7/arch/um/kernel/skas/util/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.568311088 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/util/Makefile 2004-06-29 21:02:55.737285400 +0200 -@@ -1,10 +1,9 @@ - all: mk_ptregs - - mk_ptregs : mk_ptregs.o -- $(CC) -o mk_ptregs mk_ptregs.o -+ $(HOSTCC) -o mk_ptregs mk_ptregs.o - - mk_ptregs.o : mk_ptregs.c -- $(CC) -c $< -+ $(HOSTCC) -c $< - --clean : -- $(RM) -f mk_ptregs *.o *~ -+clean-files := mk_ptregs *.o *~ -diff -puN arch/um/kernel/skas/util/mk_ptregs.c~Main-uml-patch-no-skas arch/um/kernel/skas/util/mk_ptregs.c ---- uml-linux-2.6.7/arch/um/kernel/skas/util/mk_ptregs.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.569310936 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/util/mk_ptregs.c 2004-06-29 21:02:55.738285248 +0200 -@@ -1,3 +1,4 @@ -+#include <stdio.h> - #include <asm/ptrace.h> - #include <asm/user.h> - -diff -puN arch/um/kernel/smp.c~Main-uml-patch-no-skas arch/um/kernel/smp.c ---- uml-linux-2.6.7/arch/um/kernel/smp.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.571310632 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/smp.c 2004-06-29 21:02:55.738285248 +0200 -@@ -1,9 +1,15 @@ - /* -- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - - #include "linux/config.h" -+#include "linux/percpu.h" -+#include "asm/pgalloc.h" -+#include "asm/tlb.h" -+ -+/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */ -+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); - - #ifdef CONFIG_SMP - -@@ -23,7 +29,7 @@ - #include "os.h" - - /* CPU online map, set by smp_boot_cpus */ --unsigned long cpu_online_map = cpumask_of_cpu(0); -+unsigned long cpu_online_map = CPU_MASK_NONE; - - EXPORT_SYMBOL(cpu_online_map); - -@@ -55,7 +61,7 @@ struct task_struct *idle_threads[NR_CPUS - - void smp_send_reschedule(int cpu) - { -- write(cpu_data[cpu].ipi_pipe[1], "R", 1); -+ os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); - num_reschedules_sent++; - } - -@@ -100,35 +106,34 @@ void smp_send_stop(void) - - printk(KERN_INFO "Stopping all CPUs..."); - for(i = 0; i < num_online_cpus(); i++){ -- if(i == current->thread_info->cpu) -+ if(i == current_thread->cpu) - continue; -- write(cpu_data[i].ipi_pipe[1], "S", 1); -+ os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); - } - printk("done\n"); - } - --static cpumask_t smp_commenced_mask; --static cpumask_t smp_callin_map = CPU_MASK_NONE; -+static cpumask_t smp_commenced_mask = CPU_MASK_NONE; -+static cpumask_t cpu_callin_map = CPU_MASK_NONE; - - static int idle_proc(void *cpup) - { - int cpu = (int) cpup, err; - - err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1); -- if(err) -- panic("CPU#%d failed to create IPI pipe, errno = %d", cpu, -- -err); -+ if(err < 0) -+ panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); - - activate_ipi(cpu_data[cpu].ipi_pipe[0], - current->thread.mode.tt.extern_pid); - - wmb(); -- if (cpu_test_and_set(cpu, &smp_callin_map)) { -+ if (cpu_test_and_set(cpu, cpu_callin_map)) { - printk("huh, CPU#%d already present??\n", cpu); - BUG(); - } - -- while (!cpu_isset(cpu, &smp_commenced_mask)) -+ while (!cpu_isset(cpu, smp_commenced_mask)) - cpu_relax(); - - cpu_set(cpu, cpu_online_map); -@@ -143,16 +148,20 @@ static struct task_struct *idle_thread(i - - current->thread.request.u.thread.proc = idle_proc; - current->thread.request.u.thread.arg = (void *) cpu; -- new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL); -- if(IS_ERR(new_task)) panic("do_fork failed in idle_thread"); -+ new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, -+ NULL); -+ if(IS_ERR(new_task)) -+ panic("copy_process failed in idle_thread, error = %ld", -+ PTR_ERR(new_task)); - - cpu_tasks[cpu] = ((struct cpu_task) - { .pid = new_task->thread.mode.tt.extern_pid, - .task = new_task } ); - idle_threads[cpu] = new_task; -- CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, -+ CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, - sizeof(c)), - ({ panic("skas mode doesn't support SMP"); })); -+ wake_up_forked_process(new_task); - return(new_task); - } - -@@ -160,15 +169,17 @@ void smp_prepare_cpus(unsigned int maxcp - { - struct task_struct *idle; - unsigned long waittime; -- int err, cpu; -+ int err, cpu, me = smp_processor_id(); - -- cpu_set(0, cpu_online_map); -- cpu_set(0, smp_callin_map); -+ cpu_clear(me, cpu_online_map); -+ cpu_set(me, cpu_online_map); -+ cpu_set(me, cpu_callin_map); - -- err = os_pipe(cpu_data[0].ipi_pipe, 1, 1); -- if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err); -+ err = os_pipe(cpu_data[me].ipi_pipe, 1, 1); -+ if(err < 0) -+ panic("CPU#0 failed to create IPI pipe, errno = %d", -err); - -- activate_ipi(cpu_data[0].ipi_pipe[0], -+ activate_ipi(cpu_data[me].ipi_pipe[0], - current->thread.mode.tt.extern_pid); - - for(cpu = 1; cpu < ncpus; cpu++){ -@@ -180,10 +191,10 @@ void smp_prepare_cpus(unsigned int maxcp - unhash_process(idle); - - waittime = 200000000; -- while (waittime-- && !cpu_isset(cpu, smp_callin_map)) -+ while (waittime-- && !cpu_isset(cpu, cpu_callin_map)) - cpu_relax(); - -- if (cpu_isset(cpu, smp_callin_map)) -+ if (cpu_isset(cpu, cpu_callin_map)) - printk("done\n"); - else printk("failed\n"); - } -@@ -216,7 +227,7 @@ void IPI_handler(int cpu) - int fd; - - fd = cpu_data[cpu].ipi_pipe[0]; -- while (read(fd, &c, 1) == 1) { -+ while (os_read_file(fd, &c, 1) == 1) { - switch (c) { - case 'C': - smp_call_function_slave(cpu); -@@ -276,9 +287,9 @@ int smp_call_function(void (*_func)(void - info = _info; - - for (i=0;i<NR_CPUS;i++) -- if((i != current->thread_info->cpu) && -+ if((i != current_thread->cpu) && - cpu_isset(i, cpu_online_map)) -- write(cpu_data[i].ipi_pipe[1], "C", 1); -+ os_write_file(cpu_data[i].ipi_pipe[1], "C", 1); - - while (atomic_read(&scf_started) != cpus) - barrier(); -diff -puN arch/um/kernel/syscall_kern.c~Main-uml-patch-no-skas arch/um/kernel/syscall_kern.c ---- uml-linux-2.6.7/arch/um/kernel/syscall_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.572310480 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/syscall_kern.c 2004-06-29 21:02:55.739285096 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -36,32 +36,34 @@ long um_mount(char * dev_name, char * di - - long sys_fork(void) - { -- struct task_struct *p; -+ long ret; - - current->thread.forking = 1; -- p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL); -+ ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL); - current->thread.forking = 0; -- return(IS_ERR(p) ? PTR_ERR(p) : p->pid); -+ return(ret); - } - --long sys_clone(unsigned long clone_flags, unsigned long newsp) -+long sys_clone(unsigned long clone_flags, unsigned long newsp, -+ int *parent_tid, int *child_tid) - { -- struct task_struct *p; -+ long ret; - - current->thread.forking = 1; -- p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL); -+ ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid); - current->thread.forking = 0; -- return(IS_ERR(p) ? PTR_ERR(p) : p->pid); -+ return(ret); - } - - long sys_vfork(void) - { -- struct task_struct *p; -+ long ret; - - current->thread.forking = 1; -- p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL); -+ ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, -+ NULL); - current->thread.forking = 0; -- return(IS_ERR(p) ? PTR_ERR(p) : p->pid); -+ return(ret); - } - - /* common code for old and new mmaps */ -@@ -136,43 +138,12 @@ int sys_pipe(unsigned long * fildes) - - error = do_pipe(fd); - if (!error) { -- if (copy_to_user(fildes, fd, 2*sizeof(int))) -+ if (copy_to_user(fildes, fd, sizeof(fd))) - error = -EFAULT; - } - return error; - } - --int sys_sigaction(int sig, const struct old_sigaction *act, -- struct old_sigaction *oact) --{ -- struct k_sigaction new_ka, old_ka; -- int ret; -- -- if (act) { -- old_sigset_t mask; -- if (verify_area(VERIFY_READ, act, sizeof(*act)) || -- __get_user(new_ka.sa.sa_handler, &act->sa_handler) || -- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) -- return -EFAULT; -- __get_user(new_ka.sa.sa_flags, &act->sa_flags); -- __get_user(mask, &act->sa_mask); -- siginitset(&new_ka.sa.sa_mask, mask); -- } -- -- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); -- -- if (!ret && oact) { -- if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || -- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || -- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) -- return -EFAULT; -- __put_user(old_ka.sa.sa_flags, &oact->sa_flags); -- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); -- } -- -- return ret; --} -- - /* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * -@@ -254,7 +225,7 @@ int sys_ipc (uint call, int first, int s - return sys_shmctl (first, second, - (struct shmid_ds *) ptr); - default: -- return -EINVAL; -+ return -ENOSYS; - } - } - -@@ -303,11 +274,6 @@ int sys_olduname(struct oldold_utsname * - return error; - } - --int sys_sigaltstack(const stack_t *uss, stack_t *uoss) --{ -- return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs))); --} -- - long execute_syscall(void *r) - { - return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r)); -diff -puN arch/um/kernel/sys_call_table.c~Main-uml-patch-no-skas arch/um/kernel/sys_call_table.c ---- uml-linux-2.6.7/arch/um/kernel/sys_call_table.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.573310328 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/sys_call_table.c 2004-06-29 21:02:55.740284944 +0200 -@@ -5,7 +5,6 @@ - - #include "linux/config.h" - #include "linux/unistd.h" --#include "linux/version.h" - #include "linux/sys.h" - #include "linux/swap.h" - #include "linux/syscalls.h" -@@ -14,251 +13,50 @@ - #include "sysdep/syscalls.h" - #include "kern_util.h" - --extern syscall_handler_t sys_restart_syscall; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_exit; -+#ifdef CONFIG_NFSD -+#define NFSSERVCTL sys_nfsservctl -+#else -+#define NFSSERVCTL sys_ni_syscall -+#endif -+ -+#define LAST_GENERIC_SYSCALL __NR_vserver -+ -+#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL -+#define LAST_SYSCALL LAST_GENERIC_SYSCALL -+#else -+#define LAST_SYSCALL LAST_ARCH_SYSCALL -+#endif -+ - extern syscall_handler_t sys_fork; --extern syscall_handler_t sys_creat; --extern syscall_handler_t sys_link; --extern syscall_handler_t sys_unlink; --extern syscall_handler_t sys_chdir; --extern syscall_handler_t sys_mknod; --extern syscall_handler_t sys_chmod; --extern syscall_handler_t sys_lchown16; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_stat; --extern syscall_handler_t sys_getpid; --extern syscall_handler_t sys_oldumount; --extern syscall_handler_t sys_setuid16; --extern syscall_handler_t sys_getuid16; -+extern syscall_handler_t sys_execve; -+extern syscall_handler_t um_time; -+extern syscall_handler_t um_mount; -+extern syscall_handler_t um_stime; - extern syscall_handler_t sys_ptrace; --extern syscall_handler_t sys_alarm; --extern syscall_handler_t sys_fstat; --extern syscall_handler_t sys_pause; --extern syscall_handler_t sys_utime; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_access; --extern syscall_handler_t sys_nice; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_sync; --extern syscall_handler_t sys_kill; --extern syscall_handler_t sys_rename; --extern syscall_handler_t sys_mkdir; --extern syscall_handler_t sys_rmdir; - extern syscall_handler_t sys_pipe; --extern syscall_handler_t sys_times; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_brk; --extern syscall_handler_t sys_setgid16; --extern syscall_handler_t sys_getgid16; --extern syscall_handler_t sys_signal; --extern syscall_handler_t sys_geteuid16; --extern syscall_handler_t sys_getegid16; --extern syscall_handler_t sys_acct; --extern syscall_handler_t sys_umount; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_ioctl; --extern syscall_handler_t sys_fcntl; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_setpgid; --extern syscall_handler_t sys_ni_syscall; - extern syscall_handler_t sys_olduname; --extern syscall_handler_t sys_umask; --extern syscall_handler_t sys_chroot; --extern syscall_handler_t sys_ustat; --extern syscall_handler_t sys_dup2; --extern syscall_handler_t sys_getppid; --extern syscall_handler_t sys_getpgrp; - extern syscall_handler_t sys_sigaction; --extern syscall_handler_t sys_sgetmask; --extern syscall_handler_t sys_ssetmask; --extern syscall_handler_t sys_setreuid16; --extern syscall_handler_t sys_setregid16; - extern syscall_handler_t sys_sigsuspend; --extern syscall_handler_t sys_sigpending; --extern syscall_handler_t sys_sethostname; --extern syscall_handler_t sys_setrlimit; --extern syscall_handler_t sys_old_getrlimit; --extern syscall_handler_t sys_getrusage; --extern syscall_handler_t sys_gettimeofday; --extern syscall_handler_t sys_settimeofday; --extern syscall_handler_t sys_getgroups16; --extern syscall_handler_t sys_setgroups16; --extern syscall_handler_t sys_symlink; --extern syscall_handler_t sys_lstat; --extern syscall_handler_t sys_readlink; --extern syscall_handler_t sys_swapon; --extern syscall_handler_t sys_uselib; --extern syscall_handler_t sys_reboot; - extern syscall_handler_t old_readdir; --extern syscall_handler_t sys_munmap; --extern syscall_handler_t sys_truncate; --extern syscall_handler_t sys_ftruncate; --extern syscall_handler_t sys_fchmod; --extern syscall_handler_t sys_fchown16; --extern syscall_handler_t sys_getpriority; --extern syscall_handler_t sys_setpriority; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_statfs; --extern syscall_handler_t sys_fstatfs; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_socketcall; --extern syscall_handler_t sys_syslog; --extern syscall_handler_t sys_setitimer; --extern syscall_handler_t sys_getitimer; --extern syscall_handler_t sys_newstat; --extern syscall_handler_t sys_newlstat; --extern syscall_handler_t sys_newfstat; - extern syscall_handler_t sys_uname; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_vhangup; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_swapoff; --extern syscall_handler_t sys_sysinfo; - extern syscall_handler_t sys_ipc; --extern syscall_handler_t sys_fsync; - extern syscall_handler_t sys_sigreturn; --extern syscall_handler_t sys_rt_sigreturn; - extern syscall_handler_t sys_clone; --extern syscall_handler_t sys_setdomainname; --extern syscall_handler_t sys_newuname; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_adjtimex; --extern syscall_handler_t sys_mprotect; --extern syscall_handler_t sys_sigprocmask; --extern syscall_handler_t sys_init_module; --extern syscall_handler_t sys_delete_module; --extern syscall_handler_t sys_quotactl; --extern syscall_handler_t sys_getpgid; --extern syscall_handler_t sys_fchdir; --extern syscall_handler_t sys_bdflush; --extern syscall_handler_t sys_sysfs; --extern syscall_handler_t sys_personality; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_setfsuid16; --extern syscall_handler_t sys_setfsgid16; --extern syscall_handler_t sys_llseek; --extern syscall_handler_t sys_getdents; --extern syscall_handler_t sys_flock; --extern syscall_handler_t sys_msync; --extern syscall_handler_t sys_readv; --extern syscall_handler_t sys_writev; --extern syscall_handler_t sys_getsid; --extern syscall_handler_t sys_fdatasync; --extern syscall_handler_t sys_mlock; --extern syscall_handler_t sys_munlock; --extern syscall_handler_t sys_mlockall; --extern syscall_handler_t sys_munlockall; --extern syscall_handler_t sys_sched_setparam; --extern syscall_handler_t sys_sched_getparam; --extern syscall_handler_t sys_sched_setscheduler; --extern syscall_handler_t sys_sched_getscheduler; --extern syscall_handler_t sys_sched_get_priority_max; --extern syscall_handler_t sys_sched_get_priority_min; --extern syscall_handler_t sys_sched_rr_get_interval; --extern syscall_handler_t sys_nanosleep; --extern syscall_handler_t sys_mremap; --extern syscall_handler_t sys_setresuid16; --extern syscall_handler_t sys_getresuid16; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_poll; --extern syscall_handler_t sys_nfsservctl; --extern syscall_handler_t sys_setresgid16; --extern syscall_handler_t sys_getresgid16; --extern syscall_handler_t sys_prctl; --extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_rt_sigreturn; - extern syscall_handler_t sys_rt_sigaction; --extern syscall_handler_t sys_rt_sigprocmask; --extern syscall_handler_t sys_rt_sigpending; --extern syscall_handler_t sys_rt_sigtimedwait; --extern syscall_handler_t sys_rt_sigqueueinfo; --extern syscall_handler_t sys_rt_sigsuspend; --extern syscall_handler_t sys_pread64; --extern syscall_handler_t sys_pwrite64; --extern syscall_handler_t sys_chown16; --extern syscall_handler_t sys_getcwd; --extern syscall_handler_t sys_capget; --extern syscall_handler_t sys_capset; - extern syscall_handler_t sys_sigaltstack; --extern syscall_handler_t sys_sendfile; --extern syscall_handler_t sys_ni_syscall; --extern syscall_handler_t sys_ni_syscall; - extern syscall_handler_t sys_vfork; --extern syscall_handler_t sys_getrlimit; - extern syscall_handler_t sys_mmap2; --extern syscall_handler_t sys_truncate64; --extern syscall_handler_t sys_ftruncate64; --extern syscall_handler_t sys_stat64; --extern syscall_handler_t sys_lstat64; --extern syscall_handler_t sys_fstat64; --extern syscall_handler_t sys_lchown; --extern syscall_handler_t sys_getuid; --extern syscall_handler_t sys_getgid; --extern syscall_handler_t sys_geteuid; --extern syscall_handler_t sys_getegid; --extern syscall_handler_t sys_setreuid; --extern syscall_handler_t sys_setregid; --extern syscall_handler_t sys_getgroups; --extern syscall_handler_t sys_setgroups; --extern syscall_handler_t sys_fchown; --extern syscall_handler_t sys_setresuid; --extern syscall_handler_t sys_getresuid; --extern syscall_handler_t sys_setresgid; --extern syscall_handler_t sys_getresgid; --extern syscall_handler_t sys_chown; --extern syscall_handler_t sys_setuid; --extern syscall_handler_t sys_setgid; --extern syscall_handler_t sys_setfsuid; --extern syscall_handler_t sys_setfsgid; --extern syscall_handler_t sys_pivot_root; --extern syscall_handler_t sys_mincore; --extern syscall_handler_t sys_madvise; --extern syscall_handler_t sys_fcntl64; --extern syscall_handler_t sys_getdents64; --extern syscall_handler_t sys_gettid; --extern syscall_handler_t sys_readahead; --extern syscall_handler_t sys_tkill; --extern syscall_handler_t sys_sendfile64; --extern syscall_handler_t sys_futex; --extern syscall_handler_t sys_sched_setaffinity; --extern syscall_handler_t sys_sched_getaffinity; --extern syscall_handler_t sys_io_setup; --extern syscall_handler_t sys_io_destroy; --extern syscall_handler_t sys_io_getevents; --extern syscall_handler_t sys_io_submit; --extern syscall_handler_t sys_io_cancel; --extern syscall_handler_t sys_exit_group; --extern syscall_handler_t sys_lookup_dcookie; --extern syscall_handler_t sys_epoll_create; --extern syscall_handler_t sys_epoll_ctl; --extern syscall_handler_t sys_epoll_wait; --extern syscall_handler_t sys_remap_file_pages; --extern syscall_handler_t sys_set_tid_address; -- --#ifdef CONFIG_NFSD --#define NFSSERVCTL sys_nfsservctl --#else --#define NFSSERVCTL sys_ni_syscall --#endif -- --extern syscall_handler_t um_mount; --extern syscall_handler_t um_time; --extern syscall_handler_t um_stime; -- --#define LAST_GENERIC_SYSCALL __NR_set_tid_address -- --#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL --#define LAST_SYSCALL LAST_GENERIC_SYSCALL --#else --#define LAST_SYSCALL LAST_ARCH_SYSCALL --#endif -+extern syscall_handler_t sys_timer_create; -+extern syscall_handler_t old_mmap_i386; -+extern syscall_handler_t old_select; -+extern syscall_handler_t sys_modify_ldt; -+extern syscall_handler_t sys_rt_sigsuspend; - - syscall_handler_t *sys_call_table[] = { -- [ __NR_restart_syscall ] = sys_restart_syscall, -- [ __NR_exit ] = sys_exit, -- [ __NR_fork ] = sys_fork, -+ [ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall, -+ [ __NR_exit ] (syscall_handler_t *) sys_exit, -+ [ __NR_fork ] (syscall_handler_t *) sys_fork, - [ __NR_read ] = (syscall_handler_t *) sys_read, - [ __NR_write ] = (syscall_handler_t *) sys_write, - -@@ -266,229 +64,249 @@ syscall_handler_t *sys_call_table[] = { - [ __NR_open ] = (syscall_handler_t *) sys_open, - [ __NR_close ] = (syscall_handler_t *) sys_close, - [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, -- [ __NR_creat ] = sys_creat, -- [ __NR_link ] = sys_link, -- [ __NR_unlink ] = sys_unlink, -+ [ __NR_creat ] (syscall_handler_t *) sys_creat, -+ [ __NR_link ] (syscall_handler_t *) sys_link, -+ [ __NR_unlink ] (syscall_handler_t *) sys_unlink, - [ __NR_execve ] = (syscall_handler_t *) sys_execve, - - /* declared differently in kern_util.h */ -- [ __NR_chdir ] = sys_chdir, -+ [ __NR_chdir ] (syscall_handler_t *) sys_chdir, - [ __NR_time ] = um_time, -- [ __NR_mknod ] = sys_mknod, -- [ __NR_chmod ] = sys_chmod, -- [ __NR_lchown ] = sys_lchown16, -- [ __NR_break ] = sys_ni_syscall, -- [ __NR_oldstat ] = sys_stat, -+ [ __NR_mknod ] (syscall_handler_t *) sys_mknod, -+ [ __NR_chmod ] (syscall_handler_t *) sys_chmod, -+ [ __NR_lchown ] (syscall_handler_t *) sys_lchown16, -+ [ __NR_break ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_oldstat ] (syscall_handler_t *) sys_stat, - [ __NR_lseek ] = (syscall_handler_t *) sys_lseek, -- [ __NR_getpid ] = sys_getpid, -+ [ __NR_getpid ] (syscall_handler_t *) sys_getpid, - [ __NR_mount ] = um_mount, -- [ __NR_umount ] = sys_oldumount, -- [ __NR_setuid ] = sys_setuid16, -- [ __NR_getuid ] = sys_getuid16, -+ [ __NR_umount ] (syscall_handler_t *) sys_oldumount, -+ [ __NR_setuid ] (syscall_handler_t *) sys_setuid16, -+ [ __NR_getuid ] (syscall_handler_t *) sys_getuid16, - [ __NR_stime ] = um_stime, -- [ __NR_ptrace ] = sys_ptrace, -- [ __NR_alarm ] = sys_alarm, -- [ __NR_oldfstat ] = sys_fstat, -- [ __NR_pause ] = sys_pause, -- [ __NR_utime ] = sys_utime, -- [ __NR_stty ] = sys_ni_syscall, -- [ __NR_gtty ] = sys_ni_syscall, -- [ __NR_access ] = sys_access, -- [ __NR_nice ] = sys_nice, -- [ __NR_ftime ] = sys_ni_syscall, -- [ __NR_sync ] = sys_sync, -- [ __NR_kill ] = sys_kill, -- [ __NR_rename ] = sys_rename, -- [ __NR_mkdir ] = sys_mkdir, -- [ __NR_rmdir ] = sys_rmdir, -+ [ __NR_ptrace ] (syscall_handler_t *) sys_ptrace, -+ [ __NR_alarm ] (syscall_handler_t *) sys_alarm, -+ [ __NR_oldfstat ] (syscall_handler_t *) sys_fstat, -+ [ __NR_pause ] (syscall_handler_t *) sys_pause, -+ [ __NR_utime ] (syscall_handler_t *) sys_utime, -+ [ __NR_stty ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_gtty ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_access ] (syscall_handler_t *) sys_access, -+ [ __NR_nice ] (syscall_handler_t *) sys_nice, -+ [ __NR_ftime ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_sync ] (syscall_handler_t *) sys_sync, -+ [ __NR_kill ] (syscall_handler_t *) sys_kill, -+ [ __NR_rename ] (syscall_handler_t *) sys_rename, -+ [ __NR_mkdir ] (syscall_handler_t *) sys_mkdir, -+ [ __NR_rmdir ] (syscall_handler_t *) sys_rmdir, - - /* Declared differently in asm/unistd.h */ - [ __NR_dup ] = (syscall_handler_t *) sys_dup, -- [ __NR_pipe ] = sys_pipe, -- [ __NR_times ] = sys_times, -- [ __NR_prof ] = sys_ni_syscall, -- [ __NR_brk ] = sys_brk, -- [ __NR_setgid ] = sys_setgid16, -- [ __NR_getgid ] = sys_getgid16, -- [ __NR_signal ] = sys_signal, -- [ __NR_geteuid ] = sys_geteuid16, -- [ __NR_getegid ] = sys_getegid16, -- [ __NR_acct ] = sys_acct, -- [ __NR_umount2 ] = sys_umount, -- [ __NR_lock ] = sys_ni_syscall, -- [ __NR_ioctl ] = sys_ioctl, -- [ __NR_fcntl ] = sys_fcntl, -- [ __NR_mpx ] = sys_ni_syscall, -- [ __NR_setpgid ] = sys_setpgid, -- [ __NR_ulimit ] = sys_ni_syscall, -- [ __NR_oldolduname ] = sys_olduname, -- [ __NR_umask ] = sys_umask, -- [ __NR_chroot ] = sys_chroot, -- [ __NR_ustat ] = sys_ustat, -- [ __NR_dup2 ] = sys_dup2, -- [ __NR_getppid ] = sys_getppid, -- [ __NR_getpgrp ] = sys_getpgrp, -+ [ __NR_pipe ] (syscall_handler_t *) sys_pipe, -+ [ __NR_times ] (syscall_handler_t *) sys_times, -+ [ __NR_prof ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_brk ] (syscall_handler_t *) sys_brk, -+ [ __NR_setgid ] (syscall_handler_t *) sys_setgid16, -+ [ __NR_getgid ] (syscall_handler_t *) sys_getgid16, -+ [ __NR_signal ] (syscall_handler_t *) sys_signal, -+ [ __NR_geteuid ] (syscall_handler_t *) sys_geteuid16, -+ [ __NR_getegid ] (syscall_handler_t *) sys_getegid16, -+ [ __NR_acct ] (syscall_handler_t *) sys_acct, -+ [ __NR_umount2 ] (syscall_handler_t *) sys_umount, -+ [ __NR_lock ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_ioctl ] (syscall_handler_t *) sys_ioctl, -+ [ __NR_fcntl ] (syscall_handler_t *) sys_fcntl, -+ [ __NR_mpx ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_setpgid ] (syscall_handler_t *) sys_setpgid, -+ [ __NR_ulimit ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_oldolduname ] (syscall_handler_t *) sys_olduname, -+ [ __NR_umask ] (syscall_handler_t *) sys_umask, -+ [ __NR_chroot ] (syscall_handler_t *) sys_chroot, -+ [ __NR_ustat ] (syscall_handler_t *) sys_ustat, -+ [ __NR_dup2 ] (syscall_handler_t *) sys_dup2, -+ [ __NR_getppid ] (syscall_handler_t *) sys_getppid, -+ [ __NR_getpgrp ] (syscall_handler_t *) sys_getpgrp, - [ __NR_setsid ] = (syscall_handler_t *) sys_setsid, -- [ __NR_sigaction ] = sys_sigaction, -- [ __NR_sgetmask ] = sys_sgetmask, -- [ __NR_ssetmask ] = sys_ssetmask, -- [ __NR_setreuid ] = sys_setreuid16, -- [ __NR_setregid ] = sys_setregid16, -- [ __NR_sigsuspend ] = sys_sigsuspend, -- [ __NR_sigpending ] = sys_sigpending, -- [ __NR_sethostname ] = sys_sethostname, -- [ __NR_setrlimit ] = sys_setrlimit, -- [ __NR_getrlimit ] = sys_old_getrlimit, -- [ __NR_getrusage ] = sys_getrusage, -- [ __NR_gettimeofday ] = sys_gettimeofday, -- [ __NR_settimeofday ] = sys_settimeofday, -- [ __NR_getgroups ] = sys_getgroups16, -- [ __NR_setgroups ] = sys_setgroups16, -- [ __NR_symlink ] = sys_symlink, -- [ __NR_oldlstat ] = sys_lstat, -- [ __NR_readlink ] = sys_readlink, -- [ __NR_uselib ] = sys_uselib, -+ [ __NR_sigaction ] (syscall_handler_t *) sys_sigaction, -+ [ __NR_sgetmask ] (syscall_handler_t *) sys_sgetmask, -+ [ __NR_ssetmask ] (syscall_handler_t *) sys_ssetmask, -+ [ __NR_setreuid ] (syscall_handler_t *) sys_setreuid16, -+ [ __NR_setregid ] (syscall_handler_t *) sys_setregid16, -+ [ __NR_sigsuspend ] (syscall_handler_t *) sys_sigsuspend, -+ [ __NR_sigpending ] (syscall_handler_t *) sys_sigpending, -+ [ __NR_sethostname ] (syscall_handler_t *) sys_sethostname, -+ [ __NR_setrlimit ] (syscall_handler_t *) sys_setrlimit, -+ [ __NR_getrlimit ] (syscall_handler_t *) sys_old_getrlimit, -+ [ __NR_getrusage ] (syscall_handler_t *) sys_getrusage, -+ [ __NR_gettimeofday ] (syscall_handler_t *) sys_gettimeofday, -+ [ __NR_settimeofday ] (syscall_handler_t *) sys_settimeofday, -+ [ __NR_getgroups ] (syscall_handler_t *) sys_getgroups16, -+ [ __NR_setgroups ] (syscall_handler_t *) sys_setgroups16, -+ [ __NR_symlink ] (syscall_handler_t *) sys_symlink, -+ [ __NR_oldlstat ] (syscall_handler_t *) sys_lstat, -+ [ __NR_readlink ] (syscall_handler_t *) sys_readlink, -+ [ __NR_uselib ] (syscall_handler_t *) sys_uselib, - [ __NR_swapon ] = (syscall_handler_t *) sys_swapon, -- [ __NR_reboot ] = sys_reboot, -+ [ __NR_reboot ] (syscall_handler_t *) sys_reboot, - [ __NR_readdir ] = old_readdir, -- [ __NR_munmap ] = sys_munmap, -- [ __NR_truncate ] = sys_truncate, -- [ __NR_ftruncate ] = sys_ftruncate, -- [ __NR_fchmod ] = sys_fchmod, -- [ __NR_fchown ] = sys_fchown16, -- [ __NR_getpriority ] = sys_getpriority, -- [ __NR_setpriority ] = sys_setpriority, -- [ __NR_profil ] = sys_ni_syscall, -- [ __NR_statfs ] = sys_statfs, -- [ __NR_fstatfs ] = sys_fstatfs, -- [ __NR_ioperm ] = sys_ni_syscall, -- [ __NR_socketcall ] = sys_socketcall, -- [ __NR_syslog ] = sys_syslog, -- [ __NR_setitimer ] = sys_setitimer, -- [ __NR_getitimer ] = sys_getitimer, -- [ __NR_stat ] = sys_newstat, -- [ __NR_lstat ] = sys_newlstat, -- [ __NR_fstat ] = sys_newfstat, -- [ __NR_olduname ] = sys_uname, -- [ __NR_iopl ] = sys_ni_syscall, -- [ __NR_vhangup ] = sys_vhangup, -- [ __NR_idle ] = sys_ni_syscall, -+ [ __NR_munmap ] (syscall_handler_t *) sys_munmap, -+ [ __NR_truncate ] (syscall_handler_t *) sys_truncate, -+ [ __NR_ftruncate ] (syscall_handler_t *) sys_ftruncate, -+ [ __NR_fchmod ] (syscall_handler_t *) sys_fchmod, -+ [ __NR_fchown ] (syscall_handler_t *) sys_fchown16, -+ [ __NR_getpriority ] (syscall_handler_t *) sys_getpriority, -+ [ __NR_setpriority ] (syscall_handler_t *) sys_setpriority, -+ [ __NR_profil ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_statfs ] (syscall_handler_t *) sys_statfs, -+ [ __NR_fstatfs ] (syscall_handler_t *) sys_fstatfs, -+ [ __NR_ioperm ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_socketcall ] (syscall_handler_t *) sys_socketcall, -+ [ __NR_syslog ] (syscall_handler_t *) sys_syslog, -+ [ __NR_setitimer ] (syscall_handler_t *) sys_setitimer, -+ [ __NR_getitimer ] (syscall_handler_t *) sys_getitimer, -+ [ __NR_stat ] (syscall_handler_t *) sys_newstat, -+ [ __NR_lstat ] (syscall_handler_t *) sys_newlstat, -+ [ __NR_fstat ] (syscall_handler_t *) sys_newfstat, -+ [ __NR_olduname ] (syscall_handler_t *) sys_uname, -+ [ __NR_iopl ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_vhangup ] (syscall_handler_t *) sys_vhangup, -+ [ __NR_idle ] (syscall_handler_t *) sys_ni_syscall, - [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4, - [ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff, -- [ __NR_sysinfo ] = sys_sysinfo, -- [ __NR_ipc ] = sys_ipc, -- [ __NR_fsync ] = sys_fsync, -- [ __NR_sigreturn ] = sys_sigreturn, -- [ __NR_clone ] = sys_clone, -- [ __NR_setdomainname ] = sys_setdomainname, -- [ __NR_uname ] = sys_newuname, -- [ __NR_adjtimex ] = sys_adjtimex, -- [ __NR_mprotect ] = sys_mprotect, -- [ __NR_sigprocmask ] = sys_sigprocmask, -- [ __NR_create_module ] = sys_ni_syscall, -- [ __NR_init_module ] = sys_init_module, -- [ __NR_delete_module ] = sys_delete_module, -- [ __NR_get_kernel_syms ] = sys_ni_syscall, -- [ __NR_quotactl ] = sys_quotactl, -- [ __NR_getpgid ] = sys_getpgid, -- [ __NR_fchdir ] = sys_fchdir, -- [ __NR_bdflush ] = sys_bdflush, -- [ __NR_sysfs ] = sys_sysfs, -- [ __NR_personality ] = sys_personality, -- [ __NR_afs_syscall ] = sys_ni_syscall, -- [ __NR_setfsuid ] = sys_setfsuid16, -- [ __NR_setfsgid ] = sys_setfsgid16, -- [ __NR__llseek ] = sys_llseek, -- [ __NR_getdents ] = sys_getdents, -+ [ __NR_sysinfo ] (syscall_handler_t *) sys_sysinfo, -+ [ __NR_ipc ] (syscall_handler_t *) sys_ipc, -+ [ __NR_fsync ] (syscall_handler_t *) sys_fsync, -+ [ __NR_sigreturn ] (syscall_handler_t *) sys_sigreturn, -+ [ __NR_clone ] (syscall_handler_t *) sys_clone, -+ [ __NR_setdomainname ] (syscall_handler_t *) sys_setdomainname, -+ [ __NR_uname ] (syscall_handler_t *) sys_newuname, -+ [ __NR_adjtimex ] (syscall_handler_t *) sys_adjtimex, -+ [ __NR_mprotect ] (syscall_handler_t *) sys_mprotect, -+ [ __NR_sigprocmask ] (syscall_handler_t *) sys_sigprocmask, -+ [ __NR_create_module ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_init_module ] (syscall_handler_t *) sys_init_module, -+ [ __NR_delete_module ] (syscall_handler_t *) sys_delete_module, -+ [ __NR_get_kernel_syms ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_quotactl ] (syscall_handler_t *) sys_quotactl, -+ [ __NR_getpgid ] (syscall_handler_t *) sys_getpgid, -+ [ __NR_fchdir ] (syscall_handler_t *) sys_fchdir, -+ [ __NR_bdflush ] (syscall_handler_t *) sys_bdflush, -+ [ __NR_sysfs ] (syscall_handler_t *) sys_sysfs, -+ [ __NR_personality ] (syscall_handler_t *) sys_personality, -+ [ __NR_afs_syscall ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_setfsuid ] (syscall_handler_t *) sys_setfsuid16, -+ [ __NR_setfsgid ] (syscall_handler_t *) sys_setfsgid16, -+ [ __NR__llseek ] (syscall_handler_t *) sys_llseek, -+ [ __NR_getdents ] (syscall_handler_t *) sys_getdents, - [ __NR__newselect ] = (syscall_handler_t *) sys_select, -- [ __NR_flock ] = sys_flock, -- [ __NR_msync ] = sys_msync, -- [ __NR_readv ] = sys_readv, -- [ __NR_writev ] = sys_writev, -- [ __NR_getsid ] = sys_getsid, -- [ __NR_fdatasync ] = sys_fdatasync, -+ [ __NR_flock ] (syscall_handler_t *) sys_flock, -+ [ __NR_msync ] (syscall_handler_t *) sys_msync, -+ [ __NR_readv ] (syscall_handler_t *) sys_readv, -+ [ __NR_writev ] (syscall_handler_t *) sys_writev, -+ [ __NR_getsid ] (syscall_handler_t *) sys_getsid, -+ [ __NR_fdatasync ] (syscall_handler_t *) sys_fdatasync, - [ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl, -- [ __NR_mlock ] = sys_mlock, -- [ __NR_munlock ] = sys_munlock, -- [ __NR_mlockall ] = sys_mlockall, -- [ __NR_munlockall ] = sys_munlockall, -- [ __NR_sched_setparam ] = sys_sched_setparam, -- [ __NR_sched_getparam ] = sys_sched_getparam, -- [ __NR_sched_setscheduler ] = sys_sched_setscheduler, -- [ __NR_sched_getscheduler ] = sys_sched_getscheduler, -+ [ __NR_mlock ] (syscall_handler_t *) sys_mlock, -+ [ __NR_munlock ] (syscall_handler_t *) sys_munlock, -+ [ __NR_mlockall ] (syscall_handler_t *) sys_mlockall, -+ [ __NR_munlockall ] (syscall_handler_t *) sys_munlockall, -+ [ __NR_sched_setparam ] (syscall_handler_t *) sys_sched_setparam, -+ [ __NR_sched_getparam ] (syscall_handler_t *) sys_sched_getparam, -+ [ __NR_sched_setscheduler ] (syscall_handler_t *) sys_sched_setscheduler, -+ [ __NR_sched_getscheduler ] (syscall_handler_t *) sys_sched_getscheduler, - [ __NR_sched_yield ] = (syscall_handler_t *) yield, -- [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max, -- [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min, -- [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval, -- [ __NR_nanosleep ] = sys_nanosleep, -- [ __NR_mremap ] = sys_mremap, -- [ __NR_setresuid ] = sys_setresuid16, -- [ __NR_getresuid ] = sys_getresuid16, -- [ __NR_vm86 ] = sys_ni_syscall, -- [ __NR_query_module ] = sys_ni_syscall, -- [ __NR_poll ] = sys_poll, -- [ __NR_nfsservctl ] = NFSSERVCTL, -- [ __NR_setresgid ] = sys_setresgid16, -- [ __NR_getresgid ] = sys_getresgid16, -- [ __NR_prctl ] = sys_prctl, -- [ __NR_rt_sigreturn ] = sys_rt_sigreturn, -- [ __NR_rt_sigaction ] = sys_rt_sigaction, -- [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask, -- [ __NR_rt_sigpending ] = sys_rt_sigpending, -- [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait, -- [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo, -- [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend, -- [ __NR_pread64 ] = sys_pread64, -- [ __NR_pwrite64 ] = sys_pwrite64, -- [ __NR_chown ] = sys_chown16, -- [ __NR_getcwd ] = sys_getcwd, -- [ __NR_capget ] = sys_capget, -- [ __NR_capset ] = sys_capset, -- [ __NR_sigaltstack ] = sys_sigaltstack, -- [ __NR_sendfile ] = sys_sendfile, -- [ __NR_getpmsg ] = sys_ni_syscall, -- [ __NR_putpmsg ] = sys_ni_syscall, -- [ __NR_vfork ] = sys_vfork, -- [ __NR_ugetrlimit ] = sys_getrlimit, -- [ __NR_mmap2 ] = sys_mmap2, -- [ __NR_truncate64 ] = sys_truncate64, -- [ __NR_ftruncate64 ] = sys_ftruncate64, -- [ __NR_stat64 ] = sys_stat64, -- [ __NR_lstat64 ] = sys_lstat64, -- [ __NR_fstat64 ] = sys_fstat64, -- [ __NR_fcntl64 ] = sys_fcntl64, -- [ __NR_getdents64 ] = sys_getdents64, -- [ __NR_gettid ] = sys_gettid, -- [ __NR_readahead ] = sys_readahead, -- [ __NR_setxattr ] = sys_ni_syscall, -- [ __NR_lsetxattr ] = sys_ni_syscall, -- [ __NR_fsetxattr ] = sys_ni_syscall, -- [ __NR_getxattr ] = sys_ni_syscall, -- [ __NR_lgetxattr ] = sys_ni_syscall, -- [ __NR_fgetxattr ] = sys_ni_syscall, -- [ __NR_listxattr ] = sys_ni_syscall, -- [ __NR_llistxattr ] = sys_ni_syscall, -- [ __NR_flistxattr ] = sys_ni_syscall, -- [ __NR_removexattr ] = sys_ni_syscall, -- [ __NR_lremovexattr ] = sys_ni_syscall, -- [ __NR_fremovexattr ] = sys_ni_syscall, -- [ __NR_tkill ] = sys_tkill, -- [ __NR_sendfile64 ] = sys_sendfile64, -- [ __NR_futex ] = sys_futex, -- [ __NR_sched_setaffinity ] = sys_sched_setaffinity, -- [ __NR_sched_getaffinity ] = sys_sched_getaffinity, -- [ __NR_io_setup ] = sys_io_setup, -- [ __NR_io_destroy ] = sys_io_destroy, -- [ __NR_io_getevents ] = sys_io_getevents, -- [ __NR_io_submit ] = sys_io_submit, -- [ __NR_io_cancel ] = sys_io_cancel, -- [ __NR_exit_group ] = sys_exit_group, -- [ __NR_lookup_dcookie ] = sys_lookup_dcookie, -- [ __NR_epoll_create ] = sys_epoll_create, -- [ __NR_epoll_ctl ] = sys_epoll_ctl, -- [ __NR_epoll_wait ] = sys_epoll_wait, -- [ __NR_remap_file_pages ] = sys_remap_file_pages, -- [ __NR_set_tid_address ] = sys_set_tid_address, -+ [ __NR_sched_get_priority_max ] (syscall_handler_t *) sys_sched_get_priority_max, -+ [ __NR_sched_get_priority_min ] (syscall_handler_t *) sys_sched_get_priority_min, -+ [ __NR_sched_rr_get_interval ] (syscall_handler_t *) sys_sched_rr_get_interval, -+ [ __NR_nanosleep ] (syscall_handler_t *) sys_nanosleep, -+ [ __NR_mremap ] (syscall_handler_t *) sys_mremap, -+ [ __NR_setresuid ] (syscall_handler_t *) sys_setresuid16, -+ [ __NR_getresuid ] (syscall_handler_t *) sys_getresuid16, -+ [ __NR_vm86 ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_query_module ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_poll ] (syscall_handler_t *) sys_poll, -+ [ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL, -+ [ __NR_setresgid ] (syscall_handler_t *) sys_setresgid16, -+ [ __NR_getresgid ] (syscall_handler_t *) sys_getresgid16, -+ [ __NR_prctl ] (syscall_handler_t *) sys_prctl, -+ [ __NR_rt_sigreturn ] (syscall_handler_t *) sys_rt_sigreturn, -+ [ __NR_rt_sigaction ] (syscall_handler_t *) sys_rt_sigaction, -+ [ __NR_rt_sigprocmask ] (syscall_handler_t *) sys_rt_sigprocmask, -+ [ __NR_rt_sigpending ] (syscall_handler_t *) sys_rt_sigpending, -+ [ __NR_rt_sigtimedwait ] (syscall_handler_t *) sys_rt_sigtimedwait, -+ [ __NR_rt_sigqueueinfo ] (syscall_handler_t *) sys_rt_sigqueueinfo, -+ [ __NR_rt_sigsuspend ] (syscall_handler_t *) sys_rt_sigsuspend, -+ [ __NR_pread64 ] (syscall_handler_t *) sys_pread64, -+ [ __NR_pwrite64 ] (syscall_handler_t *) sys_pwrite64, -+ [ __NR_chown ] (syscall_handler_t *) sys_chown16, -+ [ __NR_getcwd ] (syscall_handler_t *) sys_getcwd, -+ [ __NR_capget ] (syscall_handler_t *) sys_capget, -+ [ __NR_capset ] (syscall_handler_t *) sys_capset, -+ [ __NR_sigaltstack ] (syscall_handler_t *) sys_sigaltstack, -+ [ __NR_sendfile ] (syscall_handler_t *) sys_sendfile, -+ [ __NR_getpmsg ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_putpmsg ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_vfork ] (syscall_handler_t *) sys_vfork, -+ [ __NR_ugetrlimit ] (syscall_handler_t *) sys_getrlimit, -+ [ __NR_mmap2 ] (syscall_handler_t *) sys_mmap2, -+ [ __NR_truncate64 ] (syscall_handler_t *) sys_truncate64, -+ [ __NR_ftruncate64 ] (syscall_handler_t *) sys_ftruncate64, -+ [ __NR_stat64 ] (syscall_handler_t *) sys_stat64, -+ [ __NR_lstat64 ] (syscall_handler_t *) sys_lstat64, -+ [ __NR_fstat64 ] (syscall_handler_t *) sys_fstat64, -+ [ __NR_getdents64 ] (syscall_handler_t *) sys_getdents64, -+ [ __NR_fcntl64 ] (syscall_handler_t *) sys_fcntl64, -+ [ 223 ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_gettid ] (syscall_handler_t *) sys_gettid, -+ [ __NR_readahead ] (syscall_handler_t *) sys_readahead, -+ [ __NR_setxattr ] (syscall_handler_t *) sys_setxattr, -+ [ __NR_lsetxattr ] (syscall_handler_t *) sys_lsetxattr, -+ [ __NR_fsetxattr ] (syscall_handler_t *) sys_fsetxattr, -+ [ __NR_getxattr ] (syscall_handler_t *) sys_getxattr, -+ [ __NR_lgetxattr ] (syscall_handler_t *) sys_lgetxattr, -+ [ __NR_fgetxattr ] (syscall_handler_t *) sys_fgetxattr, -+ [ __NR_listxattr ] (syscall_handler_t *) sys_listxattr, -+ [ __NR_llistxattr ] (syscall_handler_t *) sys_llistxattr, -+ [ __NR_flistxattr ] (syscall_handler_t *) sys_flistxattr, -+ [ __NR_removexattr ] (syscall_handler_t *) sys_removexattr, -+ [ __NR_lremovexattr ] (syscall_handler_t *) sys_lremovexattr, -+ [ __NR_fremovexattr ] (syscall_handler_t *) sys_fremovexattr, -+ [ __NR_tkill ] (syscall_handler_t *) sys_tkill, -+ [ __NR_sendfile64 ] (syscall_handler_t *) sys_sendfile64, -+ [ __NR_futex ] (syscall_handler_t *) sys_futex, -+ [ __NR_sched_setaffinity ] (syscall_handler_t *) sys_sched_setaffinity, -+ [ __NR_sched_getaffinity ] (syscall_handler_t *) sys_sched_getaffinity, -+ [ __NR_set_thread_area ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_get_thread_area ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_io_setup ] (syscall_handler_t *) sys_io_setup, -+ [ __NR_io_destroy ] (syscall_handler_t *) sys_io_destroy, -+ [ __NR_io_getevents ] (syscall_handler_t *) sys_io_getevents, -+ [ __NR_io_submit ] (syscall_handler_t *) sys_io_submit, -+ [ __NR_io_cancel ] (syscall_handler_t *) sys_io_cancel, -+ [ __NR_fadvise64 ] (syscall_handler_t *) sys_fadvise64, -+ [ 251 ] (syscall_handler_t *) sys_ni_syscall, -+ [ __NR_exit_group ] (syscall_handler_t *) sys_exit_group, -+ [ __NR_lookup_dcookie ] (syscall_handler_t *) sys_lookup_dcookie, -+ [ __NR_epoll_create ] (syscall_handler_t *) sys_epoll_create, -+ [ __NR_epoll_ctl ] (syscall_handler_t *) sys_epoll_ctl, -+ [ __NR_epoll_wait ] (syscall_handler_t *) sys_epoll_wait, -+ [ __NR_remap_file_pages ] (syscall_handler_t *) sys_remap_file_pages, -+ [ __NR_set_tid_address ] (syscall_handler_t *) sys_set_tid_address, -+ [ __NR_timer_create ] (syscall_handler_t *) sys_timer_create, -+ [ __NR_timer_settime ] (syscall_handler_t *) sys_timer_settime, -+ [ __NR_timer_gettime ] (syscall_handler_t *) sys_timer_gettime, -+ [ __NR_timer_getoverrun ] (syscall_handler_t *) sys_timer_getoverrun, -+ [ __NR_timer_delete ] (syscall_handler_t *) sys_timer_delete, -+ [ __NR_clock_settime ] (syscall_handler_t *) sys_clock_settime, -+ [ __NR_clock_gettime ] (syscall_handler_t *) sys_clock_gettime, -+ [ __NR_clock_getres ] (syscall_handler_t *) sys_clock_getres, -+ [ __NR_clock_nanosleep ] (syscall_handler_t *) sys_clock_nanosleep, -+ [ __NR_statfs64 ] (syscall_handler_t *) sys_statfs64, -+ [ __NR_fstatfs64 ] (syscall_handler_t *) sys_fstatfs64, -+ [ __NR_tgkill ] (syscall_handler_t *) sys_tgkill, -+ [ __NR_utimes ] (syscall_handler_t *) sys_utimes, -+ [ __NR_fadvise64_64 ] (syscall_handler_t *) sys_fadvise64_64, -+ [ __NR_vserver ] (syscall_handler_t *) sys_ni_syscall, - - ARCH_SYSCALLS - [ LAST_SYSCALL + 1 ... NR_syscalls ] = -diff -puN arch/um/kernel/sysrq.c~Main-uml-patch-no-skas arch/um/kernel/sysrq.c ---- uml-linux-2.6.7/arch/um/kernel/sysrq.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.574310176 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/sysrq.c 2004-06-29 21:02:55.740284944 +0200 -@@ -44,6 +44,11 @@ void dump_stack(void) - } - EXPORT_SYMBOL(dump_stack); - -+void show_stack(struct task_struct *task, unsigned long *sp) -+{ -+ show_trace(sp); -+} -+ - /* - * 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 -puN arch/um/kernel/tempfile.c~Main-uml-patch-no-skas arch/um/kernel/tempfile.c ---- uml-linux-2.6.7/arch/um/kernel/tempfile.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.575310024 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tempfile.c 2004-06-29 21:02:55.740284944 +0200 -@@ -28,6 +28,7 @@ static void __init find_tempdir(void) - } - if((dir == NULL) || (*dir == '\0')) - dir = "/tmp"; -+ - tempdir = malloc(strlen(dir) + 2); - if(tempdir == NULL){ - fprintf(stderr, "Failed to malloc tempdir, " -@@ -49,7 +50,8 @@ int make_tempfile(const char *template, - else - *tempname = 0; - strcat(tempname, template); -- if((fd = mkstemp(tempname)) < 0){ -+ fd = mkstemp(tempname); -+ if(fd < 0){ - fprintf(stderr, "open - cannot create %s: %s\n", tempname, - strerror(errno)); - return -1; -@@ -59,7 +61,8 @@ int make_tempfile(const char *template, - return -1; - } - if(out_tempname){ -- if((*out_tempname = strdup(tempname)) == NULL){ -+ *out_tempname = strdup(tempname); -+ if(*out_tempname == NULL){ - perror("strdup"); - return -1; - } -diff -puN arch/um/kernel/time.c~Main-uml-patch-no-skas arch/um/kernel/time.c ---- uml-linux-2.6.7/arch/um/kernel/time.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.576309872 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/time.c 2004-06-29 21:02:55.741284792 +0200 -@@ -4,24 +4,33 @@ - */ - - #include <stdio.h> -+#include <stdlib.h> - #include <unistd.h> - #include <time.h> - #include <sys/time.h> - #include <signal.h> - #include <errno.h> --#include "linux/module.h" - #include "user_util.h" - #include "kern_util.h" - #include "user.h" - #include "process.h" - #include "signal_user.h" - #include "time_user.h" -+#include "kern_constants.h" -+ -+/* XXX This really needs to be declared and initialized in a kernel file since -+ * it's in <linux/time.h> -+ */ -+extern struct timespec wall_to_monotonic; - - extern struct timeval xtime; - -+struct timeval local_offset = { 0, 0 }; -+ - void timer(void) - { - gettimeofday(&xtime, NULL); -+ timeradd(&xtime, &local_offset, &xtime); - } - - void set_interval(int timer_type) -@@ -66,7 +75,7 @@ void switch_timers(int to_real) - errno); - } - --void idle_timer(void) -+void uml_idle_timer(void) - { - if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) - panic("Couldn't unset SIGVTALRM handler"); -@@ -76,14 +85,60 @@ void idle_timer(void) - set_interval(ITIMER_REAL); - } - -+static unsigned long long get_host_hz(void) -+{ -+ char mhzline[16], *end; -+ unsigned long long mhz; -+ int ret, mult, rest, len; -+ -+ ret = cpu_feature("cpu MHz", mhzline, -+ sizeof(mhzline) / sizeof(mhzline[0])); -+ if(!ret) -+ panic ("Could not get host MHZ"); -+ -+ mhz = strtoul(mhzline, &end, 10); -+ -+ /* This business is to parse a floating point number without using -+ * floating types. -+ */ -+ -+ rest = 0; -+ mult = 0; -+ if(*end == '.'){ -+ end++; -+ len = strlen(end); -+ if(len < 6) -+ mult = 6 - len; -+ else if(len > 6) -+ end[6] = '\0'; -+ rest = strtoul(end, NULL, 10); -+ while(mult-- > 0) -+ rest *= 10; -+ } -+ -+ return(1000000 * mhz + rest); -+} -+ -+unsigned long long host_hz = 0; -+ -+extern int do_posix_clock_monotonic_gettime(struct timespec *tp); -+ - void time_init(void) - { -+ struct timespec now; -+ -+ host_hz = get_host_hz(); - if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) - panic("Couldn't set SIGVTALRM handler"); - set_interval(ITIMER_VIRTUAL); -+ -+ do_posix_clock_monotonic_gettime(&now); -+ wall_to_monotonic.tv_sec = -now.tv_sec; -+ wall_to_monotonic.tv_nsec = -now.tv_nsec; - } - --struct timeval local_offset = { 0, 0 }; -+/* Declared in linux/time.h, which can't be included here */ -+extern void clock_was_set(void); - - void do_gettimeofday(struct timeval *tv) - { -@@ -96,15 +151,13 @@ void do_gettimeofday(struct timeval *tv) - clock_was_set(); - } - --EXPORT_SYMBOL(do_gettimeofday); -- - int do_settimeofday(struct timespec *tv) - { - struct timeval now; - unsigned long flags; - struct timeval tv_in; - -- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) -+ if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC) - return -EINVAL; - - tv_in.tv_sec = tv->tv_sec; -@@ -114,9 +167,9 @@ int do_settimeofday(struct timespec *tv) - gettimeofday(&now, NULL); - timersub(&tv_in, &now, &local_offset); - time_unlock(flags); --} - --EXPORT_SYMBOL(do_settimeofday); -+ return(0); -+} - - void idle_sleep(int secs) - { -diff -puN arch/um/kernel/time_kern.c~Main-uml-patch-no-skas arch/um/kernel/time_kern.c ---- uml-linux-2.6.7/arch/um/kernel/time_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.577309720 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/time_kern.c 2004-06-29 21:02:55.741284792 +0200 -@@ -30,22 +30,58 @@ int hz(void) - return(HZ); - } - -+/* -+ * Scheduler clock - returns current time in nanosec units. -+ */ -+unsigned long long sched_clock(void) -+{ -+ return (unsigned long long)jiffies_64 * (1000000000 / HZ); -+} -+ - /* Changed at early boot */ - int timer_irq_inited = 0; - --/* missed_ticks will be modified after kernel memory has been -- * write-protected, so this puts it in a section which will be left -- * write-enabled. -- */ --int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS]; -+static int first_tick; -+static unsigned long long prev_tsc; -+static long long delta; /* Deviation per interval */ -+ -+extern unsigned long long host_hz; - - void timer_irq(union uml_pt_regs *regs) - { -- int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu]; -+ unsigned long long ticks = 0; -+ -+ if(!timer_irq_inited){ -+ /* This is to ensure that ticks don't pile up when -+ * the timer handler is suspended */ -+ first_tick = 0; -+ return; -+ } - -- if(!timer_irq_inited) return; -- missed_ticks[cpu] = 0; -- while(ticks--) do_IRQ(TIMER_IRQ, regs); -+ if(first_tick){ -+#if defined(CONFIG_UML_REAL_TIME_CLOCK) -+ unsigned long long tsc; -+ /* We've had 1 tick */ -+ tsc = time_stamp(); -+ -+ delta += tsc - prev_tsc; -+ prev_tsc = tsc; -+ -+ ticks += (delta * HZ) / host_hz; -+ delta -= (ticks * host_hz) / HZ; -+#else -+ ticks = 1; -+#endif -+ } -+ else { -+ prev_tsc = time_stamp(); -+ first_tick = 1; -+ } -+ -+ while(ticks > 0){ -+ do_IRQ(TIMER_IRQ, regs); -+ ticks--; -+ } - } - - void boot_timer_handler(int sig) -@@ -58,12 +94,15 @@ void boot_timer_handler(int sig) - do_timer(®s); - } - --void um_timer(int irq, void *dev, struct pt_regs *regs) -+irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) - { -+ unsigned long flags; -+ - do_timer(regs); -- write_seqlock(&xtime_lock); -+ write_seqlock_irqsave(&xtime_lock, flags); - timer(); -- write_sequnlock(&xtime_lock); -+ write_sequnlock_irqrestore(&xtime_lock, flags); -+ return(IRQ_HANDLED); - } - - long um_time(int * tloc) -@@ -81,12 +120,12 @@ long um_time(int * tloc) - long um_stime(int * tptr) - { - int value; -- struct timeval new; -+ struct timespec new; - - if (get_user(value, tptr)) - return -EFAULT; - new.tv_sec = value; -- new.tv_usec = 0; -+ new.tv_nsec = 0; - do_settimeofday(&new); - return 0; - } -@@ -125,9 +164,11 @@ void __const_udelay(um_udelay_t usecs) - void timer_handler(int sig, union uml_pt_regs *regs) - { - #ifdef CONFIG_SMP -+ local_irq_disable(); - update_process_times(user_context(UPT_SP(regs))); -+ local_irq_enable(); - #endif -- if(current->thread_info->cpu == 0) -+ if(current_thread->cpu == 0) - timer_irq(regs); - } - -@@ -136,6 +177,7 @@ static spinlock_t timer_spinlock = SPIN_ - unsigned long time_lock(void) - { - unsigned long flags; -+ - spin_lock_irqsave(&timer_spinlock, flags); - return(flags); - } -@@ -150,8 +192,8 @@ int __init timer_init(void) - int err; - - CHOOSE_MODE(user_time_init_tt(), user_time_init_skas()); -- if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", -- NULL)) != 0) -+ err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); -+ if(err != 0) - printk(KERN_ERR "timer_init : request_irq failed - " - "errno = %d\n", -err); - timer_irq_inited = 1; -@@ -160,7 +202,6 @@ int __init timer_init(void) - - __initcall(timer_init); - -- - /* - * 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 -puN arch/um/kernel/trap_kern.c~Main-uml-patch-no-skas arch/um/kernel/trap_kern.c ---- uml-linux-2.6.7/arch/um/kernel/trap_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.590307744 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/trap_kern.c 2004-06-29 21:02:55.741284792 +0200 -@@ -16,12 +16,15 @@ - #include "asm/tlbflush.h" - #include "asm/a.out.h" - #include "asm/current.h" -+#include "asm/irq.h" - #include "user_util.h" - #include "kern_util.h" - #include "kern.h" - #include "chan_kern.h" - #include "mconsole_kern.h" - #include "2_5compat.h" -+#include "mem.h" -+#include "mem_kern.h" - - int handle_page_fault(unsigned long address, unsigned long ip, - int is_write, int is_user, int *code_out) -@@ -51,12 +54,12 @@ int handle_page_fault(unsigned long addr - if(is_write && !(vma->vm_flags & VM_WRITE)) - goto out; - page = address & PAGE_MASK; -- if(page == (unsigned long) current->thread_info + PAGE_SIZE) -+ if(page == (unsigned long) current_thread + PAGE_SIZE) - panic("Kernel stack overflow"); - pgd = pgd_offset(mm, page); - pmd = pmd_offset(pgd, page); -- survive: - do { -+ survive: - switch (handle_mm_fault(mm, vma, address, is_write)){ - case VM_FAULT_MINOR: - current->min_flt++; -@@ -71,14 +74,20 @@ int handle_page_fault(unsigned long addr - err = -ENOMEM; - goto out_of_memory; - default: -- BUG(); -+ if (current->pid == 1) { -+ up_read(&mm->mmap_sem); -+ yield(); -+ down_read(&mm->mmap_sem); -+ goto survive; -+ } -+ goto out; - } - pte = pte_offset_kernel(pmd, page); - } while(!pte_present(*pte)); -+ err = 0; - *pte = pte_mkyoung(*pte); - if(pte_write(*pte)) *pte = pte_mkdirty(*pte); - flush_tlb_page(vma, page); -- err = 0; - out: - up_read(&mm->mmap_sem); - return(err); -@@ -98,6 +107,33 @@ out_of_memory: - goto out; - } - -+LIST_HEAD(physmem_remappers); -+ -+void register_remapper(struct remapper *info) -+{ -+ list_add(&info->list, &physmem_remappers); -+} -+ -+static int check_remapped_addr(unsigned long address, int is_write) -+{ -+ struct remapper *remapper; -+ struct list_head *ele; -+ __u64 offset; -+ int fd; -+ -+ fd = phys_mapping(__pa(address), &offset); -+ if(fd == -1) -+ return(0); -+ -+ list_for_each(ele, &physmem_remappers){ -+ remapper = list_entry(ele, struct remapper, list); -+ if((*remapper->proc)(fd, address, is_write, offset)) -+ return(1); -+ } -+ -+ return(0); -+} -+ - unsigned long segv(unsigned long address, unsigned long ip, int is_write, - int is_user, void *sc) - { -@@ -109,7 +145,9 @@ unsigned long segv(unsigned long address - flush_tlb_kernel_vm(); - return(0); - } -- if(current->mm == NULL) -+ else if(check_remapped_addr(address & PAGE_MASK, is_write)) -+ return(0); -+ else if(current->mm == NULL) - panic("Segfault with no mm"); - err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); - -@@ -120,9 +158,8 @@ unsigned long segv(unsigned long address - current->thread.fault_addr = (void *) address; - do_longjmp(catcher, 1); - } -- else if(current->thread.fault_addr != NULL){ -+ else if(current->thread.fault_addr != NULL) - panic("fault_addr set but no fault catcher"); -- } - else if(arch_fixup(ip, sc)) - return(0); - -@@ -155,8 +192,6 @@ void bad_segv(unsigned long address, uns - { - struct siginfo si; - -- printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx " -- "(ip 0x%lx)\n", current->comm, current->pid, address, ip); - si.si_signo = SIGSEGV; - si.si_code = SEGV_ACCERR; - si.si_addr = (void *) address; -@@ -180,6 +215,11 @@ void bus_handler(int sig, union uml_pt_r - else relay_signal(sig, regs); - } - -+void winch(int sig, union uml_pt_regs *regs) -+{ -+ do_IRQ(WINCH_IRQ, regs); -+} -+ - void trap_init(void) - { - } -diff -puN arch/um/kernel/trap_user.c~Main-uml-patch-no-skas arch/um/kernel/trap_user.c ---- uml-linux-2.6.7/arch/um/kernel/trap_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.591307592 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/trap_user.c 2004-06-29 21:02:55.742284640 +0200 -@@ -5,11 +5,9 @@ - - #include <stdlib.h> - #include <errno.h> --#include <fcntl.h> - #include <setjmp.h> - #include <signal.h> - #include <sys/time.h> --#include <sys/ioctl.h> - #include <sys/ptrace.h> - #include <sys/wait.h> - #include <asm/page.h> -@@ -82,6 +80,8 @@ struct signal_info sig_info[] = { - .is_irq = 0 }, - [ SIGILL ] { .handler = relay_signal, - .is_irq = 0 }, -+ [ SIGWINCH ] { .handler = winch, -+ .is_irq = 1 }, - [ SIGBUS ] { .handler = bus_handler, - .is_irq = 0 }, - [ SIGSEGV] { .handler = segv_handler, -@@ -102,12 +102,11 @@ void sig_handler(int sig, struct sigcont - sig, &sc); - } - --extern int timer_irq_inited, missed_ticks[]; -+extern int timer_irq_inited; - - void alarm_handler(int sig, struct sigcontext sc) - { - if(!timer_irq_inited) return; -- missed_ticks[cpu()]++; - - if(sig == SIGALRM) - switch_timers(0); -@@ -123,7 +122,7 @@ void do_longjmp(void *b, int val) - { - jmp_buf *buf = b; - -- longjmp(*buf, val); -+ siglongjmp(*buf, val); - } - - /* -diff -puN arch/um/kernel/tt/exec_kern.c~Main-uml-patch-no-skas arch/um/kernel/tt/exec_kern.c ---- uml-linux-2.6.7/arch/um/kernel/tt/exec_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.592307440 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/exec_kern.c 2004-06-29 21:02:55.742284640 +0200 -@@ -17,6 +17,7 @@ - #include "mem_user.h" - #include "os.h" - #include "tlb.h" -+#include "mode.h" - - static int exec_tramp(void *sig_stack) - { -@@ -47,17 +48,17 @@ void flush_thread_tt(void) - do_exit(SIGKILL); - } - -- if(current->thread_info->cpu == 0) -+ if(current_thread->cpu == 0) - forward_interrupts(new_pid); - current->thread.request.op = OP_EXEC; - current->thread.request.u.exec.pid = new_pid; -- unprotect_stack((unsigned long) current->thread_info); -+ unprotect_stack((unsigned long) current_thread); - os_usr1_process(os_getpid()); - - enable_timer(); - free_page(stack); - protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1); -- task_protections((unsigned long) current->thread_info); -+ task_protections((unsigned long) current_thread); - force_flush_all(); - unblock_signals(); - } -diff -puN arch/um/kernel/tt/include/mode.h~Main-uml-patch-no-skas arch/um/kernel/tt/include/mode.h ---- uml-linux-2.6.7/arch/um/kernel/tt/include/mode.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.593307288 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/include/mode.h 2004-06-29 21:02:55.742284640 +0200 -@@ -8,6 +8,8 @@ - - #include "sysdep/ptrace.h" - -+enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; -+ - extern int tracing_pid; - - extern int tracer(int (*init_proc)(void *), void *sp); -diff -puN arch/um/kernel/tt/include/uaccess.h~Main-uml-patch-no-skas arch/um/kernel/tt/include/uaccess.h ---- uml-linux-2.6.7/arch/um/kernel/tt/include/uaccess.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.594307136 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/include/uaccess.h 2004-06-29 21:02:55.743284488 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -43,65 +43,19 @@ extern unsigned long get_fault_addr(void - - extern int __do_copy_from_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher); -- --static inline int copy_from_user_tt(void *to, const void *from, int n) --{ -- return(access_ok_tt(VERIFY_READ, from, n) ? -- __do_copy_from_user(to, from, n, -- ¤t->thread.fault_addr, -- ¤t->thread.fault_catcher) : n); --} -- --static inline int copy_to_user_tt(void *to, const void *from, int n) --{ -- return(access_ok_tt(VERIFY_WRITE, to, n) ? -- __do_copy_to_user(to, from, n, -- ¤t->thread.fault_addr, -- ¤t->thread.fault_catcher) : n); --} -- - extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, - void **fault_addr, void **fault_catcher); -- --static inline int strncpy_from_user_tt(char *dst, const char *src, int count) --{ -- int n; -- -- if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT); -- n = __do_strncpy_from_user(dst, src, count, -- ¤t->thread.fault_addr, -- ¤t->thread.fault_catcher); -- if(n < 0) return(-EFAULT); -- return(n); --} -- - extern int __do_clear_user(void *mem, size_t len, void **fault_addr, - void **fault_catcher); -- --static inline int __clear_user_tt(void *mem, int len) --{ -- return(__do_clear_user(mem, len, -- ¤t->thread.fault_addr, -- ¤t->thread.fault_catcher)); --} -- --static inline int clear_user_tt(void *mem, int len) --{ -- return(access_ok_tt(VERIFY_WRITE, mem, len) ? -- __do_clear_user(mem, len, -- ¤t->thread.fault_addr, -- ¤t->thread.fault_catcher) : len); --} -- - extern int __do_strnlen_user(const char *str, unsigned long n, - void **fault_addr, void **fault_catcher); - --static inline int strnlen_user_tt(const void *str, int len) --{ -- return(__do_strnlen_user(str, len, -- ¤t->thread.fault_addr, -- ¤t->thread.fault_catcher)); --} -+extern int copy_from_user_tt(void *to, const void *from, int n); -+extern int copy_to_user_tt(void *to, const void *from, int n); -+extern int strncpy_from_user_tt(char *dst, const char *src, int count); -+extern int __clear_user_tt(void *mem, int len); -+extern int clear_user_tt(void *mem, int len); -+extern int strnlen_user_tt(const void *str, int len); - - #endif - -diff -puN arch/um/kernel/tt/Makefile~Main-uml-patch-no-skas arch/um/kernel/tt/Makefile ---- uml-linux-2.6.7/arch/um/kernel/tt/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.595306984 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/Makefile 2004-06-29 21:02:55.743284488 +0200 -@@ -1,5 +1,5 @@ - # --# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) - # Licensed under the GPL - # - -@@ -7,7 +7,7 @@ extra-y := unmap_fin.o - - obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ - syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ -- uaccess_user.o sys-$(SUBARCH)/ -+ uaccess.o uaccess_user.o sys-$(SUBARCH)/ - - obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ - -@@ -27,5 +27,3 @@ $(obj)/unmap.o: $(src)/unmap.c - - $(obj)/unmap_fin.o : $(src)/unmap.o - ld -r -o $@ $< -lc -L/usr/lib -- --clean : -diff -puN arch/um/kernel/tt/mem_user.c~Main-uml-patch-no-skas arch/um/kernel/tt/mem_user.c ---- uml-linux-2.6.7/arch/um/kernel/tt/mem_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.597306680 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/mem_user.c 2004-06-29 21:02:55.743284488 +0200 -@@ -25,14 +25,13 @@ void remap_data(void *segment_start, voi - size = (unsigned long) segment_end - - (unsigned long) segment_start; - data = create_mem_file(size); -- if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, -- MAP_SHARED, data, 0)) == MAP_FAILED){ -+ addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0); -+ if(addr == MAP_FAILED){ - perror("mapping new data segment"); - exit(1); - } - memcpy(addr, segment_start, size); -- if(switcheroo(data, prot, addr, segment_start, -- size) < 0){ -+ if(switcheroo(data, prot, addr, segment_start, size) < 0){ - printf("switcheroo failed\n"); - exit(1); - } -diff -puN arch/um/kernel/tt/process_kern.c~Main-uml-patch-no-skas arch/um/kernel/tt/process_kern.c ---- uml-linux-2.6.7/arch/um/kernel/tt/process_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.598306528 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/process_kern.c 2004-06-29 21:02:55.744284336 +0200 -@@ -62,7 +62,7 @@ void *switch_to_tt(void *prev, void *nex - reading = 0; - err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); - if(err != sizeof(c)) -- panic("write of switch_pipe failed, errno = %d", -err); -+ panic("write of switch_pipe failed, err = %d", -err); - - reading = 1; - if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD)) -@@ -104,48 +104,72 @@ void *switch_to_tt(void *prev, void *nex - - void release_thread_tt(struct task_struct *task) - { -- os_kill_process(task->thread.mode.tt.extern_pid, 0); -+ int pid = task->thread.mode.tt.extern_pid; -+ -+ if(os_getpid() != pid) -+ os_kill_process(pid, 0); - } - - void exit_thread_tt(void) - { -- close(current->thread.mode.tt.switch_pipe[0]); -- close(current->thread.mode.tt.switch_pipe[1]); -+ os_close_file(current->thread.mode.tt.switch_pipe[0]); -+ os_close_file(current->thread.mode.tt.switch_pipe[1]); - } - - void schedule_tail(task_t *prev); - - static void new_thread_handler(int sig) - { -+ unsigned long disable; - int (*fn)(void *); - void *arg; - - fn = current->thread.request.u.thread.proc; - arg = current->thread.request.u.thread.arg; -+ - UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); -+ disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) | -+ (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1)); -+ SC_SIGMASK(UPT_SC(¤t->thread.regs.regs)) &= ~disable; -+ - suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); - -- block_signals(); -+ force_flush_all(); -+ if(current->thread.prev_sched != NULL) -+ schedule_tail(current->thread.prev_sched); -+ current->thread.prev_sched = NULL; -+ - init_new_thread_signals(1); --#ifdef CONFIG_SMP -- schedule_tail(current->thread.prev_sched); --#endif - enable_timer(); - free_page(current->thread.temp_stack); - set_cmdline("(kernel thread)"); -- force_flush_all(); - -- current->thread.prev_sched = NULL; - change_sig(SIGUSR1, 1); - change_sig(SIGVTALRM, 1); - change_sig(SIGPROF, 1); -- unblock_signals(); -+ local_irq_enable(); - if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf)) - do_exit(0); - } - - static int new_thread_proc(void *stack) - { -+ /* local_irq_disable is needed to block out signals until this thread is -+ * properly scheduled. Otherwise, the tracing thread will get mighty -+ * upset about any signals that arrive before that. -+ * This has the complication that it sets the saved signal mask in -+ * the sigcontext to block signals. This gets restored when this -+ * thread (or a descendant, since they get a copy of this sigcontext) -+ * returns to userspace. -+ * So, this is compensated for elsewhere. -+ * XXX There is still a small window until local_irq_disable() actually -+ * finishes where signals are possible - shouldn't be a problem in -+ * practice since SIGIO hasn't been forwarded here yet, and the -+ * local_irq_disable should finish before a SIGVTALRM has time to be -+ * delivered. -+ */ -+ -+ local_irq_disable(); - init_new_thread_stack(stack, new_thread_handler); - os_usr1_process(os_getpid()); - return(0); -@@ -156,7 +180,7 @@ static int new_thread_proc(void *stack) - * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off, - * so it is blocked before it's called. They are re-enabled on sigreturn - * despite the fact that they were blocked when the SIGUSR1 was issued because -- * copy_thread copies the parent's signcontext, including the signal mask -+ * copy_thread copies the parent's sigcontext, including the signal mask - * onto the signal frame. - */ - -@@ -165,35 +189,32 @@ void finish_fork_handler(int sig) - UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); - suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); - --#ifdef CONFIG_SMP -- schedule_tail(NULL); --#endif -+ force_flush_all(); -+ if(current->thread.prev_sched != NULL) -+ schedule_tail(current->thread.prev_sched); -+ current->thread.prev_sched = NULL; -+ - enable_timer(); - change_sig(SIGVTALRM, 1); - local_irq_enable(); -- force_flush_all(); - if(current->mm != current->parent->mm) - protect_memory(uml_reserved, high_physmem - uml_reserved, 1, - 1, 0, 1); -- task_protections((unsigned long) current->thread_info); -- -- current->thread.prev_sched = NULL; -+ task_protections((unsigned long) current_thread); - - free_page(current->thread.temp_stack); -+ local_irq_disable(); - change_sig(SIGUSR1, 0); - set_user_mode(current); - } - --static int sigusr1 = SIGUSR1; -- - int fork_tramp(void *stack) - { -- int sig = sigusr1; -- - local_irq_disable(); -+ arch_init_thread(); - init_new_thread_stack(stack, finish_fork_handler); - -- kill(os_getpid(), sig); -+ os_usr1_process(os_getpid()); - return(0); - } - -@@ -213,8 +234,8 @@ int copy_thread_tt(int nr, unsigned long - } - - err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1); -- if(err){ -- printk("copy_thread : pipe failed, errno = %d\n", -err); -+ if(err < 0){ -+ printk("copy_thread : pipe failed, err = %d\n", -err); - return(err); - } - -@@ -377,8 +398,8 @@ static void mprotect_kernel_mem(int w) - - pages = (1 << CONFIG_KERNEL_STACK_ORDER); - -- start = (unsigned long) current->thread_info + PAGE_SIZE; -- end = (unsigned long) current + PAGE_SIZE * pages; -+ start = (unsigned long) current_thread + PAGE_SIZE; -+ end = (unsigned long) current_thread + PAGE_SIZE * pages; - protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1); - protect_memory(end, high_physmem - end, 1, w, 1, 1); - -@@ -454,8 +475,9 @@ void set_init_pid(int pid) - - init_task.thread.mode.tt.extern_pid = pid; - err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1); -- if(err) panic("Can't create switch pipe for init_task, errno = %d", -- err); -+ if(err) -+ panic("Can't create switch pipe for init_task, errno = %d", -+ -err); - } - - int singlestepping_tt(void *t) -diff -puN arch/um/kernel/tt/ptproxy/Makefile~Main-uml-patch-no-skas arch/um/kernel/tt/ptproxy/Makefile ---- uml-linux-2.6.7/arch/um/kernel/tt/ptproxy/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.599306376 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/Makefile 2004-06-29 21:02:55.744284336 +0200 -@@ -9,5 +9,3 @@ USER_OBJS := $(foreach file,$(obj-y),$(s - - $(USER_OBJS) : %.o: %.c - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -- --clean: -diff -puN arch/um/kernel/tt/ptproxy/proxy.c~Main-uml-patch-no-skas arch/um/kernel/tt/ptproxy/proxy.c ---- uml-linux-2.6.7/arch/um/kernel/tt/ptproxy/proxy.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.600306224 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/proxy.c 2004-06-29 21:02:55.744284336 +0200 -@@ -15,7 +15,6 @@ Jeff Dike (jdike@karaya.com) : Modified - #include <unistd.h> - #include <signal.h> - #include <string.h> --#include <fcntl.h> - #include <termios.h> - #include <sys/wait.h> - #include <sys/types.h> -@@ -293,10 +292,10 @@ void fake_child_exit(void) - } - - char gdb_init_string[] = --"att 1 --b panic --b stop --handle SIGWINCH nostop noprint pass -+"att 1 \n\ -+b panic \n\ -+b stop \n\ -+handle SIGWINCH nostop noprint pass \n\ - "; - - int start_debugger(char *prog, int startup, int stop, int *fd_out) -@@ -304,7 +303,8 @@ int start_debugger(char *prog, int start - int slave, child; - - slave = open_gdb_chan(); -- if((child = fork()) == 0){ -+ child = fork(); -+ if(child == 0){ - char *tempname = NULL; - int fd; - -@@ -327,18 +327,19 @@ int start_debugger(char *prog, int start - exit(1); - #endif - } -- if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){ -- printk("start_debugger : make_tempfile failed, errno = %d\n", -- errno); -+ fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0); -+ if(fd < 0){ -+ printk("start_debugger : make_tempfile failed," -+ "err = %d\n", -fd); - exit(1); - } -- write(fd, gdb_init_string, sizeof(gdb_init_string) - 1); -+ os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1); - if(startup){ - if(stop){ -- write(fd, "b start_kernel\n", -+ os_write_file(fd, "b start_kernel\n", - strlen("b start_kernel\n")); - } -- write(fd, "c\n", strlen("c\n")); -+ os_write_file(fd, "c\n", strlen("c\n")); - } - if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ - printk("start_debugger : PTRACE_TRACEME failed, " -diff -puN arch/um/kernel/tt/ptproxy/sysdep.c~Main-uml-patch-no-skas arch/um/kernel/tt/ptproxy/sysdep.c ---- uml-linux-2.6.7/arch/um/kernel/tt/ptproxy/sysdep.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.601306072 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/sysdep.c 2004-06-29 21:02:55.744284336 +0200 -@@ -9,6 +9,7 @@ terms and conditions. - #include <string.h> - #include <stdlib.h> - #include <signal.h> -+#include <errno.h> - #include <sys/types.h> - #include <sys/ptrace.h> - #include <asm/ptrace.h> -diff -puN arch/um/kernel/tt/ptproxy/wait.c~Main-uml-patch-no-skas arch/um/kernel/tt/ptproxy/wait.c ---- uml-linux-2.6.7/arch/um/kernel/tt/ptproxy/wait.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.602305920 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/ptproxy/wait.c 2004-06-29 21:02:55.745284184 +0200 -@@ -56,21 +56,23 @@ int parent_wait_return(struct debugger * - int real_wait_return(struct debugger *debugger) - { - unsigned long ip; -- int err, pid; -+ int pid; - - pid = debugger->pid; -+ - ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0); -- ip = IP_RESTART_SYSCALL(ip); -- err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip); -+ IP_RESTART_SYSCALL(ip); -+ - if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0) - tracer_panic("real_wait_return : Failed to restart system " -- "call, errno = %d\n"); -+ "call, errno = %d\n", errno); -+ - if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) || - (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) || - (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) || - debugger_normal_return(debugger, -1)) - tracer_panic("real_wait_return : gdb failed to wait, " -- "errno = %d\n"); -+ "errno = %d\n", errno); - return(0); - } - -diff -puN arch/um/kernel/tt/syscall_kern.c~Main-uml-patch-no-skas arch/um/kernel/tt/syscall_kern.c ---- uml-linux-2.6.7/arch/um/kernel/tt/syscall_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.603305768 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/syscall_kern.c 2004-06-29 21:02:55.745284184 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -diff -puN arch/um/kernel/tt/syscall_user.c~Main-uml-patch-no-skas arch/um/kernel/tt/syscall_user.c ---- uml-linux-2.6.7/arch/um/kernel/tt/syscall_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.604305616 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/syscall_user.c 2004-06-29 21:02:55.745284184 +0200 -@@ -33,7 +33,7 @@ void syscall_handler_tt(int sig, union u - SC_START_SYSCALL(sc); - - index = record_syscall_start(syscall); -- syscall_trace(); -+ syscall_trace(regs, 1); - result = execute_syscall(regs); - - /* regs->sc may have changed while the system call ran (there may -@@ -46,7 +46,7 @@ void syscall_handler_tt(int sig, union u - (result == -ERESTARTNOINTR)) - do_signal(result); - -- syscall_trace(); -+ syscall_trace(regs, 0); - record_syscall_end(index, result); - } - -diff -puN arch/um/kernel/tt/sys-i386/Makefile~Main-uml-patch-no-skas arch/um/kernel/tt/sys-i386/Makefile ---- uml-linux-2.6.7/arch/um/kernel/tt/sys-i386/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.605305464 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/sys-i386/Makefile 2004-06-29 21:02:55.745284184 +0200 -@@ -10,5 +10,3 @@ USER_OBJS := $(foreach file,$(USER_OBJS) - - $(USER_OBJS) : %.o: %.c - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -- --clean : -diff -puN arch/um/kernel/tt/tlb.c~Main-uml-patch-no-skas arch/um/kernel/tt/tlb.c ---- uml-linux-2.6.7/arch/um/kernel/tt/tlb.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.606305312 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/tlb.c 2004-06-29 21:02:55.746284032 +0200 -@@ -10,6 +10,7 @@ - #include "asm/page.h" - #include "asm/pgtable.h" - #include "asm/uaccess.h" -+#include "asm/tlbflush.h" - #include "user_util.h" - #include "mem_user.h" - #include "os.h" -diff -puN arch/um/kernel/tt/tracer.c~Main-uml-patch-no-skas arch/um/kernel/tt/tracer.c ---- uml-linux-2.6.7/arch/um/kernel/tt/tracer.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.608305008 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/tracer.c 2004-06-29 21:02:55.746284032 +0200 -@@ -39,16 +39,17 @@ int is_tracer_winch(int pid, int fd, voi - return(0); - - register_winch_irq(tracer_winch[0], fd, -1, data); -- return(0); -+ return(1); - } - - static void tracer_winch_handler(int sig) - { -+ int n; - char c = 1; - -- if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c)) -- printk("tracer_winch_handler - write failed, errno = %d\n", -- errno); -+ n = os_write_file(tracer_winch[1], &c, sizeof(c)); -+ if(n != sizeof(c)) -+ printk("tracer_winch_handler - write failed, err = %d\n", -n); - } - - /* Called only by the tracing thread during initialization */ -@@ -58,9 +59,8 @@ static void setup_tracer_winch(void) - int err; - - err = os_pipe(tracer_winch, 1, 1); -- if(err){ -- printk("setup_tracer_winch : os_pipe failed, errno = %d\n", -- -err); -+ if(err < 0){ -+ printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err); - return; - } - signal(SIGWINCH, tracer_winch_handler); -@@ -130,8 +130,8 @@ static void sleeping_process_signal(int - case SIGTSTP: - if(ptrace(PTRACE_CONT, pid, 0, sig) < 0) - tracer_panic("sleeping_process_signal : Failed to " -- "continue pid %d, errno = %d\n", pid, -- sig); -+ "continue pid %d, signal = %d, " -+ "errno = %d\n", pid, sig, errno); - break; - - /* This happens when the debugger (e.g. strace) is doing system call -@@ -145,7 +145,7 @@ static void sleeping_process_signal(int - if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) - tracer_panic("sleeping_process_signal : Failed to " - "PTRACE_SYSCALL pid %d, errno = %d\n", -- pid, sig); -+ pid, errno); - break; - case SIGSTOP: - break; -@@ -218,7 +218,7 @@ int tracer(int (*init_proc)(void *), voi - err = attach(debugger_parent); - if(err){ - printf("Failed to attach debugger parent %d, " -- "errno = %d\n", debugger_parent, err); -+ "errno = %d\n", debugger_parent, -err); - debugger_parent = -1; - } - else { -@@ -233,7 +233,8 @@ int tracer(int (*init_proc)(void *), voi - } - set_cmdline("(tracing thread)"); - while(1){ -- if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){ -+ pid = waitpid(-1, &status, WUNTRACED); -+ if(pid <= 0){ - if(errno != ECHILD){ - printf("wait failed - errno = %d\n", errno); - } -@@ -401,7 +402,7 @@ static int __init uml_debug_setup(char * - - if(!strcmp(line, "go")) debug_stop = 0; - else if(!strcmp(line, "parent")) debug_parent = 1; -- else printk("Unknown debug option : '%s'\n", line); -+ else printf("Unknown debug option : '%s'\n", line); - - line = next; - } -diff -puN /dev/null arch/um/kernel/tt/uaccess.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/uaccess.c 2004-06-29 21:02:55.746284032 +0200 -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "asm/uaccess.h" -+ -+int copy_from_user_tt(void *to, const void *from, int n) -+{ -+ if(!access_ok_tt(VERIFY_READ, from, n)) -+ return(n); -+ -+ return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int copy_to_user_tt(void *to, const void *from, int n) -+{ -+ if(!access_ok_tt(VERIFY_WRITE, to, n)) -+ return(n); -+ -+ return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int strncpy_from_user_tt(char *dst, const char *src, int count) -+{ -+ int n; -+ -+ if(!access_ok_tt(VERIFY_READ, src, 1)) -+ return(-EFAULT); -+ -+ n = __do_strncpy_from_user(dst, src, count, -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher); -+ if(n < 0) return(-EFAULT); -+ return(n); -+} -+ -+int __clear_user_tt(void *mem, int len) -+{ -+ return(__do_clear_user(mem, len, -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int clear_user_tt(void *mem, int len) -+{ -+ if(!access_ok_tt(VERIFY_WRITE, mem, len)) -+ return(len); -+ -+ return(__do_clear_user(mem, len, ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int strnlen_user_tt(const void *str, int len) -+{ -+ return(__do_strnlen_user(str, len, -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+/* -+ * 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 -puN arch/um/kernel/tt/uaccess_user.c~Main-uml-patch-no-skas arch/um/kernel/tt/uaccess_user.c ---- uml-linux-2.6.7/arch/um/kernel/tt/uaccess_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.609304856 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/uaccess_user.c 2004-06-29 21:02:55.747283880 +0200 -@@ -8,15 +8,20 @@ - #include <string.h> - #include "user_util.h" - #include "uml_uaccess.h" -+#include "task.h" -+#include "kern_util.h" - - int __do_copy_from_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher) - { -+ struct tt_regs save = TASK_REGS(get_current())->tt; - unsigned long fault; - int faulted; - - fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, - __do_copy, &faulted); -+ TASK_REGS(get_current())->tt = save; -+ - if(!faulted) return(0); - else return(n - (fault - (unsigned long) from)); - } -@@ -29,11 +34,14 @@ static void __do_strncpy(void *dst, cons - int __do_strncpy_from_user(char *dst, const char *src, unsigned long count, - void **fault_addr, void **fault_catcher) - { -+ struct tt_regs save = TASK_REGS(get_current())->tt; - unsigned long fault; - int faulted; - - fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher, - __do_strncpy, &faulted); -+ TASK_REGS(get_current())->tt = save; -+ - if(!faulted) return(strlen(dst)); - else return(-1); - } -@@ -46,11 +54,14 @@ static void __do_clear(void *to, const v - int __do_clear_user(void *mem, unsigned long len, - void **fault_addr, void **fault_catcher) - { -+ struct tt_regs save = TASK_REGS(get_current())->tt; - unsigned long fault; - int faulted; - - fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher, - __do_clear, &faulted); -+ TASK_REGS(get_current())->tt = save; -+ - if(!faulted) return(0); - else return(len - (fault - (unsigned long) mem)); - } -@@ -58,19 +69,20 @@ int __do_clear_user(void *mem, unsigned - int __do_strnlen_user(const char *str, unsigned long n, - void **fault_addr, void **fault_catcher) - { -+ struct tt_regs save = TASK_REGS(get_current())->tt; - int ret; - unsigned long *faddrp = (unsigned long *)fault_addr; - jmp_buf jbuf; - - *fault_catcher = &jbuf; -- if(setjmp(jbuf) == 0){ -+ if(sigsetjmp(jbuf, 1) == 0) - ret = strlen(str) + 1; -- } -- else { -- ret = *faddrp - (unsigned long) str; -- } -+ else ret = *faddrp - (unsigned long) str; -+ - *fault_addr = NULL; - *fault_catcher = NULL; -+ -+ TASK_REGS(get_current())->tt = save; - return ret; - } - -diff -puN arch/um/kernel/tt/unmap.c~Main-uml-patch-no-skas arch/um/kernel/tt/unmap.c ---- uml-linux-2.6.7/arch/um/kernel/tt/unmap.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.610304704 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/unmap.c 2004-06-29 21:02:55.747283880 +0200 -@@ -3,10 +3,7 @@ - * Licensed under the GPL - */ - --#include <stdio.h> --#include <errno.h> - #include <sys/mman.h> --#include "user.h" - - int switcheroo(int fd, int prot, void *from, void *to, int size) - { -diff -puN arch/um/kernel/tty_log.c~Main-uml-patch-no-skas arch/um/kernel/tty_log.c ---- uml-linux-2.6.7/arch/um/kernel/tty_log.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.611304552 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tty_log.c 2004-06-29 21:02:55.747283880 +0200 -@@ -9,10 +9,10 @@ - #include <stdio.h> - #include <stdlib.h> - #include <unistd.h> --#include <fcntl.h> - #include <sys/time.h> - #include "init.h" - #include "user.h" -+#include "kern_util.h" - #include "os.h" - - #define TTY_LOG_DIR "./" -@@ -24,29 +24,40 @@ static int tty_log_fd = -1; - #define TTY_LOG_OPEN 1 - #define TTY_LOG_CLOSE 2 - #define TTY_LOG_WRITE 3 -+#define TTY_LOG_EXEC 4 -+ -+#define TTY_READ 1 -+#define TTY_WRITE 2 - - struct tty_log_buf { - int what; - unsigned long tty; - int len; -+ int direction; -+ unsigned long sec; -+ unsigned long usec; - }; - --int open_tty_log(void *tty) -+int open_tty_log(void *tty, void *current_tty) - { - struct timeval tv; - struct tty_log_buf data; - char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")]; - int fd; - -+ gettimeofday(&tv, NULL); - if(tty_log_fd != -1){ -- data = ((struct tty_log_buf) { what : TTY_LOG_OPEN, -- tty : (unsigned long) tty, -- len : 0 }); -- write(tty_log_fd, &data, sizeof(data)); -+ data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN, -+ .tty = (unsigned long) tty, -+ .len = sizeof(current_tty), -+ .direction = 0, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); -+ os_write_file(tty_log_fd, ¤t_tty, data.len); - return(tty_log_fd); - } - -- gettimeofday(&tv, NULL); - sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, - (unsigned int) tv.tv_usec); - -@@ -62,30 +73,117 @@ int open_tty_log(void *tty) - void close_tty_log(int fd, void *tty) - { - struct tty_log_buf data; -+ struct timeval tv; - - if(tty_log_fd != -1){ -- data = ((struct tty_log_buf) { what : TTY_LOG_CLOSE, -- tty : (unsigned long) tty, -- len : 0 }); -- write(tty_log_fd, &data, sizeof(data)); -+ gettimeofday(&tv, NULL); -+ data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE, -+ .tty = (unsigned long) tty, -+ .len = 0, -+ .direction = 0, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); - return; - } -- close(fd); -+ os_close_file(fd); - } - --int write_tty_log(int fd, char *buf, int len, void *tty) -+static int log_chunk(int fd, const char *buf, int len) - { -+ int total = 0, try, missed, n; -+ char chunk[64]; -+ -+ while(len > 0){ -+ try = (len > sizeof(chunk)) ? sizeof(chunk) : len; -+ missed = copy_from_user_proc(chunk, (char *) buf, try); -+ try -= missed; -+ n = os_write_file(fd, chunk, try); -+ if(n != try) { -+ if(n < 0) -+ return(n); -+ return(-EIO); -+ } -+ if(missed != 0) -+ return(-EFAULT); -+ -+ len -= try; -+ total += try; -+ buf += try; -+ } -+ -+ return(total); -+} -+ -+int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) -+{ -+ struct timeval tv; - struct tty_log_buf data; -+ int direction; - - if(fd == tty_log_fd){ -- data = ((struct tty_log_buf) { what : TTY_LOG_WRITE, -- tty : (unsigned long) tty, -- len : len }); -- write(tty_log_fd, &data, sizeof(data)); -+ gettimeofday(&tv, NULL); -+ direction = is_read ? TTY_READ : TTY_WRITE; -+ data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE, -+ .tty = (unsigned long) tty, -+ .len = len, -+ .direction = direction, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); - } -- return(write(fd, buf, len)); -+ -+ return(log_chunk(fd, buf, len)); - } - -+void log_exec(char **argv, void *tty) -+{ -+ struct timeval tv; -+ struct tty_log_buf data; -+ char **ptr,*arg; -+ int len; -+ -+ if(tty_log_fd == -1) return; -+ -+ gettimeofday(&tv, NULL); -+ -+ len = 0; -+ for(ptr = argv; ; ptr++){ -+ if(copy_from_user_proc(&arg, ptr, sizeof(arg))) -+ return; -+ if(arg == NULL) break; -+ len += strlen_user_proc(arg); -+ } -+ -+ data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC, -+ .tty = (unsigned long) tty, -+ .len = len, -+ .direction = 0, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); -+ -+ for(ptr = argv; ; ptr++){ -+ if(copy_from_user_proc(&arg, ptr, sizeof(arg))) -+ return; -+ if(arg == NULL) break; -+ log_chunk(tty_log_fd, arg, strlen_user_proc(arg)); -+ } -+} -+ -+extern void register_tty_logger(int (*opener)(void *, void *), -+ int (*writer)(int, const char *, int, -+ void *, int), -+ void (*closer)(int, void *)); -+ -+static int register_logger(void) -+{ -+ register_tty_logger(open_tty_log, write_tty_log, close_tty_log); -+ return(0); -+} -+ -+__uml_initcall(register_logger); -+ - static int __init set_tty_log_dir(char *name, int *add) - { - tty_log_dir = name; -@@ -104,7 +202,7 @@ static int __init set_tty_log_fd(char *n - - tty_log_fd = strtoul(name, &end, 0); - if((*end != '\0') || (end == name)){ -- printk("set_tty_log_fd - strtoul failed on '%s'\n", name); -+ printf("set_tty_log_fd - strtoul failed on '%s'\n", name); - tty_log_fd = -1; - } - return 0; -diff -puN arch/um/kernel/uaccess_user.c~Main-uml-patch-no-skas arch/um/kernel/uaccess_user.c ---- uml-linux-2.6.7/arch/um/kernel/uaccess_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.612304400 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/uaccess_user.c 2004-06-29 21:02:55.747283880 +0200 -@@ -20,7 +20,7 @@ unsigned long __do_user_copy(void *to, c - - jmp_buf jbuf; - *fault_catcher = &jbuf; -- if(setjmp(jbuf) == 0){ -+ if(sigsetjmp(jbuf, 1) == 0){ - (*op)(to, from, n); - ret = 0; - *faulted_out = 0; -diff -puN arch/um/kernel/um_arch.c~Main-uml-patch-no-skas arch/um/kernel/um_arch.c ---- uml-linux-2.6.7/arch/um/kernel/um_arch.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.614304096 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/um_arch.c 2004-06-29 21:02:55.748283728 +0200 -@@ -38,13 +38,18 @@ - #include "mode_kern.h" - #include "mode.h" - --#define DEFAULT_COMMAND_LINE "root=6200" -+#define DEFAULT_COMMAND_LINE "root=98:0" - - struct cpuinfo_um boot_cpu_data = { - .loops_per_jiffy = 0, - .ipi_pipe = { -1, -1 } - }; - -+/* Placeholder to make UML link until the vsyscall stuff is actually -+ * implemented -+ */ -+void *__kernel_vsyscall; -+ - unsigned long thread_saved_pc(struct task_struct *task) - { - return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, -@@ -53,18 +58,22 @@ unsigned long thread_saved_pc(struct tas - - static int show_cpuinfo(struct seq_file *m, void *v) - { -- int index; -+ int index = 0; - -- index = (struct cpuinfo_um *)v - cpu_data; - #ifdef CONFIG_SMP -+ index = (struct cpuinfo_um *) v - cpu_data; - if (!cpu_online(index)) - return 0; - #endif - -- seq_printf(m, "bogomips\t: %lu.%02lu\n", -+ seq_printf(m, "processor\t: %d\n", index); -+ seq_printf(m, "vendor_id\t: User Mode Linux\n"); -+ seq_printf(m, "model name\t: UML\n"); -+ seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas")); -+ seq_printf(m, "host\t\t: %s\n", host_info); -+ seq_printf(m, "bogomips\t: %lu.%02lu\n\n", - loops_per_jiffy/(500000/HZ), - (loops_per_jiffy/(5000/HZ)) % 100); -- seq_printf(m, "host\t\t: %s\n", host_info); - - return(0); - } -@@ -134,12 +143,12 @@ void set_cmdline(char *cmd) - if(umid != NULL){ - snprintf(argv1_begin, - (argv1_end - argv1_begin) * sizeof(*ptr), -- "(%s)", umid); -+ "(%s) ", umid); - ptr = &argv1_begin[strlen(argv1_begin)]; - } - else ptr = argv1_begin; - -- snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd); -+ snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd); - memset(argv1_begin + strlen(argv1_begin), '\0', - argv1_end - argv1_begin - strlen(argv1_begin)); - #endif -@@ -179,7 +188,7 @@ __uml_setup("root=", uml_root_setup, - static int __init uml_ncpus_setup(char *line, int *add) - { - if (!sscanf(line, "%d", &ncpus)) { -- printk("Couldn't parse [%s]\n", line); -+ printf("Couldn't parse [%s]\n", line); - return -1; - } - -@@ -210,7 +219,7 @@ static int __init mode_tt_setup(char *li - - static int __init mode_tt_setup(char *line, int *add) - { -- printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); -+ printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); - return(0); - } - -@@ -221,7 +230,7 @@ static int __init mode_tt_setup(char *li - - static int __init mode_tt_setup(char *line, int *add) - { -- printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); -+ printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); - return(0); - } - -@@ -291,7 +300,7 @@ static void __init uml_postsetup(void) - - /* Set during early boot */ - unsigned long brk_start; --static struct vm_reserved kernel_vm_reserved; -+unsigned long end_iomem; - - #define MIN_VMALLOC (32 * 1024 * 1024) - -@@ -299,7 +308,7 @@ int linux_main(int argc, char **argv) - { - unsigned long avail; - unsigned long virtmem_size, max_physmem; -- unsigned int i, add, err; -+ unsigned int i, add; - - for (i = 1; i < argc; i++){ - if((i == 1) && (argv[i][0] == ' ')) continue; -@@ -328,12 +337,16 @@ int linux_main(int argc, char **argv) - argv1_end = &argv[1][strlen(argv[1])]; - #endif - -- set_usable_vm(uml_physmem, get_kmem_end()); -- - highmem = 0; -- max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC; -- if(physmem_size > max_physmem){ -- highmem = physmem_size - max_physmem; -+ iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; -+ max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; -+ -+ /* Zones have to begin on a 1 << MAX_ORDER page boundary, -+ * so this makes sure that's true for highmem -+ */ -+ max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); -+ if(physmem_size + iomem_size > max_physmem){ -+ highmem = physmem_size + iomem_size - max_physmem; - physmem_size -= highmem; - #ifndef CONFIG_HIGHMEM - highmem = 0; -@@ -343,11 +356,19 @@ int linux_main(int argc, char **argv) - } - - high_physmem = uml_physmem + physmem_size; -- high_memory = (void *) high_physmem; -+ end_iomem = high_physmem + iomem_size; -+ high_memory = (void *) end_iomem; - - start_vm = VMALLOC_START; - -- setup_physmem(uml_physmem, uml_reserved, physmem_size); -+ setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); -+ if(init_maps(physmem_size, iomem_size, highmem)){ -+ printf("Failed to allocate mem_map for %ld bytes of physical " -+ "memory and %ld bytes of highmem\n", physmem_size, -+ highmem); -+ exit(1); -+ } -+ - virtmem_size = physmem_size; - avail = get_kmem_end() - start_vm; - if(physmem_size > avail) virtmem_size = avail; -@@ -357,28 +378,26 @@ int linux_main(int argc, char **argv) - printf("Kernel virtual memory size shrunk to %ld bytes\n", - virtmem_size); - -- err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved); -- if(err){ -- printf("Failed to reserve VM area for kernel VM\n"); -- exit(1); -- } -- - uml_postsetup(); - - init_task.thread.kernel_stack = (unsigned long) &init_thread_info + - 2 * PAGE_SIZE; - - task_protections((unsigned long) &init_thread_info); -+ os_flush_stdout(); - - return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); - } - -+extern int uml_exitcode; -+ - static int panic_exit(struct notifier_block *self, unsigned long unused1, - void *unused2) - { - #ifdef CONFIG_MAGIC_SYSRQ -- handle_sysrq('p', ¤t->thread.regs, NULL, NULL); -+ handle_sysrq('p', ¤t->thread.regs, NULL); - #endif -+ uml_exitcode = 1; - machine_halt(); - return(0); - } -@@ -403,6 +422,11 @@ void __init check_bugs(void) - arch_check_bugs(); - check_ptrace(); - check_sigio(); -+ check_devanon(); -+} -+ -+void apply_alternatives(void *start, void *end) -+{ - } - - /* -diff -puN arch/um/kernel/umid.c~Main-uml-patch-no-skas arch/um/kernel/umid.c ---- uml-linux-2.6.7/arch/um/kernel/umid.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.615303944 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/umid.c 2004-06-29 21:02:55.749283576 +0200 -@@ -5,7 +5,6 @@ - - #include <stdio.h> - #include <unistd.h> --#include <fcntl.h> - #include <errno.h> - #include <string.h> - #include <stdlib.h> -@@ -33,18 +32,19 @@ static char *uml_dir = UML_DIR; - static int umid_is_random = 1; - static int umid_inited = 0; - --static int make_umid(void); -+static int make_umid(int (*printer)(const char *fmt, ...)); - --static int __init set_umid(char *name, int is_random) -+static int __init set_umid(char *name, int is_random, -+ int (*printer)(const char *fmt, ...)) - { - if(umid_inited){ -- printk("Unique machine name can't be set twice\n"); -+ (*printer)("Unique machine name can't be set twice\n"); - return(-1); - } - - if(strlen(name) > UMID_LEN - 1) -- printk("Unique machine name is being truncated to %s " -- "characters\n", UMID_LEN); -+ (*printer)("Unique machine name is being truncated to %s " -+ "characters\n", UMID_LEN); - strlcpy(umid, name, sizeof(umid)); - - umid_is_random = is_random; -@@ -54,7 +54,7 @@ static int __init set_umid(char *name, i - - static int __init set_umid_arg(char *name, int *add) - { -- return(set_umid(name, 0)); -+ return(set_umid(name, 0, printf)); - } - - __uml_setup("umid=", set_umid_arg, -@@ -67,7 +67,7 @@ int __init umid_file_name(char *name, ch - { - int n; - -- if(!umid_inited && make_umid()) return(-1); -+ if(!umid_inited && make_umid(printk)) return(-1); - - n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1; - if(n > len){ -@@ -85,22 +85,23 @@ static int __init create_pid_file(void) - { - char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; - char pid[sizeof("nnnnn\0")]; -- int fd; -+ int fd, n; - - if(umid_file_name("pid", file, sizeof(file))) return 0; - - fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), - 0644); - if(fd < 0){ -- printk("Open of machine pid file \"%s\" failed - " -- "errno = %d\n", file, -fd); -+ printf("Open of machine pid file \"%s\" failed - " -+ "err = %d\n", file, -fd); - return 0; - } - - sprintf(pid, "%d\n", os_getpid()); -- if(write(fd, pid, strlen(pid)) != strlen(pid)) -- printk("Write of pid file failed - errno = %d\n", errno); -- close(fd); -+ n = os_write_file(fd, pid, strlen(pid)); -+ if(n != strlen(pid)) -+ printf("Write of pid file failed - err = %d\n", -n); -+ os_close_file(fd); - return 0; - } - -@@ -111,7 +112,8 @@ static int actually_do_remove(char *dir) - int len; - char file[256]; - -- if((directory = opendir(dir)) == NULL){ -+ directory = opendir(dir); -+ if(directory == NULL){ - printk("actually_do_remove : couldn't open directory '%s', " - "errno = %d\n", dir, errno); - return(1); -@@ -160,22 +162,24 @@ int not_dead_yet(char *dir) - { - char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; - char pid[sizeof("nnnnn\0")], *end; -- int dead, fd, p; -+ int dead, fd, p, n; - - sprintf(file, "%s/pid", dir); - dead = 0; -- if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){ -+ fd = os_open_file(file, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ - if(fd != -ENOENT){ - printk("not_dead_yet : couldn't open pid file '%s', " -- "errno = %d\n", file, -fd); -+ "err = %d\n", file, -fd); - return(1); - } - dead = 1; - } - if(fd > 0){ -- if(read(fd, pid, sizeof(pid)) < 0){ -+ n = os_read_file(fd, pid, sizeof(pid)); -+ if(n < 0){ - printk("not_dead_yet : couldn't read pid file '%s', " -- "errno = %d\n", file, errno); -+ "err = %d\n", file, -n); - return(1); - } - p = strtoul(pid, &end, 0); -@@ -197,7 +201,7 @@ static int __init set_uml_dir(char *name - if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){ - uml_dir = malloc(strlen(name) + 1); - if(uml_dir == NULL){ -- printk("Failed to malloc uml_dir - error = %d\n", -+ printf("Failed to malloc uml_dir - error = %d\n", - errno); - uml_dir = name; - return(0); -@@ -217,7 +221,7 @@ static int __init make_uml_dir(void) - char *home = getenv("HOME"); - - if(home == NULL){ -- printk("make_uml_dir : no value in environment for " -+ printf("make_uml_dir : no value in environment for " - "$HOME\n"); - exit(1); - } -@@ -232,57 +236,59 @@ static int __init make_uml_dir(void) - dir[len + 1] = '\0'; - } - -- if((uml_dir = malloc(strlen(dir) + 1)) == NULL){ -+ uml_dir = malloc(strlen(dir) + 1); -+ if(uml_dir == NULL){ - printf("make_uml_dir : malloc failed, errno = %d\n", errno); - exit(1); - } - strcpy(uml_dir, dir); - - if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){ -- printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno); -+ printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno); - return(-1); - } - return 0; - } - --static int __init make_umid(void) -+static int __init make_umid(int (*printer)(const char *fmt, ...)) - { - int fd, err; - char tmp[strlen(uml_dir) + UMID_LEN + 1]; - - strlcpy(tmp, uml_dir, sizeof(tmp)); - -- if(*umid == 0){ -+ if(!umid_inited){ - strcat(tmp, "XXXXXX"); - fd = mkstemp(tmp); - if(fd < 0){ -- printk("make_umid - mkstemp failed, errno = %d\n", -- errno); -+ (*printer)("make_umid - mkstemp failed, errno = %d\n", -+ errno); - return(1); - } - -- close(fd); -+ os_close_file(fd); - /* There's a nice tiny little race between this unlink and - * the mkdir below. It'd be nice if there were a mkstemp - * for directories. - */ - unlink(tmp); -- set_umid(&tmp[strlen(uml_dir)], 1); -+ set_umid(&tmp[strlen(uml_dir)], 1, printer); - } - - sprintf(tmp, "%s%s", uml_dir, umid); - -- if((err = mkdir(tmp, 0777)) < 0){ -+ err = mkdir(tmp, 0777); -+ if(err < 0){ - if(errno == EEXIST){ - if(not_dead_yet(tmp)){ -- printk("umid '%s' is in use\n", umid); -+ (*printer)("umid '%s' is in use\n", umid); - return(-1); - } - err = mkdir(tmp, 0777); - } - } - if(err < 0){ -- printk("Failed to create %s - errno = %d\n", umid, errno); -+ (*printer)("Failed to create %s - errno = %d\n", umid, errno); - return(-1); - } - -@@ -295,7 +301,13 @@ __uml_setup("uml_dir=", set_uml_dir, - ); - - __uml_postsetup(make_uml_dir); --__uml_postsetup(make_umid); -+ -+static int __init make_umid_setup(void) -+{ -+ return(make_umid(printf)); -+} -+ -+__uml_postsetup(make_umid_setup); - __uml_postsetup(create_pid_file); - - /* -diff -L arch/um/kernel/user_syms.c -puN arch/um/kernel/user_syms.c~Main-uml-patch-no-skas /dev/null ---- uml-linux-2.6.7/arch/um/kernel/user_syms.c -+++ /dev/null 1970-01-01 01:00:00.000000000 +0100 -@@ -1,113 +0,0 @@ --#include <stdio.h> --#include <unistd.h> --#include <fcntl.h> --#include <dirent.h> --#include <errno.h> --#include <utime.h> --#include <string.h> --#include <sys/stat.h> --#include <sys/vfs.h> --#include <sys/ioctl.h> --#include "user_util.h" --#include "mem_user.h" --#include "uml-config.h" -- --/* Had to steal this from linux/module.h because that file can't be included -- * since this includes various user-level headers. -- */ -- --struct module_symbol --{ -- unsigned long value; -- const char *name; --}; -- --/* Indirect stringification. */ -- --#define __MODULE_STRING_1(x) #x --#define __MODULE_STRING(x) __MODULE_STRING_1(x) -- --#if !defined(__AUTOCONF_INCLUDED__) -- --#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module --#define EXPORT_SYMBOL(var) error config_must_be_included_before_module --#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module -- --#elif !defined(UML_CONFIG_MODULES) -- --#define __EXPORT_SYMBOL(sym,str) --#define EXPORT_SYMBOL(var) --#define EXPORT_SYMBOL_NOVERS(var) -- --#else -- --#define __EXPORT_SYMBOL(sym, str) \ --const char __kstrtab_##sym[] \ --__attribute__((section(".kstrtab"))) = str; \ --const struct module_symbol __ksymtab_##sym \ --__attribute__((section("__ksymtab"))) = \ --{ (unsigned long)&sym, __kstrtab_##sym } -- --#if defined(__MODVERSIONS__) || !defined(UML_CONFIG_MODVERSIONS) --#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) --#else --#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) --#endif -- --#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) -- --#endif -- --EXPORT_SYMBOL(__errno_location); -- --EXPORT_SYMBOL(access); --EXPORT_SYMBOL(open); --EXPORT_SYMBOL(open64); --EXPORT_SYMBOL(close); --EXPORT_SYMBOL(read); --EXPORT_SYMBOL(write); --EXPORT_SYMBOL(dup2); --EXPORT_SYMBOL(__xstat); --EXPORT_SYMBOL(__lxstat); --EXPORT_SYMBOL(__lxstat64); --EXPORT_SYMBOL(lseek); --EXPORT_SYMBOL(lseek64); --EXPORT_SYMBOL(chown); --EXPORT_SYMBOL(truncate); --EXPORT_SYMBOL(utime); --EXPORT_SYMBOL(chmod); --EXPORT_SYMBOL(rename); --EXPORT_SYMBOL(__xmknod); -- --EXPORT_SYMBOL(symlink); --EXPORT_SYMBOL(link); --EXPORT_SYMBOL(unlink); --EXPORT_SYMBOL(readlink); -- --EXPORT_SYMBOL(mkdir); --EXPORT_SYMBOL(rmdir); --EXPORT_SYMBOL(opendir); --EXPORT_SYMBOL(readdir); --EXPORT_SYMBOL(closedir); --EXPORT_SYMBOL(seekdir); --EXPORT_SYMBOL(telldir); -- --EXPORT_SYMBOL(ioctl); -- --extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes, -- __off64_t __offset); --extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n, -- __off64_t __offset); --EXPORT_SYMBOL(pread64); --EXPORT_SYMBOL(pwrite64); -- --EXPORT_SYMBOL(statfs); --EXPORT_SYMBOL(statfs64); -- --EXPORT_SYMBOL(memcpy); --EXPORT_SYMBOL(getuid); -- --EXPORT_SYMBOL(memset); --EXPORT_SYMBOL(strstr); -- --EXPORT_SYMBOL(find_iomem); -diff -puN arch/um/kernel/user_util.c~Main-uml-patch-no-skas arch/um/kernel/user_util.c ---- uml-linux-2.6.7/arch/um/kernel/user_util.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.617303640 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/user_util.c 2004-06-29 21:02:55.749283576 +0200 -@@ -5,7 +5,6 @@ - - #include <stdio.h> - #include <stdlib.h> --#include <fcntl.h> - #include <unistd.h> - #include <limits.h> - #include <sys/mman.h> -@@ -82,7 +81,8 @@ int wait_for_stop(int pid, int sig, int - int status, ret; - - while(1){ -- if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) || -+ ret = waitpid(pid, &status, WUNTRACED); -+ if((ret < 0) || - !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){ - if(ret < 0){ - if(errno == EINTR) continue; -@@ -119,17 +119,6 @@ int wait_for_stop(int pid, int sig, int - } - } - --int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags) --{ -- int pid; -- -- pid = clone(fn, sp, flags, arg); -- if(pid < 0) return(-1); -- wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL); -- ptrace(PTRACE_CONT, pid, 0, 0); -- return(pid); --} -- - int raw(int fd, int complain) - { - struct termios tt; -diff -puN arch/um/main.c~Main-uml-patch-no-skas arch/um/main.c ---- uml-linux-2.6.7/arch/um/main.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.618303488 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/main.c 2004-06-29 21:02:55.750283424 +0200 -@@ -8,6 +8,7 @@ - #include <stdlib.h> - #include <string.h> - #include <signal.h> -+#include <errno.h> - #include <sys/resource.h> - #include <sys/mman.h> - #include <sys/user.h> -@@ -123,12 +124,14 @@ int main(int argc, char **argv, char **e - - set_stklim(); - -- if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){ -+ new_argv = malloc((argc + 1) * sizeof(char *)); -+ if(new_argv == NULL){ - perror("Mallocing argv"); - exit(1); - } - for(i=0;i<argc;i++){ -- if((new_argv[i] = strdup(argv[i])) == NULL){ -+ new_argv[i] = strdup(argv[i]); -+ if(new_argv[i] == NULL){ - perror("Mallocing an arg"); - exit(1); - } -diff -puN arch/um/Makefile~Main-uml-patch-no-skas arch/um/Makefile ---- uml-linux-2.6.7/arch/um/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.631301512 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Makefile 2004-06-29 21:02:55.750283424 +0200 -@@ -22,17 +22,21 @@ core-y += $(ARCH_DIR)/kernel/ \ - $(ARCH_DIR)/sys-$(SUBARCH)/ - - # Have to precede the include because the included Makefiles reference them. --SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \ -- include/asm-um/sigcontext.h include/asm-um/processor.h \ -- include/asm-um/ptrace.h include/asm-um/arch-signal.h -+SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \ -+ arch-signal.h module.h -+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 - --include $(ARCH_DIR)/Makefile-$(SUBARCH) --include $(ARCH_DIR)/Makefile-os-$(OS) -+# This target adds dependencies to "prepare". They are defined in the included -+# Makefiles (see Makefile-i386). -+ -+.PHONY: sys_prepare -+sys_prepare: -+ @: - - MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt - MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas -@@ -41,6 +45,9 @@ ifneq ($(MAKEFILE-y),) - include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y)) - endif - -+include $(ARCH_DIR)/Makefile-$(SUBARCH) -+include $(ARCH_DIR)/Makefile-os-$(OS) -+ - EXTRAVERSION := $(EXTRAVERSION)-1um - - ARCH_INCLUDE = -I$(ARCH_DIR)/include -@@ -52,14 +59,20 @@ ARCH_INCLUDE = -I$(ARCH_DIR)/include - - CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ - -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \ -- $(MODE_INCLUDE) -+ -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE) - - LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc - -+# These are needed for clean and mrproper, since in that case .config is not -+# included; the values here are meaningless -+ -+CONFIG_NEST_LEVEL ?= 0 -+CONFIG_KERNEL_HALF_GIGS ?= 0 -+ - SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) - - ifeq ($(CONFIG_MODE_SKAS), y) --$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h -+$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h - endif - - include/linux/version.h: arch/$(ARCH)/Makefile -@@ -98,17 +111,17 @@ CPP_MODE_TT := $(shell [ "$(CONFIG_MODE_ - CONFIG_KERNEL_STACK_ORDER ?= 2 - STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) - --AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \ -+AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \ - -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \ - -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \ -- -DKERNEL_STACK_SIZE=$(STACK_SIZE) -+ -DKERNEL_STACK_SIZE=$(STACK_SIZE)) - --AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum -+export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum - - LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y) - --$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE -- $(call if_changed_dep,as_s_S) -+#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE -+# $(call if_changed_dep,as_s_S) - - linux: vmlinux $(LD_SCRIPT-y) - $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \ -@@ -116,37 +129,47 @@ linux: vmlinux $(LD_SCRIPT-y) - - USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) - USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS)) -+USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS)) - USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ - $(MODE_INCLUDE) - - # To get a definition of F_SETSIG - USER_CFLAGS += -D_GNU_SOURCE - -+# From main Makefile, these options are set after including the ARCH makefile. -+# So copy them here. -+ -+ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -+USER_CFLAGS += -Os -+else -+USER_CFLAGS += -O2 -+endif -+ -+ifndef CONFIG_FRAME_POINTER -+USER_CFLAGS += -fomit-frame-pointer -+endif -+ -+ifdef CONFIG_DEBUG_INFO -+USER_CFLAGS += -g -+endif -+ - CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \ -- $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS) -+ $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \ -+ $(GEN_HEADERS) - --$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c -- $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< -+MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \ -+ $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) -+ -+$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare -+ @ echo ' MAIN $@' -+ @ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< - - archmrproper: -- for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \ -- do \ -- $(MAKE) -C $$d archmrproper; \ -- done -- rm -f $(CLEAN_FILES) $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \ -- $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) -- --archclean: sysclean -- for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \ -- do \ -- $(MAKE) -C $$d clean; \ -- done -- find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ -- -o -name '*.gcov' \) -type f -print | xargs rm -f -- rm -f linux x.i gmon.out $(ARCH_DIR)/link.ld $(GEN_HEADERS) -+ @: - --archdep: -- for d in $(ARCH_SUBDIRS); do $(MAKE) -C $$d fastdep; done -+archclean: -+ @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ -+ -o -name '*.gcov' \) -type f -print | xargs rm -f - - $(SYMLINK_HEADERS): - cd $(TOPDIR)/$(dir $@) ; \ -@@ -161,19 +184,26 @@ $(ARCH_DIR)/include/sysdep: - $(ARCH_DIR)/os: - cd $(ARCH_DIR) && ln -sf os-$(OS) os - --$(ARCH_DIR)/include/uml-config.h : -- sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@ -+# Generated files -+define filechk_umlconfig -+ sed 's/ CONFIG/ UML_CONFIG/' -+endef -+ -+$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h -+ $(call filechk,umlconfig) -+ -+filechk_gen_header = $< - - $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task -- $< > $@ -+ $(call filechk,gen_header) - - $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants -- $< > $@ -+ $(call filechk,gen_header) - --$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \ -- $(ARCH_DIR)/util FORCE ; -+$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \ -+ sys_prepare FORCE ; - - $(ARCH_DIR)/util: FORCE -- @$(call descend,$@,) -+ $(Q)$(MAKE) $(build)=$@ - --export SUBARCH USER_CFLAGS OS -+export SUBARCH USER_CFLAGS OS -diff -puN arch/um/Makefile-i386~Main-uml-patch-no-skas arch/um/Makefile-i386 ---- uml-linux-2.6.7/arch/um/Makefile-i386~Main-uml-patch-no-skas 2004-06-29 21:02:55.632301360 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Makefile-i386 2004-06-29 21:02:55.750283424 +0200 -@@ -16,22 +16,27 @@ SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/uti - - SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h - -+sys_prepare: $(SYS_DIR)/sc.h -+ - prepare: $(SYS_HEADERS) - -+filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc -+ - $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc -- $< > $@ -+ $(call filechk,$@) -+ -+filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread - - $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread -- $< > $@ -+ $(call filechk,$@) - --$(SYS_UTIL_DIR)/mk_sc: FORCE ; -- @$(call descend,$(SYS_UTIL_DIR),$@) -+$(SYS_UTIL_DIR)/mk_sc: scripts/basic/fixdep include/config/MARKER FORCE ; -+ $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ - --$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ; -- @$(call descend,$(SYS_UTIL_DIR),$@) -+$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ; -+ $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ - - $(SYS_UTIL_DIR): include/asm FORCE -- @$(call descend,$@,) -+ $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) - --sysclean : -- rm -f $(SYS_HEADERS) -+CLEAN_FILES += $(SYS_HEADERS) -diff -puN arch/um/Makefile-skas~Main-uml-patch-no-skas arch/um/Makefile-skas ---- uml-linux-2.6.7/arch/um/Makefile-skas~Main-uml-patch-no-skas 2004-06-29 21:02:55.633301208 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Makefile-skas 2004-06-29 21:02:55.750283424 +0200 -@@ -14,7 +14,7 @@ MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/ - LINK_SKAS = -Wl,-rpath,/lib - LD_SCRIPT_SKAS = dyn.lds.s - --GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h -+GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h - --$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h : -- $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h -+$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h : -+ $(Q)$(MAKE) $(build)=$(ARCH_DIR)/kernel/skas $@ -diff -puN arch/um/os-Linux/drivers/ethertap_kern.c~Main-uml-patch-no-skas arch/um/os-Linux/drivers/ethertap_kern.c ---- uml-linux-2.6.7/arch/um/os-Linux/drivers/ethertap_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.634301056 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/ethertap_kern.c 2004-06-29 21:02:55.751283272 +0200 -@@ -8,7 +8,6 @@ - #include "linux/init.h" - #include "linux/netdevice.h" - #include "linux/etherdevice.h" --#include "linux/init.h" - #include "net_kern.h" - #include "net_user.h" - #include "etap.h" -diff -puN arch/um/os-Linux/drivers/ethertap_user.c~Main-uml-patch-no-skas arch/um/os-Linux/drivers/ethertap_user.c ---- uml-linux-2.6.7/arch/um/os-Linux/drivers/ethertap_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.635300904 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/ethertap_user.c 2004-06-29 21:02:55.751283272 +0200 -@@ -8,7 +8,6 @@ - #include <stdio.h> - #include <unistd.h> - #include <stddef.h> --#include <fcntl.h> - #include <stdlib.h> - #include <sys/errno.h> - #include <sys/socket.h> -@@ -42,13 +41,14 @@ static void etap_change(int op, unsigned - { - struct addr_change change; - void *output; -+ int n; - - change.what = op; - memcpy(change.addr, addr, sizeof(change.addr)); - memcpy(change.netmask, netmask, sizeof(change.netmask)); -- if(write(fd, &change, sizeof(change)) != sizeof(change)) -- printk("etap_change - request failed, errno = %d\n", -- errno); -+ n = os_write_file(fd, &change, sizeof(change)); -+ if(n != sizeof(change)) -+ printk("etap_change - request failed, err = %d\n", -n); - output = um_kmalloc(page_size()); - if(output == NULL) - printk("etap_change : Failed to allocate output buffer\n"); -@@ -82,15 +82,15 @@ static void etap_pre_exec(void *arg) - struct etap_pre_exec_data *data = arg; - - dup2(data->control_remote, 1); -- close(data->data_me); -- close(data->control_me); -+ os_close_file(data->data_me); -+ os_close_file(data->control_me); - } - - static int etap_tramp(char *dev, char *gate, int control_me, - int control_remote, int data_me, int data_remote) - { - struct etap_pre_exec_data pe_data; -- int pid, status, err; -+ int pid, status, err, n; - char version_buf[sizeof("nnnnn\0")]; - char data_fd_buf[sizeof("nnnnnn\0")]; - char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; -@@ -114,21 +114,21 @@ static int etap_tramp(char *dev, char *g - pe_data.data_me = data_me; - pid = run_helper(etap_pre_exec, &pe_data, args, NULL); - -- if(pid < 0) err = errno; -- close(data_remote); -- close(control_remote); -- if(read(control_me, &c, sizeof(c)) != sizeof(c)){ -- printk("etap_tramp : read of status failed, errno = %d\n", -- errno); -- return(EINVAL); -+ if(pid < 0) err = pid; -+ os_close_file(data_remote); -+ os_close_file(control_remote); -+ n = os_read_file(control_me, &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("etap_tramp : read of status failed, err = %d\n", -n); -+ return(-EINVAL); - } - if(c != 1){ - printk("etap_tramp : uml_net failed\n"); -- err = EINVAL; -- if(waitpid(pid, &status, 0) < 0) err = errno; -- else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){ -+ err = -EINVAL; -+ if(waitpid(pid, &status, 0) < 0) -+ err = -errno; -+ else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) - printk("uml_net didn't exit with status 1\n"); -- } - } - return(err); - } -@@ -143,14 +143,14 @@ static int etap_open(void *data) - if(err) return(err); - - err = os_pipe(data_fds, 0, 0); -- if(err){ -- printk("data os_pipe failed - errno = %d\n", -err); -+ if(err < 0){ -+ printk("data os_pipe failed - err = %d\n", -err); - return(err); - } - - err = os_pipe(control_fds, 1, 0); -- if(err){ -- printk("control os_pipe failed - errno = %d\n", -err); -+ if(err < 0){ -+ printk("control os_pipe failed - err = %d\n", -err); - return(err); - } - -@@ -167,9 +167,9 @@ static int etap_open(void *data) - kfree(output); - } - -- if(err != 0){ -- printk("etap_tramp failed - errno = %d\n", err); -- return(-err); -+ if(err < 0){ -+ printk("etap_tramp failed - err = %d\n", -err); -+ return(err); - } - - pri->data_fd = data_fds[0]; -@@ -183,11 +183,11 @@ static void etap_close(int fd, void *dat - struct ethertap_data *pri = data; - - iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); -- close(fd); -+ os_close_file(fd); - os_shutdown_socket(pri->data_fd, 1, 1); -- close(pri->data_fd); -+ os_close_file(pri->data_fd); - pri->data_fd = -1; -- close(pri->control_fd); -+ os_close_file(pri->control_fd); - pri->control_fd = -1; - } - -diff -puN arch/um/os-Linux/drivers/tuntap_user.c~Main-uml-patch-no-skas arch/um/os-Linux/drivers/tuntap_user.c ---- uml-linux-2.6.7/arch/um/os-Linux/drivers/tuntap_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.637300600 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/drivers/tuntap_user.c 2004-06-29 21:02:55.752283120 +0200 -@@ -8,7 +8,6 @@ - #include <stdlib.h> - #include <unistd.h> - #include <errno.h> --#include <fcntl.h> - #include <sys/wait.h> - #include <sys/socket.h> - #include <sys/un.h> -@@ -61,7 +60,7 @@ static void tuntap_pre_exec(void *arg) - struct tuntap_pre_exec_data *data = arg; - - dup2(data->stdout, 1); -- close(data->close_me); -+ os_close_file(data->close_me); - } - - static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, -@@ -86,7 +85,7 @@ static int tuntap_open_tramp(char *gate, - - if(pid < 0) return(-pid); - -- close(remote); -+ os_close_file(remote); - - msg.msg_name = NULL; - msg.msg_namelen = 0; -@@ -107,19 +106,19 @@ static int tuntap_open_tramp(char *gate, - if(n < 0){ - printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", - errno); -- return(errno); -+ return(-errno); - } - waitpid(pid, NULL, 0); - - cmsg = CMSG_FIRSTHDR(&msg); - if(cmsg == NULL){ - printk("tuntap_open_tramp : didn't receive a message\n"); -- return(EINVAL); -+ return(-EINVAL); - } - if((cmsg->cmsg_level != SOL_SOCKET) || - (cmsg->cmsg_type != SCM_RIGHTS)){ - printk("tuntap_open_tramp : didn't receive a descriptor\n"); -- return(EINVAL); -+ return(-EINVAL); - } - *fd_out = ((int *) CMSG_DATA(cmsg))[0]; - return(0); -@@ -133,27 +132,29 @@ static int tuntap_open(void *data) - int err, fds[2], len, used; - - err = tap_open_common(pri->dev, pri->gate_addr); -- if(err) return(err); -+ if(err < 0) -+ return(err); - - if(pri->fixed_config){ -- if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){ -- printk("Failed to open /dev/net/tun, errno = %d\n", -- errno); -- return(-errno); -+ pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0); -+ if(pri->fd < 0){ -+ printk("Failed to open /dev/net/tun, err = %d\n", -+ -pri->fd); -+ return(pri->fd); - } - memset(&ifr, 0, sizeof(ifr)); -- ifr.ifr_flags = IFF_TAP; -+ 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){ -- printk("TUNSETIFF failed, errno = %d", errno); -- close(pri->fd); -+ printk("TUNSETIFF failed, errno = %d\n", errno); -+ os_close_file(pri->fd); - return(-errno); - } - } - else { - err = os_pipe(fds, 0, 0); -- if(err){ -- printk("tuntap_open : os_pipe failed - errno = %d\n", -+ if(err < 0){ -+ printk("tuntap_open : os_pipe failed - err = %d\n", - -err); - return(err); - } -@@ -166,19 +167,19 @@ static int tuntap_open(void *data) - fds[1], buffer, len, &used); - - output = buffer; -- if(err == 0){ -- pri->dev_name = uml_strdup(buffer); -- output += IFNAMSIZ; -- printk(output); -- free_output_buffer(buffer); -- } -- else { -- printk(output); -+ if(err < 0) { -+ printk("%s", output); - free_output_buffer(buffer); -- printk("tuntap_open_tramp failed - errno = %d\n", err); -- return(-err); -+ printk("tuntap_open_tramp failed - err = %d\n", -err); -+ return(err); - } -- close(fds[0]); -+ -+ pri->dev_name = uml_strdup(buffer); -+ output += IFNAMSIZ; -+ printk("%s", output); -+ free_output_buffer(buffer); -+ -+ os_close_file(fds[0]); - iter_addresses(pri->dev, open_addr, pri->dev_name); - } - -@@ -191,7 +192,7 @@ static void tuntap_close(int fd, void *d - - if(!pri->fixed_config) - iter_addresses(pri->dev, close_addr, pri->dev_name); -- close(fd); -+ os_close_file(fd); - pri->fd = -1; - } - -diff -puN arch/um/os-Linux/file.c~Main-uml-patch-no-skas arch/um/os-Linux/file.c ---- uml-linux-2.6.7/arch/um/os-Linux/file.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.638300448 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/file.c 2004-06-29 21:02:55.752283120 +0200 -@@ -8,6 +8,8 @@ - #include <errno.h> - #include <fcntl.h> - #include <signal.h> -+#include <sys/types.h> -+#include <sys/stat.h> - #include <sys/socket.h> - #include <sys/un.h> - #include <sys/ioctl.h> -@@ -17,33 +19,235 @@ - #include "user.h" - #include "kern_util.h" - --int os_file_type(char *file) -+static void copy_stat(struct uml_stat *dst, struct stat64 *src) -+{ -+ *dst = ((struct uml_stat) { -+ .ust_dev = src->st_dev, /* device */ -+ .ust_ino = src->st_ino, /* inode */ -+ .ust_mode = src->st_mode, /* protection */ -+ .ust_nlink = src->st_nlink, /* number of hard links */ -+ .ust_uid = src->st_uid, /* user ID of owner */ -+ .ust_gid = src->st_gid, /* group ID of owner */ -+ .ust_size = src->st_size, /* total size, in bytes */ -+ .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */ -+ .ust_blocks = src->st_blocks, /* number of blocks allocated */ -+ .ust_atime = src->st_atime, /* time of last access */ -+ .ust_mtime = src->st_mtime, /* time of last modification */ -+ .ust_ctime = src->st_ctime, /* time of last change */ -+ }); -+} -+ -+int os_stat_fd(const int fd, struct uml_stat *ubuf) -+{ -+ struct stat64 sbuf; -+ int err; -+ -+ do { -+ err = fstat64(fd, &sbuf); -+ } while((err < 0) && (errno == EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ -+ if(ubuf != NULL) -+ copy_stat(ubuf, &sbuf); -+ return(err); -+} -+ -+int os_stat_file(const char *file_name, struct uml_stat *ubuf) -+{ -+ struct stat64 sbuf; -+ int err; -+ -+ do { -+ err = stat64(file_name, &sbuf); -+ } while((err < 0) && (errno == EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ -+ if(ubuf != NULL) -+ copy_stat(ubuf, &sbuf); -+ return(err); -+} -+ -+int os_access(const char* file, int mode) -+{ -+ int amode, err; -+ -+ amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) | -+ (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ; -+ -+ err = access(file, amode); -+ if(err < 0) -+ return(-errno); -+ -+ return(0); -+} -+ -+void os_print_error(int error, const char* str) -+{ -+ errno = error < 0 ? -error : error; -+ -+ perror(str); -+} -+ -+/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */ -+int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) -+{ -+ int err; -+ -+ err = ioctl(fd, cmd, arg); -+ if(err < 0) -+ return(-errno); -+ -+ return(err); -+} -+ -+int os_window_size(int fd, int *rows, int *cols) -+{ -+ struct winsize size; -+ -+ if(ioctl(fd, TIOCGWINSZ, &size) < 0) -+ return(-errno); -+ -+ *rows = size.ws_row; -+ *cols = size.ws_col; -+ -+ return(0); -+} -+ -+int os_new_tty_pgrp(int fd, int pid) - { -- struct stat64 buf; -+ if(ioctl(fd, TIOCSCTTY, 0) < 0){ -+ printk("TIOCSCTTY failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ if(tcsetpgrp(fd, pid) < 0){ -+ printk("tcsetpgrp failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ return(0); -+} -+ -+/* FIXME: ensure namebuf in os_get_if_name is big enough */ -+int os_get_ifname(int fd, char* namebuf) -+{ -+ if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) -+ return(-errno); -+ -+ return(0); -+} -+ -+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); -+ } -+ -+ sencap = 0; -+ if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){ -+ printk("Failed to set slip encapsulation - " -+ "errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ return(0); -+} -+ -+int os_set_owner(int fd, int pid) -+{ -+ if(fcntl(fd, F_SETOWN, pid) < 0){ -+ int save_errno = errno; -+ -+ if(fcntl(fd, F_GETOWN, 0) != pid) -+ return(-save_errno); -+ } -+ -+ return(0); -+} -+ -+/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ -+int os_sigio_async(int master, int slave) -+{ -+ int flags; - -- if(stat64(file, &buf) == -1) -+ flags = fcntl(master, F_GETFL); -+ if(flags < 0) { -+ printk("fcntl F_GETFL failed, errno = %d\n", errno); - 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); -+ } -+ -+ if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){ -+ printk("fcntl F_SETFL failed, errno = %d\n", errno); -+ return(-errno); -+ } - -- if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR); -- else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK); -- else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV); -- else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV); -- else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO); -- else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK); -+ return(0); -+} -+ -+int os_mode_fd(int fd, int mode) -+{ -+ int err; -+ -+ do { -+ err = fchmod(fd, mode); -+ } while((err < 0) && (errno==EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ -+ return(0); -+} -+ -+int os_file_type(char *file) -+{ -+ struct uml_stat buf; -+ int err; -+ -+ err = os_stat_file(file, &buf); -+ if(err < 0) -+ return(err); -+ -+ if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR); -+ else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK); -+ else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV); -+ else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV); -+ else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO); -+ else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK); - else return(OS_TYPE_FILE); - } - - int os_file_mode(char *file, struct openflags *mode_out) - { -+ int err; -+ - *mode_out = OPENFLAGS(); - -- if(!access(file, W_OK)) *mode_out = of_write(*mode_out); -- else if(errno != EACCES) -- return(-errno); -+ err = os_access(file, OS_ACC_W_OK); -+ if((err < 0) && (err != -EACCES)) -+ return(err); - -- if(!access(file, R_OK)) *mode_out = of_read(*mode_out); -- else if(errno != EACCES) -- return(-errno); -+ *mode_out = of_write(*mode_out); -+ -+ err = os_access(file, OS_ACC_R_OK); -+ if((err < 0) && (err != -EACCES)) -+ return(err); -+ -+ *mode_out = of_read(*mode_out); - - return(0); - } -@@ -63,16 +267,14 @@ int os_open_file(char *file, struct open - if(flags.e) f |= O_EXCL; - - fd = open64(file, f, mode); -- if(fd < 0) return(-errno); -- -- if(flags.cl){ -- if(fcntl(fd, F_SETFD, 1)){ -- close(fd); -- return(-errno); -- } -+ if(fd < 0) -+ return(-errno); -+ -+ if(flags.cl && fcntl(fd, F_SETFD, 1)){ -+ os_close_file(fd); -+ return(-errno); - } - -- return(fd); - return(fd); - } - -@@ -90,7 +292,7 @@ int os_connect_socket(char *name) - - err = connect(fd, (struct sockaddr *) &sock, sizeof(sock)); - if(err) -- return(err); -+ return(-errno); - - return(fd); - } -@@ -109,88 +311,162 @@ int os_seek_file(int fd, __u64 offset) - return(0); - } - --int os_read_file(int fd, void *buf, int len) -+static int fault_buffer(void *start, int len, -+ int (*copy_proc)(void *addr, void *buf, int len)) - { -- int n; -+ int page = getpagesize(), i; -+ char c; - -- /* Force buf into memory if it's not already. */ -+ for(i = 0; i < len; i += page){ -+ if((*copy_proc)(start + i, &c, sizeof(c))) -+ return(-EFAULT); -+ } -+ if((len % page) != 0){ -+ if((*copy_proc)(start + len - 1, &c, sizeof(c))) -+ return(-EFAULT); -+ } -+ return(0); -+} - -- /* XXX This fails if buf is kernel memory */ --#ifdef notdef -- if(copy_to_user_proc(buf, &c, sizeof(c))) -- return(-EFAULT); --#endif -+static int file_io(int fd, void *buf, int len, -+ int (*io_proc)(int fd, void *buf, int len), -+ int (*copy_user_proc)(void *addr, void *buf, int len)) -+{ -+ int n, err; -+ -+ do { -+ n = (*io_proc)(fd, buf, len); -+ if((n < 0) && (errno == EFAULT)){ -+ err = fault_buffer(buf, len, copy_user_proc); -+ if(err) -+ return(err); -+ n = (*io_proc)(fd, buf, len); -+ } -+ } while((n < 0) && (errno == EINTR)); - -- n = read(fd, buf, len); - if(n < 0) - return(-errno); - return(n); - } - --int os_write_file(int fd, void *buf, int count) -+int os_read_file(int fd, void *buf, int len) - { -- int n; -- -- /* Force buf into memory if it's not already. */ -- -- /* XXX This fails if buf is kernel memory */ --#ifdef notdef -- if(copy_to_user_proc(buf, buf, buf[0])) -- return(-EFAULT); --#endif -+ return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, -+ copy_from_user_proc)); -+} - -- n = write(fd, buf, count); -- if(n < 0) -- return(-errno); -- return(n); -+int os_write_file(int fd, const void *buf, int len) -+{ -+ return(file_io(fd, (void *) buf, len, -+ (int (*)(int, void *, int)) write, copy_to_user_proc)); - } - - int os_file_size(char *file, long long *size_out) - { -- struct stat64 buf; -+ struct uml_stat buf; -+ int err; - -- if(stat64(file, &buf) == -1){ -- printk("Couldn't stat \"%s\" : errno = %d\n", file, errno); -- return(-errno); -+ err = os_stat_file(file, &buf); -+ if(err < 0){ -+ printk("Couldn't stat \"%s\" : err = %d\n", file, -err); -+ return(err); - } -- if(S_ISBLK(buf.st_mode)){ -+ -+ if(S_ISBLK(buf.ust_mode)){ - int fd, blocks; - -- if((fd = open64(file, O_RDONLY)) < 0){ -- printk("Couldn't open \"%s\", errno = %d\n", file, -- errno); -- return(-errno); -+ fd = os_open_file(file, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Couldn't open \"%s\", errno = %d\n", file, -fd); -+ return(fd); - } - if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ - printk("Couldn't get the block size of \"%s\", " - "errno = %d\n", file, errno); -- close(fd); -- return(-errno); -+ err = -errno; -+ os_close_file(fd); -+ return(err); - } - *size_out = ((long long) blocks) * 512; -- close(fd); -+ os_close_file(fd); - return(0); - } -- *size_out = buf.st_size; -+ *size_out = buf.ust_size; -+ return(0); -+} -+ -+int os_file_modtime(char *file, unsigned long *modtime) -+{ -+ struct uml_stat buf; -+ int err; -+ -+ err = os_stat_file(file, &buf); -+ if(err < 0){ -+ printk("Couldn't stat \"%s\" : err = %d\n", file, -err); -+ return(err); -+ } -+ -+ *modtime = buf.ust_mtime; - return(0); - } - -+int os_get_exec_close(int fd, int* close_on_exec) -+{ -+ int ret; -+ -+ do { -+ ret = fcntl(fd, F_GETFD); -+ } while((ret < 0) && (errno == EINTR)) ; -+ -+ if(ret < 0) -+ return(-errno); -+ -+ *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0; -+ return(ret); -+} -+ -+int os_set_exec_close(int fd, int close_on_exec) -+{ -+ int flag, err; -+ -+ if(close_on_exec) flag = FD_CLOEXEC; -+ else flag = 0; -+ -+ do { -+ err = fcntl(fd, F_SETFD, flag); -+ } while((err < 0) && (errno == EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ return(err); -+} -+ - int os_pipe(int *fds, int stream, int close_on_exec) - { - int err, type = stream ? SOCK_STREAM : SOCK_DGRAM; - - err = socketpair(AF_UNIX, type, 0, fds); -- if(err) -+ if(err < 0) - return(-errno); - - if(!close_on_exec) - return(0); - -- if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0)) -- printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d", -- errno); -+ err = os_set_exec_close(fds[0], 1); -+ if(err < 0) -+ goto error; -+ -+ err = os_set_exec_close(fds[1], 1); -+ if(err < 0) -+ goto error; - - return(0); -+ -+ error: -+ printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); -+ os_close_file(fds[1]); -+ os_close_file(fds[0]); -+ return(err); - } - - int os_set_fd_async(int fd, int owner) -@@ -270,7 +546,7 @@ int os_shutdown_socket(int fd, int r, in - return(-EINVAL); - } - err = shutdown(fd, what); -- if(err) -+ if(err < 0) - return(-errno); - return(0); - } -@@ -315,7 +591,7 @@ int os_rcv_fd(int fd, int *helper_pid_ou - return(new); - } - --int create_unix_socket(char *file, int len) -+int os_create_unix_socket(char *file, int len, int close_on_exec) - { - struct sockaddr_un addr; - int sock, err; -@@ -327,6 +603,13 @@ int create_unix_socket(char *file, int l - return(-errno); - } - -+ if(close_on_exec) { -+ err = os_set_exec_close(sock, 1); -+ if(err < 0) -+ printk("create_unix_socket : close_on_exec failed, " -+ "err = %d", -err); -+ } -+ - addr.sun_family = AF_UNIX; - - /* XXX Be more careful about overflow */ -@@ -334,14 +617,45 @@ int create_unix_socket(char *file, int l - - err = bind(sock, (struct sockaddr *) &addr, sizeof(addr)); - if (err < 0){ -- printk("create_listening_socket - bind failed, errno = %d\n", -- errno); -+ printk("create_listening_socket at '%s' - bind failed, " -+ "errno = %d\n", file, errno); - return(-errno); - } - - return(sock); - } - -+void os_flush_stdout(void) -+{ -+ fflush(stdout); -+} -+ -+int os_lock_file(int fd, int excl) -+{ -+ int type = excl ? F_WRLCK : F_RDLCK; -+ struct flock lock = ((struct flock) { .l_type = type, -+ .l_whence = SEEK_SET, -+ .l_start = 0, -+ .l_len = 0 } ); -+ int err, save; -+ -+ err = fcntl(fd, F_SETLK, &lock); -+ if(!err) -+ goto out; -+ -+ save = -errno; -+ err = fcntl(fd, F_GETLK, &lock); -+ if(err){ -+ err = -errno; -+ goto out; -+ } -+ -+ printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); -+ err = save; -+ 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 -diff -puN arch/um/os-Linux/Makefile~Main-uml-patch-no-skas arch/um/os-Linux/Makefile ---- uml-linux-2.6.7/arch/um/os-Linux/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.639300296 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/Makefile 2004-06-29 21:02:55.752283120 +0200 -@@ -3,13 +3,9 @@ - # Licensed under the GPL - # - --obj-y = file.o process.o tty.o drivers/ -+obj-y = file.o process.o tty.o user_syms.o drivers/ - - USER_OBJS := $(foreach file,file.o process.o tty.o,$(obj)/$(file)) - - $(USER_OBJS) : %.o: %.c - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -- --clean : -- --archmrproper: -diff -puN arch/um/os-Linux/process.c~Main-uml-patch-no-skas arch/um/os-Linux/process.c ---- uml-linux-2.6.7/arch/um/os-Linux/process.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.640300144 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c 2004-06-29 21:02:55.753282968 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -7,32 +7,37 @@ - #include <stdio.h> - #include <errno.h> - #include <signal.h> -+#include <linux/unistd.h> - #include <sys/mman.h> - #include <sys/wait.h> - #include "os.h" - #include "user.h" - -+#define ARBITRARY_ADDR -1 -+#define FAILURE_PID -1 -+ - unsigned long os_process_pc(int pid) - { - char proc_stat[sizeof("/proc/#####/stat\0")], buf[256]; - unsigned long pc; -- int fd; -+ int fd, err; - - sprintf(proc_stat, "/proc/%d/stat", pid); - fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); - if(fd < 0){ -- printk("os_process_pc - couldn't open '%s', errno = %d\n", -- proc_stat, errno); -- return(-1); -+ printk("os_process_pc - couldn't open '%s', err = %d\n", -+ proc_stat, -fd); -+ return(ARBITRARY_ADDR); - } -- if(read(fd, buf, sizeof(buf)) < 0){ -- printk("os_process_pc - couldn't read '%s', errno = %d\n", -- proc_stat, errno); -- close(fd); -- return(-1); -+ err = os_read_file(fd, buf, sizeof(buf)); -+ if(err < 0){ -+ printk("os_process_pc - couldn't read '%s', err = %d\n", -+ proc_stat, -err); -+ os_close_file(fd); -+ return(ARBITRARY_ADDR); - } -- close(fd); -- pc = -1; -+ os_close_file(fd); -+ pc = ARBITRARY_ADDR; - if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %ld", &pc) != 1){ -@@ -52,22 +57,23 @@ int os_process_parent(int pid) - snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); - fd = os_open_file(stat, of_read(OPENFLAGS()), 0); - if(fd < 0){ -- printk("Couldn't open '%s', errno = %d\n", stat, -fd); -- return(-1); -+ printk("Couldn't open '%s', err = %d\n", stat, -fd); -+ return(FAILURE_PID); - } - -- n = read(fd, data, sizeof(data)); -- close(fd); -+ n = os_read_file(fd, data, sizeof(data)); -+ os_close_file(fd); - - if(n < 0){ -- printk("Couldn't read '%s', errno = %d\n", stat); -- return(-1); -+ printk("Couldn't read '%s', err = %d\n", stat, -n); -+ return(FAILURE_PID); - } - -- parent = -1; -+ parent = FAILURE_PID; - /* XXX This will break if there is a space in the command */ - n = sscanf(data, "%*d %*s %*c %d", &parent); -- if(n != 1) printk("Failed to scan '%s'\n", data); -+ if(n != 1) -+ printk("Failed to scan '%s'\n", data); - - return(parent); - } -@@ -87,7 +93,8 @@ void os_kill_process(int pid, int reap_c - - void os_usr1_process(int pid) - { -- kill(pid, SIGUSR1); -+ syscall(__NR_tkill, pid, SIGUSR1); -+ /* kill(pid, SIGUSR1); */ - } - - int os_getpid(void) -@@ -95,7 +102,7 @@ int os_getpid(void) - return(getpid()); - } - --int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len, -+int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, - int r, int w, int x) - { - void *loc; -@@ -104,8 +111,8 @@ int os_map_memory(void *virt, int fd, un - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); - -- loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, -- fd, off); -+ loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, -+ fd, off); - if(loc == MAP_FAILED) - return(-errno); - return(0); -@@ -126,7 +133,8 @@ int os_unmap_memory(void *addr, int len) - int err; - - err = munmap(addr, len); -- if(err < 0) return(-errno); -+ if(err < 0) -+ return(-errno); - return(0); - } - -diff -puN arch/um/os-Linux/tty.c~Main-uml-patch-no-skas arch/um/os-Linux/tty.c ---- uml-linux-2.6.7/arch/um/os-Linux/tty.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.641299992 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/tty.c 2004-06-29 21:02:55.753282968 +0200 -@@ -28,10 +28,10 @@ int get_pty(void) - struct grantpt_info info; - int fd; - -- if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){ -- printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n", -- errno); -- return(-1); -+ fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd); -+ return(fd); - } - - info.fd = fd; -@@ -39,7 +39,7 @@ int get_pty(void) - - if(info.res < 0){ - printk("get_pty : Couldn't grant pty - errno = %d\n", -- info.err); -+ -info.err); - return(-1); - } - if(unlockpt(fd) < 0){ -diff -puN /dev/null arch/um/os-Linux/user_syms.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/user_syms.c 2004-06-29 21:02:55.753282968 +0200 -@@ -0,0 +1,88 @@ -+#include "linux/types.h" -+#include "linux/module.h" -+ -+/* Some of this are builtin function (some are not but could in the future), -+ * so I *must* declare good prototypes for them and then EXPORT them. -+ * The kernel code uses the macro defined by include/linux/string.h, -+ * so I undef macros; the userspace code does not include that and I -+ * add an EXPORT for the glibc one.*/ -+ -+#undef strlen -+#undef strstr -+#undef memcpy -+#undef memset -+ -+extern size_t strlen(const char *); -+extern void *memcpy(void *, const void *, size_t); -+extern void *memset(void *, int, size_t); -+extern int printf(const char *, ...); -+ -+EXPORT_SYMBOL(strlen); -+EXPORT_SYMBOL(memcpy); -+EXPORT_SYMBOL(memset); -+EXPORT_SYMBOL(printf); -+ -+EXPORT_SYMBOL(strstr); -+ -+/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. -+ * However, the modules will use the CRC defined *here*, no matter if it is -+ * good; so the versions of these symbols will always match -+ */ -+#define EXPORT_SYMBOL_PROTO(sym) \ -+ int sym(void); \ -+ EXPORT_SYMBOL(sym); -+ -+EXPORT_SYMBOL_PROTO(__errno_location); -+ -+EXPORT_SYMBOL_PROTO(access); -+EXPORT_SYMBOL_PROTO(open); -+EXPORT_SYMBOL_PROTO(open64); -+EXPORT_SYMBOL_PROTO(close); -+EXPORT_SYMBOL_PROTO(read); -+EXPORT_SYMBOL_PROTO(write); -+EXPORT_SYMBOL_PROTO(dup2); -+EXPORT_SYMBOL_PROTO(__xstat); -+EXPORT_SYMBOL_PROTO(__lxstat); -+EXPORT_SYMBOL_PROTO(__lxstat64); -+EXPORT_SYMBOL_PROTO(lseek); -+EXPORT_SYMBOL_PROTO(lseek64); -+EXPORT_SYMBOL_PROTO(chown); -+EXPORT_SYMBOL_PROTO(truncate); -+EXPORT_SYMBOL_PROTO(utime); -+EXPORT_SYMBOL_PROTO(chmod); -+EXPORT_SYMBOL_PROTO(rename); -+EXPORT_SYMBOL_PROTO(__xmknod); -+ -+EXPORT_SYMBOL_PROTO(symlink); -+EXPORT_SYMBOL_PROTO(link); -+EXPORT_SYMBOL_PROTO(unlink); -+EXPORT_SYMBOL_PROTO(readlink); -+ -+EXPORT_SYMBOL_PROTO(mkdir); -+EXPORT_SYMBOL_PROTO(rmdir); -+EXPORT_SYMBOL_PROTO(opendir); -+EXPORT_SYMBOL_PROTO(readdir); -+EXPORT_SYMBOL_PROTO(closedir); -+EXPORT_SYMBOL_PROTO(seekdir); -+EXPORT_SYMBOL_PROTO(telldir); -+ -+EXPORT_SYMBOL_PROTO(ioctl); -+ -+EXPORT_SYMBOL_PROTO(pread64); -+EXPORT_SYMBOL_PROTO(pwrite64); -+ -+EXPORT_SYMBOL_PROTO(statfs); -+EXPORT_SYMBOL_PROTO(statfs64); -+ -+EXPORT_SYMBOL_PROTO(getuid); -+ -+/* -+ * 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 -puN arch/um/sys-i386/bugs.c~Main-uml-patch-no-skas arch/um/sys-i386/bugs.c ---- uml-linux-2.6.7/arch/um/sys-i386/bugs.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.642299840 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/bugs.c 2004-06-29 21:02:55.754282816 +0200 -@@ -4,20 +4,21 @@ - */ - - #include <unistd.h> --#include <fcntl.h> - #include <errno.h> - #include <string.h> - #include <sys/signal.h> -+#include <asm/ldt.h> - #include "kern_util.h" - #include "user.h" - #include "sysdep/ptrace.h" - #include "task.h" -+#include "os.h" - - #define MAXTOKEN 64 - - /* Set during early boot */ --int cpu_has_cmov = 1; --int cpu_has_xmm = 0; -+int host_has_cmov = 1; -+int host_has_xmm = 0; - - static char token(int fd, char *buf, int len, char stop) - { -@@ -27,13 +28,15 @@ static char token(int fd, char *buf, int - ptr = buf; - end = &buf[len]; - do { -- n = read(fd, ptr, sizeof(*ptr)); -+ n = os_read_file(fd, ptr, sizeof(*ptr)); - c = *ptr++; -- if(n == 0) return(0); -- else if(n != sizeof(*ptr)){ -- printk("Reading /proc/cpuinfo failed, " -- "errno = %d\n", errno); -- return(-errno); -+ if(n != sizeof(*ptr)){ -+ if(n == 0) return(0); -+ printk("Reading /proc/cpuinfo failed, err = %d\n", -n); -+ if(n < 0) -+ return(n); -+ else -+ return(-EIO); - } - } while((c != '\n') && (c != stop) && (ptr < end)); - -@@ -45,45 +48,79 @@ static char token(int fd, char *buf, int - return(c); - } - --static int check_cpu_feature(char *feature, int *have_it) -+static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) - { -- char buf[MAXTOKEN], c; -- int fd, len = sizeof(buf)/sizeof(buf[0]), n; -- -- printk("Checking for host processor %s support...", feature); -- fd = open("/proc/cpuinfo", O_RDONLY); -- if(fd < 0){ -- printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno); -- return(0); -- } -+ int n; -+ char c; - -- *have_it = 0; -- buf[len - 1] = '\0'; -+ scratch[len - 1] = '\0'; - while(1){ -- c = token(fd, buf, len - 1, ':'); -- if(c <= 0) goto out; -+ c = token(fd, scratch, len - 1, ':'); -+ if(c <= 0) -+ return(0); - else if(c != ':'){ - printk("Failed to find ':' in /proc/cpuinfo\n"); -- goto out; -+ return(0); - } - -- if(!strncmp(buf, "flags", strlen("flags"))) break; -+ if(!strncmp(scratch, key, strlen(key))) -+ return(1); - - do { -- n = read(fd, &c, sizeof(c)); -+ n = os_read_file(fd, &c, sizeof(c)); - if(n != sizeof(c)){ - printk("Failed to find newline in " -- "/proc/cpuinfo, n = %d, errno = %d\n", -- n, errno); -- goto out; -+ "/proc/cpuinfo, err = %d\n", -n); -+ return(0); - } - } while(c != '\n'); - } -+ return(0); -+} -+ -+int cpu_feature(char *what, char *buf, int len) -+{ -+ int fd, ret = 0; -+ -+ fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); -+ return(0); -+ } -+ -+ if(!find_cpuinfo_line(fd, what, buf, len)){ -+ printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); -+ goto out_close; -+ } -+ -+ token(fd, buf, len, '\n'); -+ ret = 1; -+ -+ out_close: -+ os_close_file(fd); -+ return(ret); -+} -+ -+static int check_cpu_flag(char *feature, int *have_it) -+{ -+ char buf[MAXTOKEN], c; -+ int fd, len = sizeof(buf)/sizeof(buf[0]); -+ -+ printk("Checking for host processor %s support...", feature); -+ fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); -+ return(0); -+ } -+ -+ *have_it = 0; -+ if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0]))) -+ goto out; - - c = token(fd, buf, len - 1, ' '); - if(c < 0) goto out; - else if(c != ' '){ -- printk("Failed to find ':' in /proc/cpuinfo\n"); -+ printk("Failed to find ' ' in /proc/cpuinfo\n"); - goto out; - } - -@@ -100,21 +137,48 @@ static int check_cpu_feature(char *featu - out: - if(*have_it == 0) printk("No\n"); - else if(*have_it == 1) printk("Yes\n"); -- close(fd); -+ os_close_file(fd); - return(1); - } - -+#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems -+ * for some people. -+ */ -+static void disable_lcall(void) -+{ -+ struct modify_ldt_ldt_s ldt; -+ int err; -+ -+ bzero(&ldt, sizeof(ldt)); -+ ldt.entry_number = 7; -+ ldt.base_addr = 0; -+ ldt.limit = 0; -+ err = modify_ldt(1, &ldt, sizeof(ldt)); -+ if(err) -+ printk("Failed to disable lcall7 - errno = %d\n", errno); -+} -+#endif -+ -+void arch_init_thread(void) -+{ -+#if 0 -+ disable_lcall(); -+#endif -+} -+ - void arch_check_bugs(void) - { - int have_it; - -- if(access("/proc/cpuinfo", R_OK)){ -+ if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){ - printk("/proc/cpuinfo not available - skipping CPU capability " - "checks\n"); - return; - } -- if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it; -- if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it; -+ if(check_cpu_flag("cmov", &have_it)) -+ host_has_cmov = have_it; -+ if(check_cpu_flag("xmm", &have_it)) -+ host_has_xmm = have_it; - } - - int arch_handle_signal(int sig, union uml_pt_regs *regs) -@@ -130,18 +194,18 @@ int arch_handle_signal(int sig, union um - if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40)) - return(0); - -- if(cpu_has_cmov == 0) -+ if(host_has_cmov == 0) - panic("SIGILL caused by cmov, which this processor doesn't " - "implement, boot a filesystem compiled for older " - "processors"); -- else if(cpu_has_cmov == 1) -+ else if(host_has_cmov == 1) - panic("SIGILL caused by cmov, which this processor claims to " - "implement"); -- else if(cpu_has_cmov == -1) -+ else if(host_has_cmov == -1) - panic("SIGILL caused by cmov, couldn't tell if this processor " - "implements it, boot a filesystem compiled for older " - "processors"); -- else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov); -+ else panic("Bad value for host_has_cmov (%d)", host_has_cmov); - return(0); - } - -diff -L arch/um/sys-i386/extable.c -puN arch/um/sys-i386/extable.c~Main-uml-patch-no-skas /dev/null ---- uml-linux-2.6.7/arch/um/sys-i386/extable.c -+++ /dev/null 1970-01-01 01:00:00.000000000 +0100 -@@ -1,30 +0,0 @@ --/* -- * linux/arch/i386/mm/extable.c -- */ -- --#include <linux/config.h> --#include <linux/module.h> --#include <linux/spinlock.h> --#include <asm/uaccess.h> -- --/* Simple binary search */ --const struct exception_table_entry * --search_extable(const struct exception_table_entry *first, -- const struct exception_table_entry *last, -- unsigned long value) --{ -- while (first <= last) { -- const struct exception_table_entry *mid; -- long diff; -- -- mid = (last - first) / 2 + first; -- diff = mid->insn - value; -- if (diff == 0) -- return mid; -- else if (diff < 0) -- first = mid+1; -- else -- last = mid-1; -- } -- return NULL; --} -diff -puN arch/um/sys-i386/fault.c~Main-uml-patch-no-skas arch/um/sys-i386/fault.c ---- uml-linux-2.6.7/arch/um/sys-i386/fault.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.645299384 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/fault.c 2004-06-29 21:02:55.754282816 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -7,16 +7,24 @@ - #include "sysdep/ptrace.h" - #include "sysdep/sigcontext.h" - --extern unsigned long search_exception_table(unsigned long addr); -+/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -+struct exception_table_entry -+{ -+ unsigned long insn; -+ unsigned long fixup; -+}; - -+const struct exception_table_entry *search_exception_tables(unsigned long add); -+ -+/* Compare this to arch/i386/mm/extable.c:fixup_exception() */ - int arch_fixup(unsigned long address, void *sc_ptr) - { - struct sigcontext *sc = sc_ptr; -- unsigned long fixup; -+ const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if(fixup != 0){ -- sc->eip = fixup; -+ sc->eip = fixup->fixup; - return(1); - } - return(0); -diff -puN arch/um/sys-i386/Makefile~Main-uml-patch-no-skas arch/um/sys-i386/Makefile ---- uml-linux-2.6.7/arch/um/sys-i386/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.646299232 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/Makefile 2004-06-29 21:02:55.755282664 +0200 -@@ -1,7 +1,8 @@ --obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \ -- ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o -+obj-y = bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o ptrace_user.o \ -+ semaphore.o sigcontext.o syscalls.o sysrq.o time.o - - obj-$(CONFIG_HIGHMEM) += highmem.o -+obj-$(CONFIG_MODULES) += module.o - - USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o - USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) -@@ -9,6 +10,8 @@ USER_OBJS := $(foreach file,$(USER_OBJS) - SYMLINKS = semaphore.c highmem.c module.c - SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f) - -+clean-files := $(SYMLINKS) -+ - semaphore.c-dir = kernel - highmem.c-dir = mm - module.c-dir = kernel -@@ -24,19 +27,4 @@ $(USER_OBJS) : %.o: %.c - $(SYMLINKS): - $(call make_link,$@) - --clean: -- $(MAKE) -C util clean -- --fastdep: -- --dep: -- --archmrproper: -- rm -f $(SYMLINKS) -- --archclean: -- --archdep: -- --modules: -- -+subdir- := util -diff -puN arch/um/sys-i386/ptrace_user.c~Main-uml-patch-no-skas arch/um/sys-i386/ptrace_user.c ---- uml-linux-2.6.7/arch/um/sys-i386/ptrace_user.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.647299080 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/ptrace_user.c 2004-06-29 21:02:55.755282664 +0200 -@@ -39,10 +39,10 @@ static void write_debugregs(int pid, uns - nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]); - for(i = 0; i < nregs; i++){ - if((i == 4) || (i == 5)) continue; -- if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], -+ if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i], - regs[i]) < 0) -- printk("write_debugregs - ptrace failed, " -- "errno = %d\n", errno); -+ printk("write_debugregs - ptrace failed on " -+ "register %d, errno = %d\n", errno); - } - } - -@@ -54,7 +54,7 @@ static void read_debugregs(int pid, unsi - dummy = NULL; - nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]); - for(i = 0; i < nregs; i++){ -- regs[i] = ptrace(PTRACE_PEEKUSR, pid, -+ regs[i] = ptrace(PTRACE_PEEKUSER, pid, - &dummy->u_debugreg[i], 0); - } - } -diff -puN /dev/null arch/um/sys-i386/time.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/time.c 2004-06-29 21:02:55.755282664 +0200 -@@ -0,0 +1,24 @@ -+/* -+ * sys-i386/time.c -+ * Created 25.9.2002 Sapan Bhatia -+ * -+ */ -+ -+unsigned long long time_stamp(void) -+{ -+ unsigned long low, high; -+ -+ asm("rdtsc" : "=a" (low), "=d" (high)); -+ return((((unsigned long long) high) << 32) + low); -+} -+ -+/* -+ * 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 -puN arch/um/sys-i386/util/Makefile~Main-uml-patch-no-skas arch/um/sys-i386/util/Makefile ---- uml-linux-2.6.7/arch/um/sys-i386/util/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.648298928 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/util/Makefile 2004-06-29 21:02:55.755282664 +0200 -@@ -1,15 +1,10 @@ -+host-progs := mk_sc mk_thread -+always := $(host-progs) - --host-progs := mk_sc --always := $(host-progs) mk_thread --targets := mk_thread_kern.o mk_thread_user.o -+mk_thread-objs := mk_thread_kern.o mk_thread_user.o - --mk_sc-objs := mk_sc.o -- --$(obj)/mk_thread : $(obj)/mk_thread_kern.o $(obj)/mk_thread_user.o -- $(CC) $(CFLAGS) -o $@ $^ -- --$(obj)/mk_thread_user.o : $(src)/mk_thread_user.c -- $(CC) $(USER_CFLAGS) -c -o $@ $< -+HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS) -+HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS) - - clean : - $(RM) -f $(build-targets) -diff -puN arch/um/sys-i386/util/mk_sc.c~Main-uml-patch-no-skas arch/um/sys-i386/util/mk_sc.c ---- uml-linux-2.6.7/arch/um/sys-i386/util/mk_sc.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.649298776 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/util/mk_sc.c 2004-06-29 21:02:55.755282664 +0200 -@@ -38,6 +38,7 @@ int main(int argc, char **argv) - 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); -diff -puN arch/um/sys-ia64/Makefile~Main-uml-patch-no-skas arch/um/sys-ia64/Makefile ---- uml-linux-2.6.7/arch/um/sys-ia64/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.650298624 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-ia64/Makefile 2004-06-29 21:02:55.756282512 +0200 -@@ -7,18 +7,5 @@ all: $(OBJ) - $(OBJ): $(OBJS) - rm -f $@ - $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@ --clean: -- rm -f $(OBJS) - --fastdep: -- --archmrproper: -- --archclean: -- rm -f link.ld -- @$(MAKEBOOT) clean -- --archdep: -- @$(MAKEBOOT) dep -- --modules: -+clean-files := $(OBJS) link.ld -diff -puN arch/um/sys-ppc/Makefile~Main-uml-patch-no-skas arch/um/sys-ppc/Makefile ---- uml-linux-2.6.7/arch/um/sys-ppc/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.652298320 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-ppc/Makefile 2004-06-29 21:02:55.756282512 +0200 -@@ -66,13 +66,4 @@ misc.o: misc.S ppc_defs.h - $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o - rm -f asm - --clean: -- rm -f $(OBJS) -- rm -f ppc_defs.h -- rm -f checksum.S semaphore.c mk_defs.c -- --fastdep: -- --dep: -- --modules: -+clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c -diff -puN arch/um/uml.lds.S~Main-uml-patch-no-skas arch/um/uml.lds.S ---- uml-linux-2.6.7/arch/um/uml.lds.S~Main-uml-patch-no-skas 2004-06-29 21:02:55.653298168 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/uml.lds.S 2004-06-29 21:02:55.756282512 +0200 -@@ -9,7 +9,6 @@ SECTIONS - { - . = START + SIZEOF_HEADERS; - -- . = ALIGN(4096); - __binary_start = .; - #ifdef MODE_TT - .thread_private : { -@@ -26,11 +25,16 @@ SECTIONS - . = ALIGN(4096); /* Init code and data */ - _stext = .; - __init_begin = .; -- .text.init : { *(.text.init) } -+ .init.text : { -+ _sinittext = .; -+ *(.init.text) -+ _einittext = .; -+ } - . = ALIGN(4096); - .text : - { - *(.text) -+ SCHED_TEXT - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) -@@ -38,7 +42,7 @@ SECTIONS - - #include "asm/common.lds.S" - -- .data.init : { *(.data.init) } -+ init.data : { *(init.data) } - .data : - { - . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ -diff -puN arch/um/util/Makefile~Main-uml-patch-no-skas arch/um/util/Makefile ---- uml-linux-2.6.7/arch/um/util/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.654298016 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/util/Makefile 2004-06-29 21:02:55.756282512 +0200 -@@ -1,23 +1,8 @@ --always := mk_task mk_constants --targets := mk_task_user.o mk_task_kern.o \ -- mk_constants_user.o mk_constants_kern.o -+host-progs := mk_task mk_constants -+always := $(host-progs) - --$(obj)/mk_task: $(obj)/mk_task_user.o $(obj)/mk_task_kern.o -- $(CC) -o $@ $^ -+mk_task-objs := mk_task_user.o mk_task_kern.o -+mk_constants-objs := mk_constants_user.o mk_constants_kern.o - --$(obj)/mk_task_user.o: $(src)/mk_task_user.c -- $(CC) -o $@ -c $< -- --$(obj)/mk_constants : $(obj)/mk_constants_user.o $(obj)/mk_constants_kern.o -- $(CC) -o $@ $^ -- --$(obj)/mk_constants_user.o : $(src)/mk_constants_user.c -- $(CC) -c $< -o $@ -- --$(obj)/mk_constants_kern.o : $(src)/mk_constants_kern.c -- $(CC) $(CFLAGS) -c $< -o $@ -- --clean: -- $(RM) $(build-targets) -- --archmrproper: -+HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS) -+HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS) -diff -puN arch/um/util/mk_constants_kern.c~Main-uml-patch-no-skas arch/um/util/mk_constants_kern.c ---- uml-linux-2.6.7/arch/um/util/mk_constants_kern.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.655297864 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/util/mk_constants_kern.c 2004-06-29 21:02:55.757282360 +0200 -@@ -1,5 +1,6 @@ - #include "linux/kernel.h" - #include "linux/stringify.h" -+#include "linux/time.h" - #include "asm/page.h" - - extern void print_head(void); -@@ -11,6 +12,7 @@ int main(int argc, char **argv) - { - print_head(); - print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE); -+ - print_constant_str("UM_KERN_EMERG", KERN_EMERG); - print_constant_str("UM_KERN_ALERT", KERN_ALERT); - print_constant_str("UM_KERN_CRIT", KERN_CRIT); -@@ -19,6 +21,8 @@ int main(int argc, char **argv) - print_constant_str("UM_KERN_NOTICE", KERN_NOTICE); - print_constant_str("UM_KERN_INFO", KERN_INFO); - print_constant_str("UM_KERN_DEBUG", KERN_DEBUG); -+ -+ print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC); - print_tail(); - return(0); - } -diff -puN /dev/null fs/hostfs/hostfs.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/fs/hostfs/hostfs.h 2004-06-29 21:02:55.757282360 +0200 -@@ -0,0 +1,79 @@ -+#ifndef __UM_FS_HOSTFS -+#define __UM_FS_HOSTFS -+ -+#include "os.h" -+ -+/* These are exactly the same definitions as in fs.h, but the names are -+ * changed so that this file can be included in both kernel and user files. -+ */ -+ -+#define HOSTFS_ATTR_MODE 1 -+#define HOSTFS_ATTR_UID 2 -+#define HOSTFS_ATTR_GID 4 -+#define HOSTFS_ATTR_SIZE 8 -+#define HOSTFS_ATTR_ATIME 16 -+#define HOSTFS_ATTR_MTIME 32 -+#define HOSTFS_ATTR_CTIME 64 -+#define HOSTFS_ATTR_ATIME_SET 128 -+#define HOSTFS_ATTR_MTIME_SET 256 -+#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */ -+#define HOSTFS_ATTR_ATTR_FLAG 1024 -+ -+struct hostfs_iattr { -+ unsigned int ia_valid; -+ mode_t ia_mode; -+ uid_t ia_uid; -+ gid_t ia_gid; -+ loff_t ia_size; -+ struct timespec ia_atime; -+ struct timespec ia_mtime; -+ struct timespec ia_ctime; -+ unsigned int ia_attr_flags; -+}; -+ -+extern int stat_file(const char *path, unsigned long long *inode_out, -+ int *mode_out, int *nlink_out, int *uid_out, int *gid_out, -+ unsigned long long *size_out, struct timespec *atime_out, -+ struct timespec *mtime_out, struct timespec *ctime_out, -+ int *blksize_out, unsigned long long *blocks_out); -+extern int access_file(char *path, int r, int w, int x); -+extern int open_file(char *path, int r, int w, int append); -+extern int file_type(const char *path, int *rdev); -+extern void *open_dir(char *path, int *err_out); -+extern char *read_dir(void *stream, unsigned long long *pos, -+ unsigned long long *ino_out, int *len_out); -+extern void close_file(void *stream); -+extern void close_dir(void *stream); -+extern int read_file(int fd, unsigned long long *offset, char *buf, int len); -+extern int write_file(int fd, unsigned long long *offset, const char *buf, -+ int len); -+extern int lseek_file(int fd, long long offset, int whence); -+extern int file_create(char *name, int ur, int uw, int ux, int gr, -+ int gw, int gx, int or, int ow, int ox); -+extern int set_attr(const char *file, struct hostfs_iattr *attrs); -+extern int make_symlink(const char *from, const char *to); -+extern int unlink_file(const char *file); -+extern int do_mkdir(const char *file, int mode); -+extern int do_rmdir(const char *file); -+extern int do_mknod(const char *file, int mode, int dev); -+extern int link_file(const char *from, const char *to); -+extern int do_readlink(char *file, char *buf, int size); -+extern int rename_file(char *from, char *to); -+extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, -+ long long *bfree_out, long long *bavail_out, -+ long long *files_out, long long *ffree_out, -+ void *fsid_out, int fsid_size, long *namelen_out, -+ long *spare_out); -+ -+#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 -puN /dev/null fs/hostfs/hostfs_kern.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/fs/hostfs/hostfs_kern.c 2004-06-29 21:02:55.758282208 +0200 -@@ -0,0 +1,1008 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ * -+ * Ported the filesystem routines to 2.5. -+ * 2003-02-10 Petr Baudis <pasky@ucw.cz> -+ */ -+ -+#include <linux/stddef.h> -+#include <linux/fs.h> -+#include <linux/version.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/pagemap.h> -+#include <linux/blkdev.h> -+#include <linux/list.h> -+#include <linux/buffer_head.h> -+#include <linux/root_dev.h> -+#include <linux/statfs.h> -+#include <asm/uaccess.h> -+#include "hostfs.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "user_util.h" -+#include "2_5compat.h" -+#include "init.h" -+ -+struct hostfs_inode_info { -+ char *host_filename; -+ int fd; -+ int mode; -+ struct inode vfs_inode; -+}; -+ -+static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) -+{ -+ return(list_entry(inode, struct hostfs_inode_info, vfs_inode)); -+} -+ -+#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode) -+ -+int hostfs_d_delete(struct dentry *dentry) -+{ -+ return(1); -+} -+ -+struct dentry_operations hostfs_dentry_ops = { -+ .d_delete = hostfs_d_delete, -+}; -+ -+/* Changed in hostfs_args before the kernel starts running */ -+static char *root_ino = "/"; -+static int append = 0; -+ -+#define HOSTFS_SUPER_MAGIC 0x00c0ffee -+ -+static struct inode_operations hostfs_iops; -+static struct inode_operations hostfs_dir_iops; -+static struct address_space_operations hostfs_link_aops; -+ -+static int __init hostfs_args(char *options, int *add) -+{ -+ char *ptr; -+ -+ ptr = strchr(options, ','); -+ if(ptr != NULL) -+ *ptr++ = '\0'; -+ if(*options != '\0') -+ root_ino = options; -+ -+ options = ptr; -+ while(options){ -+ ptr = strchr(options, ','); -+ if(ptr != NULL) -+ *ptr++ = '\0'; -+ if(*options != '\0'){ -+ if(!strcmp(options, "append")) -+ append = 1; -+ else printf("hostfs_args - unsupported option - %s\n", -+ options); -+ } -+ options = ptr; -+ } -+ return(0); -+} -+ -+__uml_setup("hostfs=", hostfs_args, -+"hostfs=<root dir>,<flags>,...\n" -+" This is used to set hostfs parameters. The root directory argument\n" -+" is used to confine all hostfs mounts to within the specified directory\n" -+" tree on the host. If this isn't specified, then a user inside UML can\n" -+" mount anything on the host that's accessible to the user that's running\n" -+" it.\n" -+" The only flag currently supported is 'append', which specifies that all\n" -+" files opened by hostfs will be opened in append mode.\n\n" -+); -+ -+static char *dentry_name(struct dentry *dentry, int extra) -+{ -+ struct dentry *parent; -+ char *root, *name; -+ int len; -+ -+ len = 0; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ len += parent->d_name.len + 1; -+ parent = parent->d_parent; -+ } -+ -+ root = HOSTFS_I(parent->d_inode)->host_filename; -+ len += strlen(root); -+ name = kmalloc(len + extra + 1, GFP_KERNEL); -+ if(name == NULL) return(NULL); -+ -+ name[len] = '\0'; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ len -= parent->d_name.len + 1; -+ name[len] = '/'; -+ strncpy(&name[len + 1], parent->d_name.name, -+ parent->d_name.len); -+ parent = parent->d_parent; -+ } -+ strncpy(name, root, strlen(root)); -+ return(name); -+} -+ -+static char *inode_name(struct inode *ino, int extra) -+{ -+ struct dentry *dentry; -+ -+ dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias); -+ return(dentry_name(dentry, extra)); -+} -+ -+static int read_name(struct inode *ino, char *name) -+{ -+ /* The non-int inode fields are copied into ints by stat_file and -+ * then copied into the inode because passing the actual pointers -+ * in and having them treated as int * breaks on big-endian machines -+ */ -+ int err; -+ int i_mode, i_nlink, i_blksize; -+ unsigned long long i_size; -+ unsigned long long i_ino; -+ unsigned long long i_blocks; -+ -+ err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, -+ &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, -+ &ino->i_ctime, &i_blksize, &i_blocks); -+ if(err) -+ return(err); -+ -+ ino->i_ino = i_ino; -+ ino->i_mode = i_mode; -+ ino->i_nlink = i_nlink; -+ ino->i_size = i_size; -+ ino->i_blksize = i_blksize; -+ ino->i_blocks = i_blocks; -+ if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid())) -+ ino->i_uid = 0; -+ return(0); -+} -+ -+static char *follow_link(char *link) -+{ -+ int len, n; -+ char *name, *resolved, *end; -+ -+ len = 64; -+ while(1){ -+ n = -ENOMEM; -+ name = kmalloc(len, GFP_KERNEL); -+ if(name == NULL) -+ goto out; -+ -+ n = do_readlink(link, name, len); -+ if(n < len) -+ break; -+ len *= 2; -+ kfree(name); -+ } -+ if(n < 0) -+ goto out_free; -+ -+ if(*name == '/') -+ return(name); -+ -+ end = strrchr(link, '/'); -+ if(end == NULL) -+ return(name); -+ -+ *(end + 1) = '\0'; -+ len = strlen(link) + strlen(name) + 1; -+ -+ resolved = kmalloc(len, GFP_KERNEL); -+ if(resolved == NULL){ -+ n = -ENOMEM; -+ goto out_free; -+ } -+ -+ sprintf(resolved, "%s%s", link, name); -+ kfree(name); -+ kfree(link); -+ return(resolved); -+ -+ out_free: -+ kfree(name); -+ out: -+ return(ERR_PTR(n)); -+} -+ -+static int read_inode(struct inode *ino) -+{ -+ char *name; -+ int err = 0; -+ -+ /* Unfortunately, we are called from iget() when we don't have a dentry -+ * allocated yet. -+ */ -+ if(list_empty(&ino->i_dentry)) -+ goto out; -+ -+ err = -ENOMEM; -+ name = inode_name(ino, 0); -+ if(name == NULL) -+ goto out; -+ -+ if(file_type(name, NULL) == OS_TYPE_SYMLINK){ -+ name = follow_link(name); -+ if(IS_ERR(name)){ -+ err = PTR_ERR(name); -+ goto out; -+ } -+ } -+ -+ err = read_name(ino, name); -+ kfree(name); -+ out: -+ return(err); -+} -+ -+int hostfs_statfs(struct super_block *sb, struct kstatfs *sf) -+{ -+ /* do_statfs uses struct statfs64 internally, but the linux kernel -+ * struct statfs still has 32-bit versions for most of these fields, -+ * so we convert them here -+ */ -+ int err; -+ long long f_blocks; -+ long long f_bfree; -+ long long f_bavail; -+ long long f_files; -+ long long f_ffree; -+ -+ err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename, -+ &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, -+ &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), -+ &sf->f_namelen, sf->f_spare); -+ if(err) return(err); -+ sf->f_blocks = f_blocks; -+ sf->f_bfree = f_bfree; -+ sf->f_bavail = f_bavail; -+ sf->f_files = f_files; -+ sf->f_ffree = f_ffree; -+ sf->f_type = HOSTFS_SUPER_MAGIC; -+ return(0); -+} -+ -+static struct inode *hostfs_alloc_inode(struct super_block *sb) -+{ -+ struct hostfs_inode_info *hi; -+ -+ hi = kmalloc(sizeof(*hi), GFP_KERNEL); -+ if(hi == NULL) -+ return(NULL); -+ -+ *hi = ((struct hostfs_inode_info) { .host_filename = NULL, -+ .fd = -1, -+ .mode = 0 }); -+ inode_init_once(&hi->vfs_inode); -+ return(&hi->vfs_inode); -+} -+ -+static void hostfs_destroy_inode(struct inode *inode) -+{ -+ if(HOSTFS_I(inode)->host_filename) -+ kfree(HOSTFS_I(inode)->host_filename); -+ -+ if(HOSTFS_I(inode)->fd != -1) -+ close_file(&HOSTFS_I(inode)->fd); -+ -+ kfree(HOSTFS_I(inode)); -+} -+ -+static void hostfs_read_inode(struct inode *inode) -+{ -+ read_inode(inode); -+} -+ -+static struct super_operations hostfs_sbops = { -+ .alloc_inode = hostfs_alloc_inode, -+ .destroy_inode = hostfs_destroy_inode, -+ .read_inode = hostfs_read_inode, -+ .statfs = hostfs_statfs, -+}; -+ -+int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) -+{ -+ void *dir; -+ char *name; -+ unsigned long long next, ino; -+ int error, len; -+ -+ name = dentry_name(file->f_dentry, 0); -+ if(name == NULL) return(-ENOMEM); -+ dir = open_dir(name, &error); -+ kfree(name); -+ if(dir == NULL) return(-error); -+ next = file->f_pos; -+ while((name = read_dir(dir, &next, &ino, &len)) != NULL){ -+ error = (*filldir)(ent, name, len, file->f_pos, -+ ino, DT_UNKNOWN); -+ if(error) break; -+ file->f_pos = next; -+ } -+ close_dir(dir); -+ return(0); -+} -+ -+int hostfs_file_open(struct inode *ino, struct file *file) -+{ -+ char *name; -+ int mode = 0, r = 0, w = 0, fd; -+ -+ mode = file->f_mode & (FMODE_READ | FMODE_WRITE); -+ if((mode & HOSTFS_I(ino)->mode) == mode) -+ return(0); -+ -+ /* The file may already have been opened, but with the wrong access, -+ * so this resets things and reopens the file with the new access. -+ */ -+ if(HOSTFS_I(ino)->fd != -1){ -+ close_file(&HOSTFS_I(ino)->fd); -+ HOSTFS_I(ino)->fd = -1; -+ } -+ -+ HOSTFS_I(ino)->mode |= mode; -+ if(HOSTFS_I(ino)->mode & FMODE_READ) -+ r = 1; -+ if(HOSTFS_I(ino)->mode & FMODE_WRITE) -+ w = 1; -+ if(w) -+ r = 1; -+ -+ name = dentry_name(file->f_dentry, 0); -+ if(name == NULL) -+ return(-ENOMEM); -+ -+ fd = open_file(name, r, w, append); -+ kfree(name); -+ if(fd < 0) return(fd); -+ FILE_HOSTFS_I(file)->fd = fd; -+ -+ return(0); -+} -+ -+int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) -+{ -+ return(0); -+} -+ -+static struct file_operations hostfs_file_fops = { -+ .llseek = generic_file_llseek, -+ .read = generic_file_read, -+ .write = generic_file_write, -+ .mmap = generic_file_mmap, -+ .open = hostfs_file_open, -+ .release = NULL, -+ .fsync = hostfs_fsync, -+}; -+ -+static struct file_operations hostfs_dir_fops = { -+ .readdir = hostfs_readdir, -+ .read = generic_read_dir, -+}; -+ -+int hostfs_writepage(struct page *page, struct writeback_control *wbc) -+{ -+ struct address_space *mapping = page->mapping; -+ struct inode *inode = mapping->host; -+ char *buffer; -+ unsigned long long base; -+ int count = PAGE_CACHE_SIZE; -+ int end_index = inode->i_size >> PAGE_CACHE_SHIFT; -+ int err; -+ -+ if (page->index >= end_index) -+ count = inode->i_size & (PAGE_CACHE_SIZE-1); -+ -+ buffer = kmap(page); -+ base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT; -+ -+ err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count); -+ if(err != count){ -+ ClearPageUptodate(page); -+ goto out; -+ } -+ -+ if (base > inode->i_size) -+ inode->i_size = base; -+ -+ if (PageError(page)) -+ ClearPageError(page); -+ err = 0; -+ -+ out: -+ kunmap(page); -+ -+ unlock_page(page); -+ return err; -+} -+ -+int hostfs_readpage(struct file *file, struct page *page) -+{ -+ char *buffer; -+ long long start; -+ int err = 0; -+ -+ start = (long long) page->index << PAGE_CACHE_SHIFT; -+ buffer = kmap(page); -+ err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer, -+ PAGE_CACHE_SIZE); -+ if(err < 0) goto out; -+ -+ memset(&buffer[err], 0, PAGE_CACHE_SIZE - err); -+ -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ if (PageError(page)) ClearPageError(page); -+ err = 0; -+ out: -+ kunmap(page); -+ unlock_page(page); -+ return(err); -+} -+ -+int hostfs_prepare_write(struct file *file, struct page *page, -+ unsigned int from, unsigned int to) -+{ -+ char *buffer; -+ long long start, tmp; -+ int err; -+ -+ start = (long long) page->index << PAGE_CACHE_SHIFT; -+ buffer = kmap(page); -+ if(from != 0){ -+ tmp = start; -+ err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer, -+ from); -+ if(err < 0) goto out; -+ } -+ if(to != PAGE_CACHE_SIZE){ -+ start += to; -+ err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to, -+ PAGE_CACHE_SIZE - to); -+ if(err < 0) goto out; -+ } -+ err = 0; -+ out: -+ kunmap(page); -+ return(err); -+} -+ -+int hostfs_commit_write(struct file *file, struct page *page, unsigned from, -+ unsigned to) -+{ -+ struct address_space *mapping = page->mapping; -+ struct inode *inode = mapping->host; -+ char *buffer; -+ long long start; -+ int err = 0; -+ -+ start = (long long) (page->index << PAGE_CACHE_SHIFT) + from; -+ buffer = kmap(page); -+ err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, -+ to - from); -+ if(err > 0) err = 0; -+ if(!err && (start > inode->i_size)) -+ inode->i_size = start; -+ -+ kunmap(page); -+ return(err); -+} -+ -+static struct address_space_operations hostfs_aops = { -+ .writepage = hostfs_writepage, -+ .readpage = hostfs_readpage, -+/* .set_page_dirty = __set_page_dirty_nobuffers, */ -+ .prepare_write = hostfs_prepare_write, -+ .commit_write = hostfs_commit_write -+}; -+ -+static int init_inode(struct inode *inode, struct dentry *dentry) -+{ -+ char *name; -+ int type, err = -ENOMEM, rdev; -+ -+ if(dentry){ -+ name = dentry_name(dentry, 0); -+ if(name == NULL) -+ goto out; -+ type = file_type(name, &rdev); -+ kfree(name); -+ } -+ else type = OS_TYPE_DIR; -+ -+ err = 0; -+ if(type == OS_TYPE_SYMLINK) -+ inode->i_op = &page_symlink_inode_operations; -+ else if(type == OS_TYPE_DIR) -+ inode->i_op = &hostfs_dir_iops; -+ else inode->i_op = &hostfs_iops; -+ -+ if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops; -+ else inode->i_fop = &hostfs_file_fops; -+ -+ if(type == OS_TYPE_SYMLINK) -+ inode->i_mapping->a_ops = &hostfs_link_aops; -+ else inode->i_mapping->a_ops = &hostfs_aops; -+ -+ switch (type) { -+ case OS_TYPE_CHARDEV: -+ init_special_inode(inode, S_IFCHR, rdev); -+ break; -+ case OS_TYPE_BLOCKDEV: -+ init_special_inode(inode, S_IFBLK, rdev); -+ break; -+ case OS_TYPE_FIFO: -+ init_special_inode(inode, S_IFIFO, 0); -+ break; -+ case OS_TYPE_SOCK: -+ init_special_inode(inode, S_IFSOCK, 0); -+ break; -+ } -+ out: -+ return(err); -+} -+ -+int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, -+ struct nameidata *nd) -+{ -+ struct inode *inode; -+ char *name; -+ int error, fd; -+ -+ error = -ENOMEM; -+ inode = iget(dir->i_sb, 0); -+ if(inode == NULL) goto out; -+ -+ error = init_inode(inode, dentry); -+ if(error) -+ goto out_put; -+ -+ error = -ENOMEM; -+ name = dentry_name(dentry, 0); -+ if(name == NULL) -+ goto out_put; -+ -+ fd = file_create(name, -+ mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, -+ mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, -+ mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH); -+ if(fd < 0) -+ error = fd; -+ else error = read_name(inode, name); -+ -+ kfree(name); -+ if(error) -+ goto out_put; -+ -+ HOSTFS_I(inode)->fd = fd; -+ HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE; -+ d_instantiate(dentry, inode); -+ return(0); -+ -+ out_put: -+ iput(inode); -+ out: -+ return(error); -+} -+ -+struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, -+ struct nameidata *nd) -+{ -+ struct inode *inode; -+ char *name; -+ int err; -+ -+ err = -ENOMEM; -+ inode = iget(ino->i_sb, 0); -+ if(inode == NULL) -+ goto out; -+ -+ err = init_inode(inode, dentry); -+ if(err) -+ goto out_put; -+ -+ err = -ENOMEM; -+ name = dentry_name(dentry, 0); -+ if(name == NULL) -+ goto out_put; -+ -+ err = read_name(inode, name); -+ kfree(name); -+ if(err == -ENOENT){ -+ iput(inode); -+ inode = NULL; -+ } -+ else if(err) -+ goto out_put; -+ -+ d_add(dentry, inode); -+ dentry->d_op = &hostfs_dentry_ops; -+ return(NULL); -+ -+ out_put: -+ iput(inode); -+ out: -+ return(ERR_PTR(err)); -+} -+ -+static char *inode_dentry_name(struct inode *ino, struct dentry *dentry) -+{ -+ char *file; -+ int len; -+ -+ file = inode_name(ino, dentry->d_name.len + 1); -+ if(file == NULL) return(NULL); -+ strcat(file, "/"); -+ len = strlen(file); -+ strncat(file, dentry->d_name.name, dentry->d_name.len); -+ file[len + dentry->d_name.len] = '\0'; -+ return(file); -+} -+ -+int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from) -+{ -+ char *from_name, *to_name; -+ int err; -+ -+ if((from_name = inode_dentry_name(ino, from)) == NULL) -+ return(-ENOMEM); -+ to_name = dentry_name(to, 0); -+ if(to_name == NULL){ -+ kfree(from_name); -+ return(-ENOMEM); -+ } -+ err = link_file(to_name, from_name); -+ kfree(from_name); -+ kfree(to_name); -+ return(err); -+} -+ -+int hostfs_unlink(struct inode *ino, struct dentry *dentry) -+{ -+ char *file; -+ int err; -+ -+ if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); -+ if(append) -+ return(-EPERM); -+ -+ err = unlink_file(file); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) -+{ -+ char *file; -+ int err; -+ -+ if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); -+ err = make_symlink(file, to); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode) -+{ -+ char *file; -+ int err; -+ -+ if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); -+ err = do_mkdir(file, mode); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_rmdir(struct inode *ino, struct dentry *dentry) -+{ -+ char *file; -+ int err; -+ -+ if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM); -+ err = do_rmdir(file); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -+{ -+ struct inode *inode; -+ char *name; -+ int err = -ENOMEM; -+ -+ inode = iget(dir->i_sb, 0); -+ if(inode == NULL) -+ goto out; -+ -+ err = init_inode(inode, dentry); -+ if(err) -+ goto out_put; -+ -+ err = -ENOMEM; -+ name = dentry_name(dentry, 0); -+ if(name == NULL) -+ goto out_put; -+ -+ init_special_inode(inode, mode, dev); -+ err = do_mknod(name, mode, dev); -+ if(err) -+ goto out_free; -+ -+ err = read_name(inode, name); -+ kfree(name); -+ if(err) -+ goto out_put; -+ -+ d_instantiate(dentry, inode); -+ return(0); -+ -+ out_free: -+ kfree(name); -+ out_put: -+ iput(inode); -+ out: -+ return(err); -+} -+ -+int hostfs_rename(struct inode *from_ino, struct dentry *from, -+ struct inode *to_ino, struct dentry *to) -+{ -+ char *from_name, *to_name; -+ int err; -+ -+ if((from_name = inode_dentry_name(from_ino, from)) == NULL) -+ return(-ENOMEM); -+ if((to_name = inode_dentry_name(to_ino, to)) == NULL){ -+ kfree(from_name); -+ return(-ENOMEM); -+ } -+ err = rename_file(from_name, to_name); -+ kfree(from_name); -+ kfree(to_name); -+ return(err); -+} -+ -+void hostfs_truncate(struct inode *ino) -+{ -+ not_implemented(); -+} -+ -+int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd) -+{ -+ char *name; -+ int r = 0, w = 0, x = 0, err; -+ -+ if(desired & MAY_READ) r = 1; -+ if(desired & MAY_WRITE) w = 1; -+ if(desired & MAY_EXEC) x = 1; -+ name = inode_name(ino, 0); -+ if(name == NULL) return(-ENOMEM); -+ err = access_file(name, r, w, x); -+ kfree(name); -+ if(!err) err = vfs_permission(ino, desired); -+ return(err); -+} -+ -+int hostfs_setattr(struct dentry *dentry, struct iattr *attr) -+{ -+ struct hostfs_iattr attrs; -+ char *name; -+ int err; -+ -+ if(append) -+ attr->ia_valid &= ~ATTR_SIZE; -+ -+ attrs.ia_valid = 0; -+ if(attr->ia_valid & ATTR_MODE){ -+ attrs.ia_valid |= HOSTFS_ATTR_MODE; -+ attrs.ia_mode = attr->ia_mode; -+ } -+ if(attr->ia_valid & ATTR_UID){ -+ if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && -+ (attr->ia_uid == 0)) -+ attr->ia_uid = getuid(); -+ attrs.ia_valid |= HOSTFS_ATTR_UID; -+ attrs.ia_uid = attr->ia_uid; -+ } -+ if(attr->ia_valid & ATTR_GID){ -+ if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && -+ (attr->ia_gid == 0)) -+ attr->ia_gid = getuid(); -+ attrs.ia_valid |= HOSTFS_ATTR_GID; -+ attrs.ia_gid = attr->ia_gid; -+ } -+ if(attr->ia_valid & ATTR_SIZE){ -+ attrs.ia_valid |= HOSTFS_ATTR_SIZE; -+ attrs.ia_size = attr->ia_size; -+ } -+ if(attr->ia_valid & ATTR_ATIME){ -+ attrs.ia_valid |= HOSTFS_ATTR_ATIME; -+ attrs.ia_atime = attr->ia_atime; -+ } -+ if(attr->ia_valid & ATTR_MTIME){ -+ attrs.ia_valid |= HOSTFS_ATTR_MTIME; -+ attrs.ia_mtime = attr->ia_mtime; -+ } -+ if(attr->ia_valid & ATTR_CTIME){ -+ attrs.ia_valid |= HOSTFS_ATTR_CTIME; -+ attrs.ia_ctime = attr->ia_ctime; -+ } -+ if(attr->ia_valid & ATTR_ATIME_SET){ -+ attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET; -+ } -+ if(attr->ia_valid & ATTR_MTIME_SET){ -+ attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET; -+ } -+ name = dentry_name(dentry, 0); -+ if(name == NULL) return(-ENOMEM); -+ err = set_attr(name, &attrs); -+ kfree(name); -+ if(err) -+ return(err); -+ -+ return(inode_setattr(dentry->d_inode, attr)); -+} -+ -+int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, -+ struct kstat *stat) -+{ -+ generic_fillattr(dentry->d_inode, stat); -+ return(0); -+} -+ -+static struct inode_operations hostfs_iops = { -+ .create = hostfs_create, -+ .link = hostfs_link, -+ .unlink = hostfs_unlink, -+ .symlink = hostfs_symlink, -+ .mkdir = hostfs_mkdir, -+ .rmdir = hostfs_rmdir, -+ .mknod = hostfs_mknod, -+ .rename = hostfs_rename, -+ .truncate = hostfs_truncate, -+ .permission = hostfs_permission, -+ .setattr = hostfs_setattr, -+ .getattr = hostfs_getattr, -+}; -+ -+static struct inode_operations hostfs_dir_iops = { -+ .create = hostfs_create, -+ .lookup = hostfs_lookup, -+ .link = hostfs_link, -+ .unlink = hostfs_unlink, -+ .symlink = hostfs_symlink, -+ .mkdir = hostfs_mkdir, -+ .rmdir = hostfs_rmdir, -+ .mknod = hostfs_mknod, -+ .rename = hostfs_rename, -+ .truncate = hostfs_truncate, -+ .permission = hostfs_permission, -+ .setattr = hostfs_setattr, -+ .getattr = hostfs_getattr, -+}; -+ -+int hostfs_link_readpage(struct file *file, struct page *page) -+{ -+ char *buffer, *name; -+ long long start; -+ int err; -+ -+ start = page->index << PAGE_CACHE_SHIFT; -+ buffer = kmap(page); -+ name = inode_name(page->mapping->host, 0); -+ if(name == NULL) return(-ENOMEM); -+ err = do_readlink(name, buffer, PAGE_CACHE_SIZE); -+ kfree(name); -+ if(err == PAGE_CACHE_SIZE) -+ err = -E2BIG; -+ else if(err > 0){ -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ if (PageError(page)) ClearPageError(page); -+ err = 0; -+ } -+ kunmap(page); -+ unlock_page(page); -+ return(err); -+} -+ -+static struct address_space_operations hostfs_link_aops = { -+ .readpage = hostfs_link_readpage, -+}; -+ -+static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) -+{ -+ struct inode *root_inode; -+ char *name, *data = d; -+ int err; -+ -+ sb->s_blocksize = 1024; -+ sb->s_blocksize_bits = 10; -+ sb->s_magic = HOSTFS_SUPER_MAGIC; -+ sb->s_op = &hostfs_sbops; -+ -+ if((data == NULL) || (*data == '\0')) -+ data = root_ino; -+ -+ err = -ENOMEM; -+ name = kmalloc(strlen(data) + 1, GFP_KERNEL); -+ if(name == NULL) -+ goto out; -+ -+ strcpy(name, data); -+ -+ root_inode = iget(sb, 0); -+ if(root_inode == NULL) -+ goto out_free; -+ -+ err = init_inode(root_inode, NULL); -+ if(err) -+ goto out_put; -+ -+ HOSTFS_I(root_inode)->host_filename = name; -+ -+ err = -ENOMEM; -+ sb->s_root = d_alloc_root(root_inode); -+ if(sb->s_root == NULL) -+ goto out_put; -+ -+ err = read_inode(root_inode); -+ if(err) -+ goto out_put; -+ -+ return(0); -+ -+ out_put: -+ iput(root_inode); -+ out_free: -+ kfree(name); -+ out: -+ return(err); -+} -+ -+static struct super_block *hostfs_read_sb(struct file_system_type *type, -+ int flags, const char *dev_name, -+ void *data) -+{ -+ return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common)); -+} -+ -+static struct file_system_type hostfs_type = { -+ .owner = THIS_MODULE, -+ .name = "hostfs", -+ .get_sb = hostfs_read_sb, -+ .kill_sb = kill_anon_super, -+ .fs_flags = 0, -+}; -+ -+static int __init init_hostfs(void) -+{ -+ return(register_filesystem(&hostfs_type)); -+} -+ -+static void __exit exit_hostfs(void) -+{ -+ unregister_filesystem(&hostfs_type); -+} -+ -+module_init(init_hostfs) -+module_exit(exit_hostfs) -+MODULE_LICENSE("GPL"); -+ -+/* -+ * 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 -puN /dev/null fs/hostfs/hostfs_user.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/fs/hostfs/hostfs_user.c 2004-06-29 21:02:55.758282208 +0200 -@@ -0,0 +1,361 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <stdio.h> -+#include <fcntl.h> -+#include <dirent.h> -+#include <errno.h> -+#include <utime.h> -+#include <string.h> -+#include <sys/stat.h> -+#include <sys/time.h> -+#include <sys/vfs.h> -+#include "hostfs.h" -+#include "kern_util.h" -+#include "user.h" -+ -+int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, -+ int *nlink_out, int *uid_out, int *gid_out, -+ unsigned long long *size_out, struct timespec *atime_out, -+ struct timespec *mtime_out, struct timespec *ctime_out, -+ int *blksize_out, unsigned long long *blocks_out) -+{ -+ struct stat64 buf; -+ -+ if(lstat64(path, &buf) < 0) -+ return(-errno); -+ -+ /* See the Makefile for why STAT64_INO_FIELD is passed in -+ * by the build -+ */ -+ if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD; -+ if(mode_out != NULL) *mode_out = buf.st_mode; -+ if(nlink_out != NULL) *nlink_out = buf.st_nlink; -+ if(uid_out != NULL) *uid_out = buf.st_uid; -+ if(gid_out != NULL) *gid_out = buf.st_gid; -+ if(size_out != NULL) *size_out = buf.st_size; -+ if(atime_out != NULL) { -+ atime_out->tv_sec = buf.st_atime; -+ atime_out->tv_nsec = 0; -+ } -+ if(mtime_out != NULL) { -+ mtime_out->tv_sec = buf.st_mtime; -+ mtime_out->tv_nsec = 0; -+ } -+ if(ctime_out != NULL) { -+ ctime_out->tv_sec = buf.st_ctime; -+ ctime_out->tv_nsec = 0; -+ } -+ if(blksize_out != NULL) *blksize_out = buf.st_blksize; -+ if(blocks_out != NULL) *blocks_out = buf.st_blocks; -+ return(0); -+} -+ -+int file_type(const char *path, int *rdev) -+{ -+ struct stat64 buf; -+ -+ if(lstat64(path, &buf) < 0) -+ return(-errno); -+ if(rdev != NULL) -+ *rdev = buf.st_rdev; -+ -+ if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR); -+ else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK); -+ else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV); -+ else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV); -+ else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO); -+ else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK); -+ else return(OS_TYPE_FILE); -+} -+ -+int access_file(char *path, int r, int w, int x) -+{ -+ int mode = 0; -+ -+ if(r) mode = R_OK; -+ if(w) mode |= W_OK; -+ if(x) mode |= X_OK; -+ if(access(path, mode) != 0) return(-errno); -+ else return(0); -+} -+ -+int open_file(char *path, int r, int w, int append) -+{ -+ int mode = 0, fd; -+ -+ if(r && !w) -+ mode = O_RDONLY; -+ else if(!r && w) -+ mode = O_WRONLY; -+ else if(r && w) -+ mode = O_RDWR; -+ else panic("Impossible mode in open_file"); -+ -+ if(append) -+ mode |= O_APPEND; -+ fd = open64(path, mode); -+ if(fd < 0) return(-errno); -+ else return(fd); -+} -+ -+void *open_dir(char *path, int *err_out) -+{ -+ DIR *dir; -+ -+ dir = opendir(path); -+ *err_out = errno; -+ if(dir == NULL) return(NULL); -+ return(dir); -+} -+ -+char *read_dir(void *stream, unsigned long long *pos, -+ unsigned long long *ino_out, int *len_out) -+{ -+ DIR *dir = stream; -+ struct dirent *ent; -+ -+ seekdir(dir, *pos); -+ ent = readdir(dir); -+ if(ent == NULL) return(NULL); -+ *len_out = strlen(ent->d_name); -+ *ino_out = ent->d_ino; -+ *pos = telldir(dir); -+ return(ent->d_name); -+} -+ -+int read_file(int fd, unsigned long long *offset, char *buf, int len) -+{ -+ int n; -+ -+ n = pread64(fd, buf, len, *offset); -+ if(n < 0) return(-errno); -+ *offset += n; -+ return(n); -+} -+ -+int write_file(int fd, unsigned long long *offset, const char *buf, int len) -+{ -+ int n; -+ -+ n = pwrite64(fd, buf, len, *offset); -+ if(n < 0) return(-errno); -+ *offset += n; -+ return(n); -+} -+ -+int lseek_file(int fd, long long offset, int whence) -+{ -+ int ret; -+ -+ ret = lseek64(fd, offset, whence); -+ if(ret < 0) return(-errno); -+ return(0); -+} -+ -+void close_file(void *stream) -+{ -+ close(*((int *) stream)); -+} -+ -+void close_dir(void *stream) -+{ -+ closedir(stream); -+} -+ -+int file_create(char *name, int ur, int uw, int ux, int gr, -+ int gw, int gx, int or, int ow, int ox) -+{ -+ int mode, fd; -+ -+ mode = 0; -+ mode |= ur ? S_IRUSR : 0; -+ mode |= uw ? S_IWUSR : 0; -+ mode |= ux ? S_IXUSR : 0; -+ mode |= gr ? S_IRGRP : 0; -+ mode |= gw ? S_IWGRP : 0; -+ mode |= gx ? S_IXGRP : 0; -+ mode |= or ? S_IROTH : 0; -+ mode |= ow ? S_IWOTH : 0; -+ mode |= ox ? S_IXOTH : 0; -+ fd = open64(name, O_CREAT | O_RDWR, mode); -+ if(fd < 0) -+ return(-errno); -+ return(fd); -+} -+ -+int set_attr(const char *file, struct hostfs_iattr *attrs) -+{ -+ struct utimbuf buf; -+ int err, ma; -+ -+ if(attrs->ia_valid & HOSTFS_ATTR_MODE){ -+ if(chmod(file, attrs->ia_mode) != 0) return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_UID){ -+ if(chown(file, attrs->ia_uid, -1)) return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_GID){ -+ if(chown(file, -1, attrs->ia_gid)) return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_SIZE){ -+ if(truncate(file, attrs->ia_size)) return(-errno); -+ } -+ ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET; -+ if((attrs->ia_valid & ma) == ma){ -+ buf.actime = attrs->ia_atime.tv_sec; -+ buf.modtime = attrs->ia_mtime.tv_sec; -+ if(utime(file, &buf) != 0) return(-errno); -+ } -+ else { -+ struct timespec ts; -+ -+ if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){ -+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, -+ NULL, NULL, &ts, NULL, NULL, NULL); -+ if(err != 0) -+ return(err); -+ buf.actime = attrs->ia_atime.tv_sec; -+ buf.modtime = ts.tv_sec; -+ if(utime(file, &buf) != 0) -+ return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){ -+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, -+ NULL, &ts, NULL, NULL, NULL, NULL); -+ if(err != 0) -+ return(err); -+ buf.actime = ts.tv_sec; -+ buf.modtime = attrs->ia_mtime.tv_sec; -+ if(utime(file, &buf) != 0) -+ return(-errno); -+ } -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ; -+ if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){ -+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, -+ &attrs->ia_atime, &attrs->ia_mtime, NULL, -+ NULL, NULL); -+ if(err != 0) return(err); -+ } -+ return(0); -+} -+ -+int make_symlink(const char *from, const char *to) -+{ -+ int err; -+ -+ err = symlink(to, from); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int unlink_file(const char *file) -+{ -+ int err; -+ -+ err = unlink(file); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_mkdir(const char *file, int mode) -+{ -+ int err; -+ -+ err = mkdir(file, mode); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_rmdir(const char *file) -+{ -+ int err; -+ -+ err = rmdir(file); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_mknod(const char *file, int mode, int dev) -+{ -+ int err; -+ -+ err = mknod(file, mode, dev); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int link_file(const char *to, const char *from) -+{ -+ int err; -+ -+ err = link(to, from); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_readlink(char *file, char *buf, int size) -+{ -+ int n; -+ -+ n = readlink(file, buf, size); -+ if(n < 0) -+ return(-errno); -+ if(n < size) -+ buf[n] = '\0'; -+ return(n); -+} -+ -+int rename_file(char *from, char *to) -+{ -+ int err; -+ -+ err = rename(from, to); -+ if(err < 0) return(-errno); -+ return(0); -+} -+ -+int do_statfs(char *root, long *bsize_out, long long *blocks_out, -+ long long *bfree_out, long long *bavail_out, -+ long long *files_out, long long *ffree_out, -+ void *fsid_out, int fsid_size, long *namelen_out, -+ long *spare_out) -+{ -+ struct statfs64 buf; -+ int err; -+ -+ err = statfs64(root, &buf); -+ if(err < 0) return(-errno); -+ *bsize_out = buf.f_bsize; -+ *blocks_out = buf.f_blocks; -+ *bfree_out = buf.f_bfree; -+ *bavail_out = buf.f_bavail; -+ *files_out = buf.f_files; -+ *ffree_out = buf.f_ffree; -+ memcpy(fsid_out, &buf.f_fsid, -+ sizeof(buf.f_fsid) > fsid_size ? fsid_size : -+ sizeof(buf.f_fsid)); -+ *namelen_out = buf.f_namelen; -+ spare_out[0] = buf.f_spare[0]; -+ spare_out[1] = buf.f_spare[1]; -+ spare_out[2] = buf.f_spare[2]; -+ spare_out[3] = buf.f_spare[3]; -+ spare_out[4] = buf.f_spare[4]; -+ spare_out[5] = buf.f_spare[5]; -+ 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 -puN /dev/null fs/hostfs/Makefile ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/fs/hostfs/Makefile 2004-06-29 21:02:55.759282056 +0200 -@@ -0,0 +1,26 @@ -+# -+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino -+# to __st_ino. It stayed in the same place, so as long as the correct name -+# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa. -+ -+STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \ -+ echo __)st_ino -+ -+hostfs-objs := hostfs_kern.o hostfs_user.o -+ -+obj-y = -+obj-$(CONFIG_HOSTFS) += hostfs.o -+ -+SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) -+ -+USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS)) -+USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) -+ -+USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD) -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -diff -puN /dev/null fs/hppfs/hppfs_kern.c ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/fs/hppfs/hppfs_kern.c 2004-06-29 21:02:55.760281904 +0200 -@@ -0,0 +1,811 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <linux/fs.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/list.h> -+#include <linux/kernel.h> -+#include <linux/ctype.h> -+#include <linux/dcache.h> -+#include <linux/statfs.h> -+#include <asm/uaccess.h> -+#include <asm/fcntl.h> -+#include "os.h" -+ -+static int init_inode(struct inode *inode, struct dentry *dentry); -+ -+struct hppfs_data { -+ struct list_head list; -+ char contents[PAGE_SIZE - sizeof(struct list_head)]; -+}; -+ -+struct hppfs_private { -+ struct file proc_file; -+ int host_fd; -+ loff_t len; -+ struct hppfs_data *contents; -+}; -+ -+struct hppfs_inode_info { -+ struct dentry *proc_dentry; -+ struct inode vfs_inode; -+}; -+ -+static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode) -+{ -+ return(list_entry(inode, struct hppfs_inode_info, vfs_inode)); -+} -+ -+#define HPPFS_SUPER_MAGIC 0xb00000ee -+ -+static struct super_operations hppfs_sbops; -+ -+static int is_pid(struct dentry *dentry) -+{ -+ struct super_block *sb; -+ int i; -+ -+ sb = dentry->d_sb; -+ if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root)) -+ return(0); -+ -+ for(i = 0; i < dentry->d_name.len; i++){ -+ if(!isdigit(dentry->d_name.name[i])) -+ return(0); -+ } -+ return(1); -+} -+ -+static char *dentry_name(struct dentry *dentry, int extra) -+{ -+ struct dentry *parent; -+ char *root, *name; -+ const char *seg_name; -+ int len, seg_len; -+ -+ len = 0; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ if(is_pid(parent)) -+ len += strlen("pid") + 1; -+ else len += parent->d_name.len + 1; -+ parent = parent->d_parent; -+ } -+ -+ root = "proc"; -+ len += strlen(root); -+ name = kmalloc(len + extra + 1, GFP_KERNEL); -+ if(name == NULL) return(NULL); -+ -+ name[len] = '\0'; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ if(is_pid(parent)){ -+ seg_name = "pid"; -+ seg_len = strlen("pid"); -+ } -+ else { -+ seg_name = parent->d_name.name; -+ seg_len = parent->d_name.len; -+ } -+ -+ len -= seg_len + 1; -+ name[len] = '/'; -+ strncpy(&name[len + 1], seg_name, seg_len); -+ parent = parent->d_parent; -+ } -+ strncpy(name, root, strlen(root)); -+ return(name); -+} -+ -+struct dentry_operations hppfs_dentry_ops = { -+}; -+ -+static int file_removed(struct dentry *dentry, const char *file) -+{ -+ char *host_file; -+ int extra, fd; -+ -+ extra = 0; -+ if(file != NULL) extra += strlen(file) + 1; -+ -+ host_file = dentry_name(dentry, extra + strlen("/remove")); -+ if(host_file == NULL){ -+ printk("file_removed : allocation failed\n"); -+ return(-ENOMEM); -+ } -+ -+ if(file != NULL){ -+ strcat(host_file, "/"); -+ strcat(host_file, file); -+ } -+ strcat(host_file, "/remove"); -+ -+ fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); -+ kfree(host_file); -+ if(fd > 0){ -+ os_close_file(fd); -+ return(1); -+ } -+ return(0); -+} -+ -+static void hppfs_read_inode(struct inode *ino) -+{ -+ struct inode *proc_ino; -+ -+ if(HPPFS_I(ino)->proc_dentry == NULL) -+ return; -+ -+ proc_ino = HPPFS_I(ino)->proc_dentry->d_inode; -+ ino->i_uid = proc_ino->i_uid; -+ ino->i_gid = proc_ino->i_gid; -+ ino->i_atime = proc_ino->i_atime; -+ ino->i_mtime = proc_ino->i_mtime; -+ ino->i_ctime = proc_ino->i_ctime; -+ ino->i_ino = proc_ino->i_ino; -+ ino->i_mode = proc_ino->i_mode; -+ ino->i_nlink = proc_ino->i_nlink; -+ ino->i_size = proc_ino->i_size; -+ ino->i_blksize = proc_ino->i_blksize; -+ ino->i_blocks = proc_ino->i_blocks; -+} -+ -+static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, -+ struct nameidata *nd) -+{ -+ struct dentry *proc_dentry, *new, *parent; -+ struct inode *inode; -+ int err, deleted; -+ -+ deleted = file_removed(dentry, NULL); -+ if(deleted < 0) -+ return(ERR_PTR(deleted)); -+ else if(deleted) -+ return(ERR_PTR(-ENOENT)); -+ -+ err = -ENOMEM; -+ parent = HPPFS_I(ino)->proc_dentry; -+ down(&parent->d_inode->i_sem); -+ proc_dentry = d_lookup(parent, &dentry->d_name); -+ if(proc_dentry == NULL){ -+ proc_dentry = d_alloc(parent, &dentry->d_name); -+ if(proc_dentry == NULL){ -+ up(&parent->d_inode->i_sem); -+ goto out; -+ } -+ new = (*parent->d_inode->i_op->lookup)(parent->d_inode, -+ proc_dentry, NULL); -+ if(new){ -+ dput(proc_dentry); -+ proc_dentry = new; -+ } -+ } -+ up(&parent->d_inode->i_sem); -+ -+ if(IS_ERR(proc_dentry)) -+ return(proc_dentry); -+ -+ inode = iget(ino->i_sb, 0); -+ if(inode == NULL) -+ goto out_dput; -+ -+ err = init_inode(inode, proc_dentry); -+ if(err) -+ goto out_put; -+ -+ hppfs_read_inode(inode); -+ -+ d_add(dentry, inode); -+ dentry->d_op = &hppfs_dentry_ops; -+ return(NULL); -+ -+ out_put: -+ iput(inode); -+ out_dput: -+ dput(proc_dentry); -+ out: -+ return(ERR_PTR(err)); -+} -+ -+static struct inode_operations hppfs_file_iops = { -+}; -+ -+static ssize_t read_proc(struct file *file, char *buf, ssize_t count, -+ loff_t *ppos, int is_user) -+{ -+ ssize_t (*read)(struct file *, char *, size_t, loff_t *); -+ ssize_t n; -+ -+ read = file->f_dentry->d_inode->i_fop->read; -+ -+ if(!is_user) -+ set_fs(KERNEL_DS); -+ -+ n = (*read)(file, buf, count, &file->f_pos); -+ -+ if(!is_user) -+ set_fs(USER_DS); -+ -+ if(ppos) *ppos = file->f_pos; -+ return(n); -+} -+ -+static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count) -+{ -+ ssize_t n; -+ int cur, err; -+ char *new_buf; -+ -+ n = -ENOMEM; -+ new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); -+ if(new_buf == NULL){ -+ printk("hppfs_read_file : kmalloc failed\n"); -+ goto out; -+ } -+ n = 0; -+ while(count > 0){ -+ cur = min_t(ssize_t, count, PAGE_SIZE); -+ err = os_read_file(fd, new_buf, cur); -+ if(err < 0){ -+ printk("hppfs_read : read failed, errno = %d\n", -+ count); -+ n = err; -+ goto out_free; -+ } -+ else if(err == 0) -+ break; -+ -+ if(copy_to_user(buf, new_buf, err)){ -+ n = -EFAULT; -+ goto out_free; -+ } -+ n += err; -+ count -= err; -+ } -+ out_free: -+ kfree(new_buf); -+ out: -+ return(n); -+} -+ -+static ssize_t hppfs_read(struct file *file, char *buf, size_t count, -+ loff_t *ppos) -+{ -+ struct hppfs_private *hppfs = file->private_data; -+ struct hppfs_data *data; -+ loff_t off; -+ int err; -+ -+ if(hppfs->contents != NULL){ -+ if(*ppos >= hppfs->len) return(0); -+ -+ data = hppfs->contents; -+ off = *ppos; -+ while(off >= sizeof(data->contents)){ -+ data = list_entry(data->list.next, struct hppfs_data, -+ list); -+ off -= sizeof(data->contents); -+ } -+ -+ if(off + count > hppfs->len) -+ count = hppfs->len - off; -+ copy_to_user(buf, &data->contents[off], count); -+ *ppos += count; -+ } -+ else if(hppfs->host_fd != -1){ -+ err = os_seek_file(hppfs->host_fd, *ppos); -+ if(err){ -+ printk("hppfs_read : seek failed, errno = %d\n", err); -+ return(err); -+ } -+ count = hppfs_read_file(hppfs->host_fd, buf, count); -+ if(count > 0) -+ *ppos += count; -+ } -+ else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1); -+ -+ return(count); -+} -+ -+static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, -+ loff_t *ppos) -+{ -+ struct hppfs_private *data = file->private_data; -+ struct file *proc_file = &data->proc_file; -+ ssize_t (*write)(struct file *, const char *, size_t, loff_t *); -+ int err; -+ -+ write = proc_file->f_dentry->d_inode->i_fop->write; -+ -+ proc_file->f_pos = file->f_pos; -+ err = (*write)(proc_file, buf, len, &proc_file->f_pos); -+ file->f_pos = proc_file->f_pos; -+ -+ return(err); -+} -+ -+static int open_host_sock(char *host_file, int *filter_out) -+{ -+ char *end; -+ int fd; -+ -+ end = &host_file[strlen(host_file)]; -+ strcpy(end, "/rw"); -+ *filter_out = 1; -+ fd = os_connect_socket(host_file); -+ if(fd > 0) -+ return(fd); -+ -+ strcpy(end, "/r"); -+ *filter_out = 0; -+ fd = os_connect_socket(host_file); -+ return(fd); -+} -+ -+static void free_contents(struct hppfs_data *head) -+{ -+ struct hppfs_data *data; -+ struct list_head *ele, *next; -+ -+ if(head == NULL) return; -+ -+ list_for_each_safe(ele, next, &head->list){ -+ data = list_entry(ele, struct hppfs_data, list); -+ kfree(data); -+ } -+ kfree(head); -+} -+ -+static struct hppfs_data *hppfs_get_data(int fd, int filter, -+ struct file *proc_file, -+ struct file *hppfs_file, -+ loff_t *size_out) -+{ -+ struct hppfs_data *data, *new, *head; -+ int n, err; -+ -+ err = -ENOMEM; -+ data = kmalloc(sizeof(*data), GFP_KERNEL); -+ if(data == NULL){ -+ printk("hppfs_get_data : head allocation failed\n"); -+ goto failed; -+ } -+ -+ INIT_LIST_HEAD(&data->list); -+ -+ head = data; -+ *size_out = 0; -+ -+ if(filter){ -+ while((n = read_proc(proc_file, data->contents, -+ sizeof(data->contents), NULL, 0)) > 0) -+ os_write_file(fd, data->contents, n); -+ err = os_shutdown_socket(fd, 0, 1); -+ if(err){ -+ printk("hppfs_get_data : failed to shut down " -+ "socket\n"); -+ goto failed_free; -+ } -+ } -+ while(1){ -+ n = os_read_file(fd, data->contents, sizeof(data->contents)); -+ if(n < 0){ -+ err = n; -+ printk("hppfs_get_data : read failed, errno = %d\n", -+ err); -+ goto failed_free; -+ } -+ else if(n == 0) -+ break; -+ -+ *size_out += n; -+ -+ if(n < sizeof(data->contents)) -+ break; -+ -+ new = kmalloc(sizeof(*data), GFP_KERNEL); -+ if(new == 0){ -+ printk("hppfs_get_data : data allocation failed\n"); -+ err = -ENOMEM; -+ goto failed_free; -+ } -+ -+ INIT_LIST_HEAD(&new->list); -+ list_add(&new->list, &data->list); -+ data = new; -+ } -+ return(head); -+ -+ failed_free: -+ free_contents(head); -+ failed: -+ return(ERR_PTR(err)); -+} -+ -+static struct hppfs_private *hppfs_data(void) -+{ -+ struct hppfs_private *data; -+ -+ data = kmalloc(sizeof(*data), GFP_KERNEL); -+ if(data == NULL) -+ return(data); -+ -+ *data = ((struct hppfs_private ) { .host_fd = -1, -+ .len = -1, -+ .contents = NULL } ); -+ return(data); -+} -+ -+static int file_mode(int fmode) -+{ -+ if(fmode == (FMODE_READ | FMODE_WRITE)) -+ return(O_RDWR); -+ if(fmode == FMODE_READ) -+ return(O_RDONLY); -+ if(fmode == FMODE_WRITE) -+ return(O_WRONLY); -+ return(0); -+} -+ -+static int hppfs_open(struct inode *inode, struct file *file) -+{ -+ struct hppfs_private *data; -+ struct dentry *proc_dentry; -+ char *host_file; -+ int err, fd, type, filter; -+ -+ err = -ENOMEM; -+ data = hppfs_data(); -+ if(data == NULL) -+ goto out; -+ -+ host_file = dentry_name(file->f_dentry, strlen("/rw")); -+ if(host_file == NULL) -+ goto out_free2; -+ -+ proc_dentry = HPPFS_I(inode)->proc_dentry; -+ -+ /* XXX This isn't closed anywhere */ -+ err = open_private_file(&data->proc_file, proc_dentry, -+ file_mode(file->f_mode)); -+ if(err) -+ goto out_free1; -+ -+ type = os_file_type(host_file); -+ if(type == OS_TYPE_FILE){ -+ fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); -+ if(fd >= 0) -+ data->host_fd = fd; -+ else printk("hppfs_open : failed to open '%s', errno = %d\n", -+ host_file, -fd); -+ -+ data->contents = NULL; -+ } -+ else if(type == OS_TYPE_DIR){ -+ fd = open_host_sock(host_file, &filter); -+ if(fd > 0){ -+ data->contents = hppfs_get_data(fd, filter, -+ &data->proc_file, -+ file, &data->len); -+ if(!IS_ERR(data->contents)) -+ data->host_fd = fd; -+ } -+ else printk("hppfs_open : failed to open a socket in " -+ "'%s', errno = %d\n", host_file, -fd); -+ } -+ kfree(host_file); -+ -+ file->private_data = data; -+ return(0); -+ -+ out_free1: -+ kfree(host_file); -+ out_free2: -+ free_contents(data->contents); -+ kfree(data); -+ out: -+ return(err); -+} -+ -+static int hppfs_dir_open(struct inode *inode, struct file *file) -+{ -+ struct hppfs_private *data; -+ struct dentry *proc_dentry; -+ int err; -+ -+ err = -ENOMEM; -+ data = hppfs_data(); -+ if(data == NULL) -+ goto out; -+ -+ proc_dentry = HPPFS_I(inode)->proc_dentry; -+ err = open_private_file(&data->proc_file, proc_dentry, -+ file_mode(file->f_mode)); -+ if(err) -+ goto out_free; -+ -+ file->private_data = data; -+ return(0); -+ -+ out_free: -+ kfree(data); -+ out: -+ return(err); -+} -+ -+static loff_t hppfs_llseek(struct file *file, loff_t off, int where) -+{ -+ struct hppfs_private *data = file->private_data; -+ struct file *proc_file = &data->proc_file; -+ loff_t (*llseek)(struct file *, loff_t, int); -+ loff_t ret; -+ -+ llseek = proc_file->f_dentry->d_inode->i_fop->llseek; -+ if(llseek != NULL){ -+ ret = (*llseek)(proc_file, off, where); -+ if(ret < 0) -+ return(ret); -+ } -+ -+ return(default_llseek(file, off, where)); -+} -+ -+static struct file_operations hppfs_file_fops = { -+ .owner = NULL, -+ .llseek = hppfs_llseek, -+ .read = hppfs_read, -+ .write = hppfs_write, -+ .open = hppfs_open, -+}; -+ -+struct hppfs_dirent { -+ void *vfs_dirent; -+ filldir_t filldir; -+ struct dentry *dentry; -+}; -+ -+static int hppfs_filldir(void *d, const char *name, int size, -+ loff_t offset, ino_t inode, unsigned int type) -+{ -+ struct hppfs_dirent *dirent = d; -+ -+ if(file_removed(dirent->dentry, name)) -+ return(0); -+ -+ return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, -+ inode, type)); -+} -+ -+static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) -+{ -+ struct hppfs_private *data = file->private_data; -+ struct file *proc_file = &data->proc_file; -+ int (*readdir)(struct file *, void *, filldir_t); -+ struct hppfs_dirent dirent = ((struct hppfs_dirent) -+ { .vfs_dirent = ent, -+ .filldir = filldir, -+ .dentry = file->f_dentry } ); -+ int err; -+ -+ readdir = proc_file->f_dentry->d_inode->i_fop->readdir; -+ -+ proc_file->f_pos = file->f_pos; -+ err = (*readdir)(proc_file, &dirent, hppfs_filldir); -+ file->f_pos = proc_file->f_pos; -+ -+ return(err); -+} -+ -+static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync) -+{ -+ return(0); -+} -+ -+static struct file_operations hppfs_dir_fops = { -+ .owner = NULL, -+ .readdir = hppfs_readdir, -+ .open = hppfs_dir_open, -+ .fsync = hppfs_fsync, -+}; -+ -+static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf) -+{ -+ sf->f_blocks = 0; -+ sf->f_bfree = 0; -+ sf->f_bavail = 0; -+ sf->f_files = 0; -+ sf->f_ffree = 0; -+ sf->f_type = HPPFS_SUPER_MAGIC; -+ return(0); -+} -+ -+static struct inode *hppfs_alloc_inode(struct super_block *sb) -+{ -+ struct hppfs_inode_info *hi; -+ -+ hi = kmalloc(sizeof(*hi), GFP_KERNEL); -+ if(hi == NULL) -+ return(NULL); -+ -+ *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL }); -+ inode_init_once(&hi->vfs_inode); -+ return(&hi->vfs_inode); -+} -+ -+void hppfs_delete_inode(struct inode *ino) -+{ -+ clear_inode(ino); -+} -+ -+static void hppfs_destroy_inode(struct inode *inode) -+{ -+ kfree(HPPFS_I(inode)); -+} -+ -+static struct super_operations hppfs_sbops = { -+ .alloc_inode = hppfs_alloc_inode, -+ .destroy_inode = hppfs_destroy_inode, -+ .read_inode = hppfs_read_inode, -+ .delete_inode = hppfs_delete_inode, -+ .statfs = hppfs_statfs, -+}; -+ -+static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen) -+{ -+ struct file proc_file; -+ struct dentry *proc_dentry; -+ int (*readlink)(struct dentry *, char *, int); -+ int err, n; -+ -+ proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; -+ err = open_private_file(&proc_file, proc_dentry, O_RDONLY); -+ if(err) -+ return(err); -+ -+ readlink = proc_dentry->d_inode->i_op->readlink; -+ n = (*readlink)(proc_dentry, buffer, buflen); -+ -+ close_private_file(&proc_file); -+ -+ return(n); -+} -+ -+static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) -+{ -+ struct file proc_file; -+ struct dentry *proc_dentry; -+ int (*follow_link)(struct dentry *, struct nameidata *); -+ int err, n; -+ -+ proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; -+ err = open_private_file(&proc_file, proc_dentry, O_RDONLY); -+ if(err) -+ return(err); -+ -+ follow_link = proc_dentry->d_inode->i_op->follow_link; -+ n = (*follow_link)(proc_dentry, nd); -+ -+ close_private_file(&proc_file); -+ -+ return(n); -+} -+ -+static struct inode_operations hppfs_dir_iops = { -+ .lookup = hppfs_lookup, -+}; -+ -+static struct inode_operations hppfs_link_iops = { -+ .readlink = hppfs_readlink, -+ .follow_link = hppfs_follow_link, -+}; -+ -+static int init_inode(struct inode *inode, struct dentry *dentry) -+{ -+ if(S_ISDIR(dentry->d_inode->i_mode)){ -+ inode->i_op = &hppfs_dir_iops; -+ inode->i_fop = &hppfs_dir_fops; -+ } -+ else if(S_ISLNK(dentry->d_inode->i_mode)){ -+ inode->i_op = &hppfs_link_iops; -+ inode->i_fop = &hppfs_file_fops; -+ } -+ else { -+ inode->i_op = &hppfs_file_iops; -+ inode->i_fop = &hppfs_file_fops; -+ } -+ -+ HPPFS_I(inode)->proc_dentry = dentry; -+ -+ return(0); -+} -+ -+static int hppfs_fill_super(struct super_block *sb, void *d, int silent) -+{ -+ struct inode *root_inode; -+ struct file_system_type *procfs; -+ struct super_block *proc_sb; -+ int err; -+ -+ err = -ENOENT; -+ procfs = get_fs_type("proc"); -+ if(procfs == NULL) -+ goto out; -+ -+ if(list_empty(&procfs->fs_supers)) -+ goto out; -+ -+ proc_sb = list_entry(procfs->fs_supers.next, struct super_block, -+ s_instances); -+ -+ sb->s_blocksize = 1024; -+ sb->s_blocksize_bits = 10; -+ sb->s_magic = HPPFS_SUPER_MAGIC; -+ sb->s_op = &hppfs_sbops; -+ -+ root_inode = iget(sb, 0); -+ if(root_inode == NULL) -+ goto out; -+ -+ err = init_inode(root_inode, proc_sb->s_root); -+ if(err) -+ goto out_put; -+ -+ err = -ENOMEM; -+ sb->s_root = d_alloc_root(root_inode); -+ if(sb->s_root == NULL) -+ goto out_put; -+ -+ hppfs_read_inode(root_inode); -+ -+ return(0); -+ -+ out_put: -+ iput(root_inode); -+ out: -+ return(err); -+} -+ -+static struct super_block *hppfs_read_super(struct file_system_type *type, -+ int flags, const char *dev_name, -+ void *data) -+{ -+ return(get_sb_nodev(type, flags, data, hppfs_fill_super)); -+} -+ -+static struct file_system_type hppfs_type = { -+ .owner = THIS_MODULE, -+ .name = "hppfs", -+ .get_sb = hppfs_read_super, -+ .kill_sb = kill_anon_super, -+ .fs_flags = 0, -+}; -+ -+static int __init init_hppfs(void) -+{ -+ return(register_filesystem(&hppfs_type)); -+} -+ -+static void __exit exit_hppfs(void) -+{ -+ unregister_filesystem(&hppfs_type); -+} -+ -+module_init(init_hppfs) -+module_exit(exit_hppfs) -+MODULE_LICENSE("GPL"); -+ -+/* -+ * 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 -puN /dev/null fs/hppfs/Makefile ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/fs/hppfs/Makefile 2004-06-29 21:02:55.760281904 +0200 -@@ -0,0 +1,19 @@ -+# -+# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+hppfs-objs := hppfs_kern.o -+ -+obj-y = -+obj-$(CONFIG_HPPFS) += hppfs.o -+ -+clean: -+ -+modules: -+ -+fastdep: -+ -+dep: -+ -+archmrproper: clean -diff -puN fs/Makefile~Main-uml-patch-no-skas fs/Makefile ---- uml-linux-2.6.7/fs/Makefile~Main-uml-patch-no-skas 2004-06-29 21:02:55.657297560 +0200 -+++ uml-linux-2.6.7-paolo/fs/Makefile 2004-06-29 21:02:55.760281904 +0200 -@@ -91,3 +91,5 @@ obj-$(CONFIG_JFS_FS) += jfs/ - obj-$(CONFIG_XFS_FS) += xfs/ - obj-$(CONFIG_AFS_FS) += afs/ - obj-$(CONFIG_BEFS_FS) += befs/ -+obj-$(CONFIG_HOSTFS) += hostfs/ -+obj-$(CONFIG_HPPFS) += hppfs/ -diff -puN include/asm-um/archparam-i386.h~Main-uml-patch-no-skas include/asm-um/archparam-i386.h ---- uml-linux-2.6.7/include/asm-um/archparam-i386.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.658297408 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/archparam-i386.h 2004-06-29 21:02:55.760281904 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -@@ -56,6 +56,93 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR - pr_reg[16] = PT_REGS_SS(regs); \ - } while(0); - -+#if 0 /* Turn this back on when UML has VSYSCALL working */ -+#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL)) -+#else -+#define VSYSCALL_BASE 0 -+#endif -+ -+#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE) -+#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall) -+extern void *__kernel_vsyscall; -+ -+/* -+ * Architecture-neutral AT_ values in 0-17, leave some room -+ * for more of them, start the x86-specific ones at 32. -+ */ -+#define AT_SYSINFO 32 -+#define AT_SYSINFO_EHDR 33 -+ -+#define ARCH_DLINFO \ -+do { \ -+ NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \ -+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \ -+} while (0) -+ -+/* -+ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out -+ * extra segments containing the vsyscall DSO contents. Dumping its -+ * contents makes post-mortem fully interpretable later without matching up -+ * the same kernel and hardware config to see what PC values meant. -+ * Dumping its extra ELF program headers includes all the other information -+ * a debugger needs to easily find how the vsyscall DSO was being used. -+ */ -+#if 0 -+#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum) -+#endif -+ -+#undef ELF_CORE_EXTRA_PHDRS -+ -+#if 0 -+#define ELF_CORE_WRITE_EXTRA_PHDRS \ -+do { \ -+ const struct elf_phdr *const vsyscall_phdrs = \ -+ (const struct elf_phdr *) (VSYSCALL_BASE \ -+ + VSYSCALL_EHDR->e_phoff); \ -+ int i; \ -+ Elf32_Off ofs = 0; \ -+ for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \ -+ struct elf_phdr phdr = vsyscall_phdrs[i]; \ -+ if (phdr.p_type == PT_LOAD) { \ -+ ofs = phdr.p_offset = offset; \ -+ offset += phdr.p_filesz; \ -+ } \ -+ else \ -+ phdr.p_offset += ofs; \ -+ phdr.p_paddr = 0; /* match other core phdrs */ \ -+ DUMP_WRITE(&phdr, sizeof(phdr)); \ -+ } \ -+} while (0) -+#define ELF_CORE_WRITE_EXTRA_DATA \ -+do { \ -+ const struct elf_phdr *const vsyscall_phdrs = \ -+ (const struct elf_phdr *) (VSYSCALL_BASE \ -+ + VSYSCALL_EHDR->e_phoff); \ -+ int i; \ -+ for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \ -+ if (vsyscall_phdrs[i].p_type == PT_LOAD) \ -+ DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \ -+ vsyscall_phdrs[i].p_filesz); \ -+ } \ -+} while (0) -+#endif -+ -+#undef ELF_CORE_WRITE_EXTRA_PHDRS -+#undef ELF_CORE_WRITE_EXTRA_DATA -+ -+#define R_386_NONE 0 -+#define R_386_32 1 -+#define R_386_PC32 2 -+#define R_386_GOT32 3 -+#define R_386_PLT32 4 -+#define R_386_COPY 5 -+#define R_386_GLOB_DAT 6 -+#define R_386_JMP_SLOT 7 -+#define R_386_RELATIVE 8 -+#define R_386_GOTOFF 9 -+#define R_386_GOTPC 10 -+#define R_386_NUM 11 -+ - /********* Bits for asm-um/delay.h **********/ - - typedef unsigned long um_udelay_t; -diff -puN include/asm-um/common.lds.S~Main-uml-patch-no-skas include/asm-um/common.lds.S ---- uml-linux-2.6.7/include/asm-um/common.lds.S~Main-uml-patch-no-skas 2004-06-29 21:02:55.659297256 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/common.lds.S 2004-06-29 21:02:55.761281752 +0200 -@@ -1,3 +1,5 @@ -+#include <asm-generic/vmlinux.lds.h> -+ - .fini : { *(.fini) } =0x9090 - _etext = .; - PROVIDE (etext = .); -@@ -13,18 +15,6 @@ - - RODATA - -- __start___ksymtab = .; /* Kernel symbol table */ -- __ksymtab : { *(__ksymtab) } -- __stop___ksymtab = .; -- -- __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ -- __gpl_ksymtab : { *(__gpl_ksymtab) } -- __stop___gpl_ksymtab = .; -- -- __start___kallsyms = .; /* All kernel symbols */ -- __kallsyms : { *(__kallsyms) } -- __stop___kallsyms = .; -- - .unprotected : { *(.unprotected) } - . = ALIGN(4096); - PROVIDE (_unprotected_end = .); -@@ -67,11 +57,17 @@ - } - __initcall_end = .; - -+ __con_initcall_start = .; -+ .con_initcall.init : { *(.con_initcall.init) } -+ __con_initcall_end = .; -+ - __uml_initcall_start = .; - .uml.initcall.init : { *(.uml.initcall.init) } - __uml_initcall_end = .; - __init_end = .; - -+ SECURITY_INIT -+ - __exitcall_begin = .; - .exitcall : { *(.exitcall.exit) } - __exitcall_end = .; -@@ -80,7 +76,33 @@ - .uml.exitcall : { *(.uml.exitcall.exit) } - __uml_exitcall_end = .; - -- . = ALIGN(4096); -+ . = ALIGN(4); -+ __alt_instructions = .; -+ .altinstructions : { *(.altinstructions) } -+ __alt_instructions_end = .; -+ .altinstr_replacement : { *(.altinstr_replacement) } -+ /* .exit.text is discard at runtime, not link time, to deal with references -+ from .altinstructions and .eh_frame */ -+ .exit.text : { *(.exit.text) } -+ .exit.data : { *(.exit.data) } -+ -+ __preinit_array_start = .; -+ .preinit_array : { *(.preinit_array) } -+ __preinit_array_end = .; -+ __init_array_start = .; -+ .init_array : { *(.init_array) } -+ __init_array_end = .; -+ __fini_array_start = .; -+ .fini_array : { *(.fini_array) } -+ __fini_array_end = .; -+ -+ . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; -+ -+ /* Sections to be discarded */ -+ /DISCARD/ : { -+ *(.exitcall.exit) -+ } -+ -diff -puN /dev/null include/asm-um/cpufeature.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/include/asm-um/cpufeature.h 2004-06-29 21:02:55.761281752 +0200 -@@ -0,0 +1,6 @@ -+#ifndef __UM_CPUFEATURE_H -+#define __UM_CPUFEATURE_H -+ -+#include "asm/arch/cpufeature.h" -+ -+#endif -diff -puN include/asm-um/current.h~Main-uml-patch-no-skas include/asm-um/current.h ---- uml-linux-2.6.7/include/asm-um/current.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.661296952 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/current.h 2004-06-29 21:02:55.761281752 +0200 -@@ -16,8 +16,10 @@ struct thread_info; - #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \ - (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER)) - --#define current ({ int dummy; \ -- ((struct thread_info *) CURRENT_THREAD(dummy))->task; }) -+#define current_thread \ -+ ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); }) -+ -+#define current (current_thread->task) - - #endif /* __ASSEMBLY__ */ - -diff -puN include/asm-um/dma-mapping.h~Main-uml-patch-no-skas include/asm-um/dma-mapping.h ---- uml-linux-2.6.7/include/asm-um/dma-mapping.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.662296800 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/dma-mapping.h 2004-06-29 21:02:55.761281752 +0200 -@@ -1 +1,119 @@ --#include <asm-generic/dma-mapping.h> -+#ifndef _ASM_DMA_MAPPING_H -+#define _ASM_DMA_MAPPING_H -+ -+static inline int -+dma_supported(struct device *dev, u64 mask) -+{ -+ BUG(); -+ return(0); -+} -+ -+static inline int -+dma_set_mask(struct device *dev, u64 dma_mask) -+{ -+ BUG(); -+ return(0); -+} -+ -+static inline void * -+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, -+ int flag) -+{ -+ BUG(); -+ return((void *) 0); -+} -+ -+static inline void -+dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, -+ dma_addr_t dma_handle) -+{ -+ BUG(); -+} -+ -+static inline dma_addr_t -+dma_map_single(struct device *dev, void *cpu_addr, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+ return(0); -+} -+ -+static inline void -+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+} -+ -+static inline dma_addr_t -+dma_map_page(struct device *dev, struct page *page, -+ unsigned long offset, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+ return(0); -+} -+ -+static inline void -+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+} -+ -+static inline int -+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+ return(0); -+} -+ -+static inline void -+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+} -+ -+static inline void -+dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+} -+ -+static inline void -+dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+} -+ -+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) -+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -+#define dma_is_consistent(d) (1) -+ -+static inline int -+dma_get_cache_alignment(void) -+{ -+ BUG(); -+ return(0); -+} -+ -+static inline void -+dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, -+ unsigned long offset, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+} -+ -+static inline void -+dma_cache_sync(void *vaddr, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG(); -+} -+ -+#endif -diff -puN include/asm-um/elf.h~Main-uml-patch-no-skas include/asm-um/elf.h ---- uml-linux-2.6.7/include/asm-um/elf.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.663296648 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/elf.h 2004-06-29 21:02:55.762281600 +0200 -@@ -15,4 +15,17 @@ - - #define USE_ELF_CORE_DUMP - -+#define R_386_NONE 0 -+#define R_386_32 1 -+#define R_386_PC32 2 -+#define R_386_GOT32 3 -+#define R_386_PLT32 4 -+#define R_386_COPY 5 -+#define R_386_GLOB_DAT 6 -+#define R_386_JMP_SLOT 7 -+#define R_386_RELATIVE 8 -+#define R_386_GOTOFF 9 -+#define R_386_GOTPC 10 -+#define R_386_NUM 11 -+ - #endif -diff -puN include/asm-um/fixmap.h~Main-uml-patch-no-skas include/asm-um/fixmap.h ---- uml-linux-2.6.7/include/asm-um/fixmap.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.664296496 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/fixmap.h 2004-06-29 21:02:55.762281600 +0200 -@@ -34,6 +34,7 @@ enum fixed_addresses { - FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ - FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, - #endif -+ FIX_VSYSCALL, - __end_of_fixed_addresses - }; - -@@ -63,6 +64,13 @@ extern unsigned long get_kmem_end(void); - #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) - #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) - -+/* -+ * This is the range that is readable by user mode, and things -+ * acting like user mode such as get_user_pages. -+ */ -+#define FIXADDR_USER_START (__fix_to_virt(FIX_VSYSCALL)) -+#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE) -+ - extern void __this_fixmap_does_not_exist(void); - - /* -diff -puN include/asm-um/irq.h~Main-uml-patch-no-skas include/asm-um/irq.h ---- uml-linux-2.6.7/include/asm-um/irq.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.665296344 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/irq.h 2004-06-29 21:02:55.762281600 +0200 -@@ -1,15 +1,6 @@ - #ifndef __UM_IRQ_H - #define __UM_IRQ_H - --/* The i386 irq.h has a struct task_struct in a prototype without including -- * sched.h. This forward declaration kills the resulting warning. -- */ --struct task_struct; -- --#include "asm/ptrace.h" -- --#undef NR_IRQS -- - #define TIMER_IRQ 0 - #define UMN_IRQ 1 - #define CONSOLE_IRQ 2 -@@ -28,13 +19,4 @@ struct task_struct; - #define LAST_IRQ XTERM_IRQ - #define NR_IRQS (LAST_IRQ + 1) - --extern int um_request_irq(unsigned int irq, int fd, int type, -- void (*handler)(int, void *, struct pt_regs *), -- unsigned long irqflags, const char * devname, -- void *dev_id); -- --struct irqaction; --struct pt_regs; --int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); -- - #endif -diff -puN /dev/null include/asm-um/local.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/include/asm-um/local.h 2004-06-29 21:02:55.762281600 +0200 -@@ -0,0 +1,6 @@ -+#ifndef __UM_LOCAL_H -+#define __UM_LOCAL_H -+ -+#include "asm/arch/local.h" -+ -+#endif -diff -puN /dev/null include/asm-um/module-generic.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/include/asm-um/module-generic.h 2004-06-29 21:02:55.762281600 +0200 -@@ -0,0 +1,6 @@ -+#ifndef __UM_MODULE_GENERIC_H -+#define __UM_MODULE_GENERIC_H -+ -+#include "asm/arch/module.h" -+ -+#endif -diff -puN /dev/null include/asm-um/module-i386.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/include/asm-um/module-i386.h 2004-06-29 21:02:55.763281448 +0200 -@@ -0,0 +1,13 @@ -+#ifndef __UM_MODULE_I386_H -+#define __UM_MODULE_I386_H -+ -+/* UML is simple */ -+struct mod_arch_specific -+{ -+}; -+ -+#define Elf_Shdr Elf32_Shdr -+#define Elf_Sym Elf32_Sym -+#define Elf_Ehdr Elf32_Ehdr -+ -+#endif -diff -puN include/asm-um/page.h~Main-uml-patch-no-skas include/asm-um/page.h ---- uml-linux-2.6.7/include/asm-um/page.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.667296040 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/page.h 2004-06-29 21:02:55.763281448 +0200 -@@ -1,10 +1,14 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ - #ifndef __UM_PAGE_H - #define __UM_PAGE_H - - struct page; - - #include "asm/arch/page.h" --#include "asm/bug.h" - - #undef __pa - #undef __va -@@ -24,25 +28,36 @@ extern unsigned long uml_physmem; - - #define __va_space (8*1024*1024) - --extern unsigned long region_pa(void *virt); --extern void *region_va(unsigned long phys); -- --#define __pa(virt) region_pa((void *) (virt)) --#define __va(phys) region_va((unsigned long) (phys)) -- --extern unsigned long page_to_pfn(struct page *page); --extern struct page *pfn_to_page(unsigned long pfn); -+extern unsigned long to_phys(void *virt); -+extern void *to_virt(unsigned long phys); - --extern struct page *phys_to_page(unsigned long phys); -+#define __pa(virt) to_phys((void *) virt) -+#define __va(phys) to_virt((unsigned long) phys) - --#define virt_to_page(v) (phys_to_page(__pa(v))) -+#define page_to_pfn(page) ((page) - mem_map) -+#define pfn_to_page(pfn) (mem_map + (pfn)) - --extern struct page *page_mem_map(struct page *page); -+#define phys_to_pfn(p) ((p) >> PAGE_SHIFT) -+#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) - --#define pfn_valid(pfn) (page_mem_map(pfn_to_page(pfn)) != NULL) --#define virt_addr_valid(v) pfn_valid(__pa(v) >> PAGE_SHIFT) -+#define pfn_valid(pfn) ((pfn) < max_mapnr) -+#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v))) - - extern struct page *arch_validate(struct page *page, int mask, int order); - #define HAVE_ARCH_VALIDATE - -+extern void arch_free_page(struct page *page, int order); -+#define HAVE_ARCH_FREE_PAGE -+ - #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 -puN include/asm-um/pgtable.h~Main-uml-patch-no-skas include/asm-um/pgtable.h ---- uml-linux-2.6.7/include/asm-um/pgtable.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.668295888 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/pgtable.h 2004-06-29 21:02:55.763281448 +0200 -@@ -12,8 +12,6 @@ - #include "asm/page.h" - #include "asm/fixmap.h" - --extern pgd_t swapper_pg_dir[1024]; -- - extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt, - pte_t *pte_out); - -@@ -49,6 +47,8 @@ extern unsigned long *empty_zero_page; - #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) - -+extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -+ - /* - * pgd entries used up by user/kernel: - */ -@@ -65,10 +65,10 @@ extern unsigned long *empty_zero_page; - * area for the same reason. ;) - */ - --extern unsigned long high_physmem; -+extern unsigned long end_iomem; - - #define VMALLOC_OFFSET (__va_space) --#define VMALLOC_START (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -+#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) - - #ifdef CONFIG_HIGHMEM - # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) -@@ -78,12 +78,13 @@ extern unsigned long high_physmem; - - #define _PAGE_PRESENT 0x001 - #define _PAGE_NEWPAGE 0x002 --#define _PAGE_PROTNONE 0x004 /* If not present */ --#define _PAGE_RW 0x008 --#define _PAGE_USER 0x010 --#define _PAGE_ACCESSED 0x020 --#define _PAGE_DIRTY 0x040 --#define _PAGE_NEWPROT 0x080 -+#define _PAGE_NEWPROT 0x004 -+#define _PAGE_FILE 0x008 /* set:pagecache unset:swap */ -+#define _PAGE_PROTNONE 0x010 /* If not present */ -+#define _PAGE_RW 0x020 -+#define _PAGE_USER 0x040 -+#define _PAGE_ACCESSED 0x080 -+#define _PAGE_DIRTY 0x100 - - #define REGION_MASK 0xf0000000 - #define REGION_SHIFT 28 -@@ -143,7 +144,8 @@ extern pte_t * __bad_pagetable(void); - - #define BAD_PAGETABLE __bad_pagetable() - #define BAD_PAGE __bad_page() --#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) -+ -+#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) - - /* number of bits that fit into a memory pointer */ - #define BITS_PER_PTR (8*sizeof(unsigned long)) -@@ -164,9 +166,6 @@ extern pte_t * __bad_pagetable(void); - - #define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0) - --#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT) --#define pte_region_index(x) phys_region_index(pte_val(x)) -- - #define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE)) - #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) - #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -@@ -188,19 +187,25 @@ static inline void pgd_clear(pgd_t * pgd - - #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) - --extern struct page *pte_mem_map(pte_t pte); --extern struct page *phys_mem_map(unsigned long phys); --extern unsigned long phys_to_pfn(unsigned long p); --extern unsigned long pfn_to_phys(unsigned long pfn); -- --#define pte_page(x) pfn_to_page(pte_pfn(x)) --#define pte_address(x) (__va(pte_val(x) & PAGE_MASK)) --#define mk_phys(a, r) ((a) + (r << REGION_SHIFT)) --#define phys_addr(p) ((p) & ~REGION_MASK) --#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT)) -+#define pte_page(pte) phys_to_page(pte_val(pte)) -+#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK) -+ - #define pte_pfn(x) phys_to_pfn(pte_val(x)) - #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot)) --#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot)) -+ -+extern struct page *phys_to_page(const unsigned long phys); -+extern struct page *__virt_to_page(const unsigned long virt); -+#define virt_to_page(addr) __virt_to_page((const unsigned long) addr) -+ -+/* -+ * Bits 0 through 3 are taken -+ */ -+#define PTE_FILE_MAX_BITS 28 -+ -+#define pte_to_pgoff(pte) ((pte).pte_low >> 4) -+ -+#define pgoff_to_pte(off) \ -+ ((pte_t) { ((off) << 4) + _PAGE_FILE }) - - static inline pte_t pte_mknewprot(pte_t pte) - { -@@ -235,6 +240,12 @@ static inline void set_pte(pte_t *pteptr - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -+static inline int pte_user(pte_t pte) -+{ -+ return((pte_val(pte) & _PAGE_USER) && -+ !(pte_val(pte) & _PAGE_PROTNONE)); -+} -+ - static inline int pte_read(pte_t pte) - { - return((pte_val(pte) & _PAGE_USER) && -@@ -252,6 +263,14 @@ static inline int pte_write(pte_t pte) - !(pte_val(pte) & _PAGE_PROTNONE)); - } - -+/* -+ * The following only works if pte_present() is not true. -+ */ -+static inline int pte_file(pte_t pte) -+{ -+ return (pte).pte_low & _PAGE_FILE; -+} -+ - static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } - static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } - static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; } -@@ -334,14 +353,7 @@ extern unsigned long page_to_phys(struct - * and a page entry and page directory to the page they refer to. - */ - --#define mk_pte(page, pgprot) \ --({ \ -- pte_t __pte; \ -- \ -- pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\ -- if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \ -- __pte; \ --}) -+extern pte_t mk_pte(struct page *page, pgprot_t pgprot); - - static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) - { -@@ -351,17 +363,27 @@ static inline pte_t pte_modify(pte_t pte - } - - #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) --#define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \ -- ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT))) - --/* to find an entry in a page-table-directory. */ -+/* -+ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] -+ * -+ * this macro returns the index of the entry in the pgd page which would -+ * control the given virtual address -+ */ - #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) - --/* to find an entry in a page-table-directory */ -+/* -+ * pgd_offset() returns a (pgd_t *) -+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's; -+ */ - #define pgd_offset(mm, address) \ - ((mm)->pgd + ((address) >> PGDIR_SHIFT)) - --/* to find an entry in a kernel page-table-directory */ -+ -+/* -+ * a shortcut which implies the use of the kernel's pgd, instead -+ * of a process's -+ */ - #define pgd_offset_k(address) pgd_offset(&init_mm, address) - - #define pmd_index(address) \ -@@ -373,7 +395,12 @@ static inline pmd_t * pmd_offset(pgd_t * - return (pmd_t *) dir; - } - --/* Find an entry in the third-level page table.. */ -+/* -+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE] -+ * -+ * this macro returns the index of the entry in the pte page which would -+ * control the given virtual address -+ */ - #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) - #define pte_offset_kernel(dir, address) \ - ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address)) -@@ -387,11 +414,11 @@ static inline pmd_t * pmd_offset(pgd_t * - #define update_mmu_cache(vma,address,pte) do ; while (0) - - /* Encode and de-code a swap entry */ --#define __swp_type(x) (((x).val >> 3) & 0x7f) --#define __swp_offset(x) ((x).val >> 10) -+#define __swp_type(x) (((x).val >> 4) & 0x3f) -+#define __swp_offset(x) ((x).val >> 11) - - #define __swp_entry(type, offset) \ -- ((swp_entry_t) { ((type) << 3) | ((offset) << 10) }) -+ ((swp_entry_t) { ((type) << 4) | ((offset) << 11) }) - #define __pte_to_swp_entry(pte) \ - ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) }) - #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -diff -puN include/asm-um/processor-generic.h~Main-uml-patch-no-skas include/asm-um/processor-generic.h ---- uml-linux-2.6.7/include/asm-um/processor-generic.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.669295736 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/processor-generic.h 2004-06-29 21:02:55.764281296 +0200 -@@ -11,33 +11,14 @@ struct pt_regs; - struct task_struct; - - #include "linux/config.h" --#include "linux/signal.h" - #include "asm/ptrace.h" --#include "asm/siginfo.h" - #include "choose-mode.h" - - struct mm_struct; - - #define current_text_addr() ((void *) 0) - --#define cpu_relax() do ; while (0) -- --#ifdef CONFIG_MODE_TT --struct proc_tt_mode { -- int extern_pid; -- int tracing; -- int switch_pipe[2]; -- int singlestep_syscall; -- int vm_seq; --}; --#endif -- --#ifdef CONFIG_MODE_SKAS --struct proc_skas_mode { -- void *switch_buf; -- void *fork_buf; --}; --#endif -+#define cpu_relax() barrier() - - struct thread_struct { - int forking; -@@ -46,6 +27,7 @@ struct thread_struct { - struct pt_regs regs; - unsigned long cr2; - int err; -+ unsigned long trap_no; - void *fault_addr; - void *fault_catcher; - struct task_struct *prev_sched; -@@ -54,10 +36,20 @@ struct thread_struct { - struct arch_thread arch; - union { - #ifdef CONFIG_MODE_TT -- struct proc_tt_mode tt; -+ struct { -+ int extern_pid; -+ int tracing; -+ int switch_pipe[2]; -+ int singlestep_syscall; -+ int vm_seq; -+ } tt; - #endif - #ifdef CONFIG_MODE_SKAS -- struct proc_skas_mode skas; -+ struct { -+ void *switch_buf; -+ void *fork_buf; -+ int mm_count; -+ } skas; - #endif - } mode; - struct { -@@ -99,14 +91,19 @@ typedef struct { - } mm_segment_t; - - extern struct task_struct *alloc_task_struct(void); --extern void free_task_struct(struct task_struct *task); - - extern void release_thread(struct task_struct *); - extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - extern void dump_thread(struct pt_regs *regs, struct user *u); -+extern void prepare_to_copy(struct task_struct *tsk); - - extern unsigned long thread_saved_pc(struct task_struct *t); - -+static inline void mm_copy_segments(struct mm_struct *from_mm, -+ struct mm_struct *new_mm) -+{ -+} -+ - #define init_stack (init_thread_union.stack) - - /* -diff -puN include/asm-um/processor-i386.h~Main-uml-patch-no-skas include/asm-um/processor-i386.h ---- uml-linux-2.6.7/include/asm-um/processor-i386.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.670295584 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/processor-i386.h 2004-06-29 21:02:55.764281296 +0200 -@@ -6,8 +6,8 @@ - #ifndef __UM_PROCESSOR_I386_H - #define __UM_PROCESSOR_I386_H - --extern int cpu_has_xmm; --extern int cpu_has_cmov; -+extern int host_has_xmm; -+extern int host_has_cmov; - - struct arch_thread { - unsigned long debugregs[8]; -diff -puN /dev/null include/asm-um/sections.h ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ uml-linux-2.6.7-paolo/include/asm-um/sections.h 2004-06-29 21:02:55.764281296 +0200 -@@ -0,0 +1,7 @@ -+#ifndef _UM_SECTIONS_H -+#define _UM_SECTIONS_H -+ -+/* nothing to see, move along */ -+#include <asm-generic/sections.h> -+ -+#endif -diff -puN include/asm-um/smp.h~Main-uml-patch-no-skas include/asm-um/smp.h ---- uml-linux-2.6.7/include/asm-um/smp.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.672295280 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/smp.h 2004-06-29 21:02:55.764281296 +0200 -@@ -10,7 +10,7 @@ - - extern cpumask_t cpu_online_map; - --#define smp_processor_id() (current->thread_info->cpu) -+#define smp_processor_id() (current_thread->cpu) - #define cpu_logical_map(n) (n) - #define cpu_number_map(n) (n) - #define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */ -diff -L include/asm-um/smplock.h -puN include/asm-um/smplock.h~Main-uml-patch-no-skas /dev/null ---- uml-linux-2.6.7/include/asm-um/smplock.h -+++ /dev/null 1970-01-01 01:00:00.000000000 +0100 -@@ -1,6 +0,0 @@ --#ifndef __UM_SMPLOCK_H --#define __UM_SMPLOCK_H -- --#include "asm/arch/smplock.h" -- --#endif -diff -L include/asm-um/spinlock.h -puN include/asm-um/spinlock.h~Main-uml-patch-no-skas /dev/null ---- uml-linux-2.6.7/include/asm-um/spinlock.h -+++ /dev/null 1970-01-01 01:00:00.000000000 +0100 -@@ -1,10 +0,0 @@ --#ifndef __UM_SPINLOCK_H --#define __UM_SPINLOCK_H -- --#include "linux/config.h" -- --#ifdef CONFIG_SMP --#include "asm/arch/spinlock.h" --#endif -- --#endif -diff -puN include/asm-um/system-generic.h~Main-uml-patch-no-skas include/asm-um/system-generic.h ---- uml-linux-2.6.7/include/asm-um/system-generic.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.675294824 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/system-generic.h 2004-06-29 21:02:55.765281144 +0200 -@@ -23,8 +23,10 @@ extern int get_signals(void); - extern void block_signals(void); - extern void unblock_signals(void); - --#define local_save_flags(flags) do { (flags) = get_signals(); } while(0) --#define local_irq_restore(flags) do { set_signals(flags); } while(0) -+#define local_save_flags(flags) do { typecheck(unsigned long, flags); \ -+ (flags) = get_signals(); } while(0) -+#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \ -+ set_signals(flags); } while(0) - - #define local_irq_save(flags) do { local_save_flags(flags); \ - local_irq_disable(); } while(0) -@@ -39,4 +41,7 @@ extern void unblock_signals(void); - (flags == 0); \ - }) - -+extern void *_switch_to(void *prev, void *next, void *last); -+#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) -+ - #endif -diff -puN include/asm-um/system-i386.h~Main-uml-patch-no-skas include/asm-um/system-i386.h ---- uml-linux-2.6.7/include/asm-um/system-i386.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.676294672 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/system-i386.h 2004-06-29 21:02:55.765281144 +0200 -@@ -2,36 +2,5 @@ - #define __UM_SYSTEM_I386_H - - #include "asm/system-generic.h" -- --static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, -- unsigned long new, int size) --{ -- unsigned long prev; -- switch (size) { -- case 1: -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" -- : "=a"(prev) -- : "q"(new), "m"(*__xg(ptr)), "0"(old) -- : "memory"); -- return prev; -- case 2: -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" -- : "=a"(prev) -- : "q"(new), "m"(*__xg(ptr)), "0"(old) -- : "memory"); -- return prev; -- case 4: -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" -- : "=a"(prev) -- : "q"(new), "m"(*__xg(ptr)), "0"(old) -- : "memory"); -- return prev; -- } -- return old; --} -- --#define cmpxchg(ptr,o,n)\ -- ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ -- (unsigned long)(n),sizeof(*(ptr)))) - - #endif -diff -puN include/asm-um/thread_info.h~Main-uml-patch-no-skas include/asm-um/thread_info.h ---- uml-linux-2.6.7/include/asm-um/thread_info.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.677294520 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/thread_info.h 2004-06-29 21:02:55.765281144 +0200 -@@ -9,6 +9,7 @@ - #ifndef __ASSEMBLY__ - - #include <asm/processor.h> -+#include <asm/types.h> - - struct thread_info { - struct task_struct *task; /* main task structure */ -@@ -43,15 +44,18 @@ struct thread_info { - static inline struct thread_info *current_thread_info(void) - { - struct thread_info *ti; -- __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL)); -+ unsigned long mask = PAGE_SIZE * -+ (1 << CONFIG_KERNEL_STACK_ORDER) - 1; -+ __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask)); - return ti; - } - - /* thread information allocation */ --#define THREAD_SIZE (4*PAGE_SIZE) --#define alloc_thread_info(tsk) ((struct thread_info *) \ -- __get_free_pages(GFP_KERNEL,2)) --#define free_thread_info(ti) free_pages((unsigned long) (ti), 2) -+#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) -+#define alloc_thread_info(tsk) \ -+ ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL)) -+#define free_thread_info(ti) kfree(ti) -+ - #define get_thread_info(ti) get_task_struct((ti)->task) - #define put_thread_info(ti) put_task_struct((ti)->task) - -@@ -65,11 +69,13 @@ static inline struct thread_info *curren - #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling - * TIF_NEED_RESCHED - */ -+#define TIF_RESTART_BLOCK 4 - - #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) - #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) - #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) -+#define _TIF_RESTART_BLOCK (1 << TIF_RESTART_BLOCK) - - #endif - -diff -puN include/asm-um/timex.h~Main-uml-patch-no-skas include/asm-um/timex.h ---- uml-linux-2.6.7/include/asm-um/timex.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.678294368 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/timex.h 2004-06-29 21:02:55.766280992 +0200 -@@ -1,8 +1,6 @@ - #ifndef __UM_TIMEX_H - #define __UM_TIMEX_H - --#include "linux/time.h" -- - typedef unsigned long cycles_t; - - #define cacheflush_time (0) -diff -puN include/asm-um/uaccess.h~Main-uml-patch-no-skas include/asm-um/uaccess.h ---- uml-linux-2.6.7/include/asm-um/uaccess.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.680294064 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/uaccess.h 2004-06-29 21:02:55.766280992 +0200 -@@ -6,6 +6,8 @@ - #ifndef __UM_UACCESS_H - #define __UM_UACCESS_H - -+#include "linux/sched.h" -+ - #define VERIFY_READ 0 - #define VERIFY_WRITE 1 - -diff -puN include/asm-um/unistd.h~Main-uml-patch-no-skas include/asm-um/unistd.h ---- uml-linux-2.6.7/include/asm-um/unistd.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.681293912 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/unistd.h 2004-06-29 21:02:55.766280992 +0200 -@@ -48,7 +48,10 @@ extern int um_execve(const char *file, c - set_fs(KERNEL_DS); \ - ret = sys(args); \ - set_fs(fs); \ -- return ret; -+ if (ret >= 0) \ -+ return ret; \ -+ errno = -(long)ret; \ -+ return -1; - - static inline long open(const char *pathname, int flags, int mode) - { -diff -puN include/linux/gfp.h~Main-uml-patch-no-skas include/linux/gfp.h ---- uml-linux-2.6.7/include/linux/gfp.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.697291480 +0200 -+++ uml-linux-2.6.7-paolo/include/linux/gfp.h 2004-06-29 21:02:55.766280992 +0200 -@@ -73,6 +73,11 @@ struct vm_area_struct; - * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets - * optimized to &contig_page_data at compile-time. - */ -+ -+#ifndef HAVE_ARCH_FREE_PAGE -+static inline void arch_free_page(struct page *page, int order) { } -+#endif -+ - extern struct page * - FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *)); - -diff -puN include/linux/time.h~Main-uml-patch-no-skas include/linux/time.h ---- uml-linux-2.6.7/include/linux/time.h~Main-uml-patch-no-skas 2004-06-29 21:02:55.698291328 +0200 -+++ uml-linux-2.6.7-paolo/include/linux/time.h 2004-06-29 21:02:55.767280840 +0200 -@@ -41,7 +41,7 @@ struct timezone { - * Have the 32 bit jiffies value wrap 5 minutes after boot - * so jiffies wrap bugs show up earlier. - */ --#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) -+#define INITIAL_JIFFIES ((unsigned long)(0)) - - /* - * Change timeval to jiffies, trying to avoid the -diff -puN mm/page_alloc.c~Main-uml-patch-no-skas mm/page_alloc.c ---- uml-linux-2.6.7/mm/page_alloc.c~Main-uml-patch-no-skas 2004-06-29 21:02:55.699291176 +0200 -+++ uml-linux-2.6.7-paolo/mm/page_alloc.c 2004-06-29 21:02:55.767280840 +0200 -@@ -279,6 +279,8 @@ void __free_pages_ok(struct page *page, - LIST_HEAD(list); - int i; - -+ arch_free_page(page, order); -+ - mod_page_state(pgfree, 1 << order); - for (i = 0 ; i < (1 << order) ; ++i) - free_pages_check(__FUNCTION__, page + i); -@@ -497,6 +499,8 @@ static void fastcall free_hot_cold_page( - struct per_cpu_pages *pcp; - unsigned long flags; - -+ arch_free_page(page, 0); -+ - kernel_map_pages(page, 1, 0); - inc_page_state(pgfree); - free_pages_check(__FUNCTION__, page); -_ diff --git a/linux-uml/linux-uml-2.6.7/MakeHelp.patch b/linux-uml/linux-uml-2.6.7/MakeHelp.patch deleted file mode 100644 index dfce0d1de5..0000000000 --- a/linux-uml/linux-uml-2.6.7/MakeHelp.patch +++ /dev/null @@ -1,23 +0,0 @@ - -Makes "make help ARCH=um" work. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/Makefile | 6 ++++++ - 1 files changed, 6 insertions(+) - -diff -puN arch/um/Makefile~MakeHelp arch/um/Makefile ---- uml-linux-2.6.7/arch/um/Makefile~MakeHelp 2004-06-29 21:03:01.703378416 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Makefile 2004-06-29 21:03:01.705378112 +0200 -@@ -209,3 +209,9 @@ $(ARCH_DIR)/util: FORCE - $(Q)$(MAKE) $(build)=$@ - - export SUBARCH USER_CFLAGS OS -+ -+all: linux -+ -+define archhelp -+ echo '* linux - Binary kernel image (./linux)' -+endef -_ diff --git a/linux-uml/linux-uml-2.6.7/Move_away_from_user.patch b/linux-uml/linux-uml-2.6.7/Move_away_from_user.patch deleted file mode 100644 index 5daab7aea7..0000000000 --- a/linux-uml/linux-uml-2.6.7/Move_away_from_user.patch +++ /dev/null @@ -1,140 +0,0 @@ - -Reduces code in *_user files, by moving it in _kern files if already possible. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/drivers/chan_kern.c | 47 +++++++++++++++++++++ - uml-linux-2.6.7-paolo/arch/um/drivers/chan_user.c | 48 ---------------------- - 2 files changed, 47 insertions(+), 48 deletions(-) - -diff -puN arch/um/drivers/chan_kern.c~Move_away_from_user arch/um/drivers/chan_kern.c ---- uml-linux-2.6.7/arch/um/drivers/chan_kern.c~Move_away_from_user 2004-06-29 21:03:02.858202856 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/chan_kern.c 2004-06-29 21:03:02.861202400 +0200 -@@ -17,6 +17,7 @@ - #include "irq_user.h" - #include "sigio.h" - #include "line.h" -+#include "os.h" - - static void *not_configged_init(char *str, int device, struct chan_opts *opts) - { -@@ -87,6 +88,52 @@ static struct chan_ops not_configged_ops - .winch = 0, - }; - -+void generic_close(int fd, void *unused) -+{ -+ os_close_file(fd); -+} -+ -+int generic_read(int fd, char *c_out, void *unused) -+{ -+ int n; -+ -+ n = os_read_file(fd, c_out, sizeof(*c_out)); -+ -+ if(n == -EAGAIN) -+ return(0); -+ else if(n == 0) -+ return(-EIO); -+ return(n); -+} -+ -+int generic_write(int fd, const char *buf, int n, void *unused) -+{ -+ return(os_write_file(fd, buf, n)); -+} -+ -+int generic_window_size(int fd, void *unused, unsigned short *rows_out, -+ unsigned short *cols_out) -+{ -+ int rows, cols; -+ int ret; -+ -+ ret = os_window_size(fd, &rows, &cols); -+ if(ret < 0) -+ return(ret); -+ -+ ret = ((*rows_out != rows) || (*cols_out != cols)); -+ -+ *rows_out = rows; -+ *cols_out = cols; -+ -+ return(ret); -+} -+ -+void generic_free(void *data) -+{ -+ kfree(data); -+} -+ - static void tty_receive_char(struct tty_struct *tty, char ch) - { - if(tty == NULL) return; -diff -puN arch/um/drivers/chan_user.c~Move_away_from_user arch/um/drivers/chan_user.c ---- uml-linux-2.6.7/arch/um/drivers/chan_user.c~Move_away_from_user 2004-06-29 21:03:02.859202704 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/chan_user.c 2004-06-29 21:03:02.861202400 +0200 -@@ -21,31 +21,6 @@ - #include "choose-mode.h" - #include "mode.h" - --void generic_close(int fd, void *unused) --{ -- os_close_file(fd); --} -- --int generic_read(int fd, char *c_out, void *unused) --{ -- int n; -- -- n = os_read_file(fd, c_out, sizeof(*c_out)); -- -- if(n == -EAGAIN) -- return(0); -- else if(n == 0) -- return(-EIO); -- return(n); --} -- --/* XXX Trivial wrapper around os_write_file */ -- --int generic_write(int fd, const char *buf, int n, void *unused) --{ -- return(os_write_file(fd, buf, n)); --} -- - int generic_console_write(int fd, const char *buf, int n, void *unused) - { - struct termios save, new; -@@ -62,29 +37,6 @@ int generic_console_write(int fd, const - return(err); - } - --int generic_window_size(int fd, void *unused, unsigned short *rows_out, -- unsigned short *cols_out) --{ -- int rows, cols; -- int ret; -- -- ret = os_window_size(fd, &rows, &cols); -- if(ret < 0) -- return(ret); -- -- ret = ((*rows_out != rows) || (*cols_out != cols)); -- -- *rows_out = rows; -- *cols_out = cols; -- -- return(ret); --} -- --void generic_free(void *data) --{ -- kfree(data); --} -- - static void winch_handler(int sig) - { - } -_ diff --git a/linux-uml/linux-uml-2.6.7/NR_tkill_undefined.patch b/linux-uml/linux-uml-2.6.7/NR_tkill_undefined.patch deleted file mode 100644 index 21c5f58dd7..0000000000 --- a/linux-uml/linux-uml-2.6.7/NR_tkill_undefined.patch +++ /dev/null @@ -1,27 +0,0 @@ - -Avoids compile failure when host misses tkill(), by simply using kill() in -that case. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c | 5 ++++- - 1 files changed, 4 insertions(+), 1 deletion(-) - -diff -puN arch/um/os-Linux/process.c~NR_tkill_undefined arch/um/os-Linux/process.c ---- uml-linux-2.6.7/arch/um/os-Linux/process.c~NR_tkill_undefined 2004-06-29 21:03:02.577245568 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/os-Linux/process.c 2004-06-29 21:03:02.579245264 +0200 -@@ -93,8 +93,11 @@ void os_kill_process(int pid, int reap_c - - void os_usr1_process(int pid) - { -+#ifdef __NR_tkill - syscall(__NR_tkill, pid, SIGUSR1); -- /* kill(pid, SIGUSR1); */ -+#else -+ kill(pid, SIGUSR1); -+#endif - } - - int os_getpid(void) -_ diff --git a/linux-uml/linux-uml-2.6.7/SMP_fix.patch b/linux-uml/linux-uml-2.6.7/SMP_fix.patch deleted file mode 100644 index 8f7b17d5e4..0000000000 --- a/linux-uml/linux-uml-2.6.7/SMP_fix.patch +++ /dev/null @@ -1,510 +0,0 @@ ---- - - uml-linux-2.6.7-paolo/arch/um/include/kern_util.h | 11 + - uml-linux-2.6.7-paolo/arch/um/kernel/process_kern.c | 11 + - uml-linux-2.6.7-paolo/arch/um/kernel/reboot.c | 1 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c | 73 ----------- - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c | 93 +++++++++++++-- - uml-linux-2.6.7-paolo/arch/um/kernel/smp.c | 4 - uml-linux-2.6.7-paolo/arch/um/kernel/tt/process_kern.c | 5 - uml-linux-2.6.7-paolo/arch/um/sys-i386/ldt.c | 11 + - uml-linux-2.6.7-paolo/include/asm-um/smp.h | 21 ++- - uml-linux-2.6.7-paolo/include/asm-um/spinlock.h | 13 ++ - 10 files changed, 150 insertions(+), 93 deletions(-) - -diff -puN arch/um/kernel/skas/process.c~SMP_fix arch/um/kernel/skas/process.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process.c~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c 2004-06-21 20:03:56.000000000 +0200 -@@ -100,7 +100,6 @@ static int userspace_tramp(void *arg) - } - - /* Each element set once, and only accessed by a single processor anyway */ --#define NR_CPUS 1 - int userspace_pid[NR_CPUS]; - - void start_userspace(int cpu) -@@ -301,39 +300,6 @@ void switch_threads(void *me, void *next - siglongjmp(*next_buf, 1); - } - --static jmp_buf initial_jmpbuf; -- --/* XXX Make these percpu */ --static void (*cb_proc)(void *arg); --static void *cb_arg; --static jmp_buf *cb_back; -- --int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) --{ -- jmp_buf **switch_buf = switch_buf_ptr; -- int n; -- -- *fork_buf_ptr = &initial_jmpbuf; -- n = sigsetjmp(initial_jmpbuf, 1); -- if(n == 0) -- new_thread_proc((void *) stack, new_thread_handler); -- else if(n == 1) -- remove_sigstack(); -- else if(n == 2){ -- (*cb_proc)(cb_arg); -- siglongjmp(*cb_back, 1); -- } -- else if(n == 3){ -- kmalloc_ok = 0; -- return(0); -- } -- else if(n == 4){ -- kmalloc_ok = 0; -- return(1); -- } -- siglongjmp(**switch_buf, 1); --} -- - void remove_sigstack(void) - { - stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE, -@@ -344,36 +310,6 @@ void remove_sigstack(void) - panic("disabling signal stack failed, errno = %d\n", errno); - } - --void initial_thread_cb_skas(void (*proc)(void *), void *arg) --{ -- jmp_buf here; -- -- cb_proc = proc; -- cb_arg = arg; -- cb_back = &here; -- -- block_signals(); -- if(sigsetjmp(here, 1) == 0) -- siglongjmp(initial_jmpbuf, 2); -- unblock_signals(); -- -- cb_proc = NULL; -- cb_arg = NULL; -- cb_back = NULL; --} -- --void halt_skas(void) --{ -- block_signals(); -- siglongjmp(initial_jmpbuf, 3); --} -- --void reboot_skas(void) --{ -- block_signals(); -- siglongjmp(initial_jmpbuf, 4); --} -- - int new_mm(int from) - { - struct proc_mm_op copy; -@@ -400,8 +336,7 @@ void switch_mm_skas(int mm_fd) - { - int err; - --#warning need cpu pid in switch_mm_skas -- err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd); -+ err = ptrace(PTRACE_SWITCH_MM, userspace_pid[cpu()], 0, mm_fd); - if(err) - panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n", - errno); -@@ -409,8 +344,10 @@ void switch_mm_skas(int mm_fd) - - void kill_off_processes_skas(void) - { --#warning need to loop over userspace_pids in kill_off_processes_skas -- os_kill_process(userspace_pid[0], 1); -+ int i; -+ for(i = 0; i < ncpus; i++){ -+ os_kill_process(userspace_pid[i], 1); -+ } - } - - void init_registers(int pid) -diff -puN arch/um/kernel/skas/process_kern.c~SMP_fix arch/um/kernel/skas/process_kern.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process_kern.c~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c 2004-06-21 19:48:57.000000000 +0200 -@@ -3,6 +3,11 @@ - * Licensed under the GPL - */ - -+/*I checked that this is safe to include here; if it becomes not, -+ * we can always wrap it*/ -+ -+#include <setjmp.h> -+ - #include "linux/sched.h" - #include "linux/slab.h" - #include "linux/ptrace.h" -@@ -10,6 +15,7 @@ - #include "linux/file.h" - #include "linux/errno.h" - #include "linux/init.h" -+#include "linux/percpu.h" - #include "asm/uaccess.h" - #include "asm/atomic.h" - #include "kern_util.h" -@@ -22,6 +28,7 @@ - #include "frame.h" - #include "kern.h" - #include "mode.h" -+#include "asm/smp.h" - - #ifdef PTRACE_SYSEMU - static atomic_t using_sysemu; -@@ -91,7 +98,10 @@ void *switch_to_skas(void *prev, void *n - from = prev; - to = next; - -- /* XXX need to check runqueues[cpu].idle */ -+ /* XXX need to check runqueues[cpu].idle. jdike*/ -+ /* Are you sure? 1) runqueues is private to sched.c -+ * 2) The idle tasks have *always* pid 0 -+ * Blaisorblade*/ - if(current->pid == 0) - switch_timers(0); - -@@ -197,7 +207,7 @@ int copy_thread_skas(int nr, unsigned lo - - void init_idle_skas(void) - { -- cpu_tasks[current_thread->cpu].pid = os_getpid(); -+ cpu_tasks[smp_processor_id()].pid = os_getpid(); - default_idle(); - } - -@@ -236,14 +246,83 @@ int start_uml_skas(void) - - int external_pid_skas(struct task_struct *task) - { --#warning Need to look up userspace_pid by cpu -- return(userspace_pid[0]); -+ return(userspace_pid[smp_processor_id()]); -+} -+ -+static jmp_buf initial_jmpbuf; -+ -+/* XXX Make these percpu */ -+/*static void (*cb_proc)(void *arg); -+static void *cb_arg; -+static jmp_buf *cb_back;*/ -+static DEFINE_PER_CPU(void (*)(void*), cb_proc); -+static DEFINE_PER_CPU(void*, cb_arg); -+static DEFINE_PER_CPU(jmp_buf*, cb_back); -+ -+int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) -+{ -+ jmp_buf **switch_buf = switch_buf_ptr; -+ int n; -+ -+ *fork_buf_ptr = &initial_jmpbuf; -+ n = sigsetjmp(initial_jmpbuf, 1); -+ if(n == 0) -+ new_thread_proc((void *) stack, new_thread_handler); -+ else if(n == 1) -+ remove_sigstack(); -+ else if(n == 2){ -+ jmp_buf* loc_cb_back; -+ -+ preempt_disable(); -+ -+ (*__get_cpu_var(cb_proc))(__get_cpu_var(cb_arg)); -+ loc_cb_back = __get_cpu_var(cb_back); -+ -+ preempt_enable(); -+ -+ siglongjmp(*loc_cb_back, 1); -+ } -+ else if(n == 3){ -+ kmalloc_ok = 0; -+ return(0); -+ } -+ else if(n == 4){ -+ kmalloc_ok = 0; -+ return(1); -+ } -+ siglongjmp(**switch_buf, 1); -+} -+ -+void initial_thread_cb_skas(void (*proc)(void *), void *arg) -+{ -+ jmp_buf here; -+ -+ preempt_disable(); -+ __get_cpu_var(cb_proc) = proc; -+ __get_cpu_var(cb_arg) = arg; -+ __get_cpu_var(cb_back) = &here; -+ -+ block_signals(); -+ if(sigsetjmp(here, 1) == 0) -+ siglongjmp(initial_jmpbuf, 2); -+ unblock_signals(); -+ -+ __get_cpu_var(cb_proc) = NULL; -+ __get_cpu_var(cb_arg) = NULL; -+ __get_cpu_var(cb_back) = NULL; -+ preempt_enable(); -+} -+ -+void halt_skas(void) -+{ -+ block_signals(); -+ siglongjmp(initial_jmpbuf, 3); - } - --int thread_pid_skas(struct task_struct *task) -+void reboot_skas(void) - { --#warning Need to look up userspace_pid by cpu -- return(userspace_pid[0]); -+ block_signals(); -+ siglongjmp(initial_jmpbuf, 4); - } - - /* -diff -puN arch/um/kernel/process_kern.c~SMP_fix arch/um/kernel/process_kern.c ---- uml-linux-2.6.7/arch/um/kernel/process_kern.c~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/process_kern.c 2004-06-21 19:48:57.000000000 +0200 -@@ -43,6 +43,7 @@ - #include "mode.h" - #include "mode_kern.h" - #include "choose-mode.h" -+#include "asm/smp.h" - - /* This is a per-cpu array. A processor only modifies its entry and it only - * cares about its entry, so it's OK if another processor is modifying its -@@ -62,6 +63,7 @@ struct task_struct *get_task(int pid, in - return(ret); - } - -+/*Call with preempt disabled (with preempt on we can change CPU, and then even external_pid)*/ - int external_pid(void *t) - { - struct task_struct *task = t ? t : current; -@@ -110,6 +112,7 @@ int kernel_thread(int (*fn)(void *), voi - return(pid); - } - -+/*Must be called with preempt disabled.*/ - void switch_mm(struct mm_struct *prev, struct mm_struct *next, - struct task_struct *tsk) - { -@@ -119,11 +122,12 @@ void switch_mm(struct mm_struct *prev, s - set_bit(cpu, &next->cpu_vm_mask); - } - -+/*Must be called with preempt disabled.*/ - void set_current(void *t) - { - struct task_struct *task = t; - -- cpu_tasks[task->thread_info->cpu] = ((struct cpu_task) -+ cpu_tasks[smp_processor_id()] = ((struct cpu_task) - { external_pid(task), task }); - } - -@@ -377,8 +381,9 @@ int strlen_user_proc(char *str) - int smp_sigio_handler(void) - { - #ifdef CONFIG_SMP -- int cpu = current_thread->cpu; -+ int cpu = get_cpu(); - IPI_handler(cpu); -+ put_cpu(); - if(cpu != 0) - return(1); - #endif -@@ -392,7 +397,7 @@ int um_in_interrupt(void) - - int cpu(void) - { -- return(current_thread->cpu); -+ return(smp_processor_id()); - } - - /* -diff -puN arch/um/include/kern_util.h~SMP_fix arch/um/include/kern_util.h ---- uml-linux-2.6.7/arch/um/include/kern_util.h~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/kern_util.h 2004-06-21 20:02:22.000000000 +0200 -@@ -6,8 +6,15 @@ - #ifndef __KERN_UTIL_H__ - #define __KERN_UTIL_H__ - --#include "linux/threads.h" - #include "sysdep/ptrace.h" -+#include "uml-config.h" -+ -+#undef NR_CPUS -+#ifdef UML_CONFIG_SMP -+#define NR_CPUS UML_CONFIG_NR_CPUS -+#else -+#define NR_CPUS 1 -+#endif - - extern int ncpus; - extern char *linux_prog; -@@ -17,8 +24,6 @@ extern int timer_irq_inited; - extern int jail; - extern int nsyscalls; - --extern struct task_struct *idle_threads[NR_CPUS]; -- - #define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK)) - #define UML_ROUND_UP(addr) \ - UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) -diff -puN arch/um/kernel/reboot.c~SMP_fix arch/um/kernel/reboot.c ---- uml-linux-2.6.7/arch/um/kernel/reboot.c~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/reboot.c 2004-06-21 19:48:57.000000000 +0200 -@@ -11,6 +11,7 @@ - #include "os.h" - #include "mode.h" - #include "choose-mode.h" -+#include "asm/smp.h" - - #ifdef CONFIG_SMP - static void kill_idlers(int me) -diff -puN include/asm-um/smp.h~SMP_fix include/asm-um/smp.h ---- uml-linux-2.6.7/include/asm-um/smp.h~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/include/asm-um/smp.h 2004-06-21 19:48:57.000000000 +0200 -@@ -1,26 +1,35 @@ - #ifndef __UM_SMP_H - #define __UM_SMP_H - -+#ifndef __KERNEL__ -+#error Cannot be included from user-space files! -+#endif -+#include "linux/config.h" -+ - #ifdef CONFIG_SMP - --#include "linux/config.h" - #include "linux/bitops.h" - #include "asm/current.h" - #include "linux/cpumask.h" -+#include "linux/threads.h" - - extern cpumask_t cpu_online_map; - - #define smp_processor_id() (current_thread->cpu) --#define cpu_logical_map(n) (n) --#define cpu_number_map(n) (n) - #define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */ - extern int hard_smp_processor_id(void); -+/*XXX figure out what to do with this, which was added in 2.6 asm-i386/smp.h */ -+/*static __inline int logical_smp_processor_id(void)*/ - #define NO_PROC_ID -1 - --#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) -+/*XXX check we can remove these. Already out of the i386 one.*/ -+/*#define cpu_logical_map(n) (n) -+#define cpu_number_map(n) (n) -+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)*/ - - extern int ncpus; - -+extern struct task_struct *idle_threads[NR_CPUS]; - - extern inline void smp_cpus_done(unsigned int maxcpus) - { -@@ -28,4 +37,8 @@ extern inline void smp_cpus_done(unsigne - - #endif - -+#ifdef CONFIG_MODE_SKAS -+extern int userspace_pid[NR_CPUS]; -+#endif -+ - #endif -diff -puN arch/um/kernel/smp.c~SMP_fix arch/um/kernel/smp.c ---- uml-linux-2.6.7/arch/um/kernel/smp.c~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/smp.c 2004-06-21 19:48:57.000000000 +0200 -@@ -29,7 +29,9 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_ga - #include "os.h" - - /* CPU online map, set by smp_boot_cpus */ --unsigned long cpu_online_map = CPU_MASK_NONE; -+cpumask_t cpu_online_map = CPU_MASK_NONE; -+cpumask_t cpu_possible_map; -+cpumask_t cpu_present_map; - - EXPORT_SYMBOL(cpu_online_map); - -diff -puN arch/um/sys-i386/ldt.c~SMP_fix arch/um/sys-i386/ldt.c ---- uml-linux-2.6.7/arch/um/sys-i386/ldt.c~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/sys-i386/ldt.c 2004-06-21 19:48:57.000000000 +0200 -@@ -5,8 +5,10 @@ - - #include "linux/config.h" - #include "linux/slab.h" -+#include "linux/types.h" - #include "asm/uaccess.h" - #include "asm/ptrace.h" -+#include "asm/smp.h" - #include "choose-mode.h" - #include "kern.h" - -@@ -21,13 +23,13 @@ int sys_modify_ldt_tt(int func, void *pt - #endif - - #ifdef CONFIG_MODE_SKAS --extern int userspace_pid; - - int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) - { - struct ptrace_ldt ldt; - void *buf; - int res, n; -+ u32 cpu; - - buf = kmalloc(bytecount, GFP_KERNEL); - if(buf == NULL) -@@ -50,7 +52,12 @@ int sys_modify_ldt_skas(int func, void * - ldt = ((struct ptrace_ldt) { .func = func, - .ptr = buf, - .bytecount = bytecount }); -- res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt); -+ -+ cpu = get_cpu(); -+ -+ res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt); -+ -+ put_cpu(); - if(res < 0) - goto out; - -diff -puN /dev/null include/asm-um/spinlock.h ---- /dev/null 2002-11-29 19:17:06.000000000 +0100 -+++ uml-linux-2.6.7-paolo/include/asm-um/spinlock.h 2004-06-21 19:48:57.000000000 +0200 -@@ -0,0 +1,13 @@ -+#ifndef __UM_SPINLOCK_H -+#define __UM_SPINLOCK_H -+ -+#ifndef __KERNEL__ -+#error Cannot be included from userspace files! -+#endif -+#include "linux/config.h" -+ -+#ifdef CONFIG_SMP -+#include "asm/arch/spinlock.h" -+#endif -+ -+#endif -diff -puN arch/um/kernel/tt/process_kern.c~SMP_fix arch/um/kernel/tt/process_kern.c ---- uml-linux-2.6.7/arch/um/kernel/tt/process_kern.c~SMP_fix 2004-06-21 19:48:57.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/tt/process_kern.c 2004-06-21 19:48:57.000000000 +0200 -@@ -512,11 +512,6 @@ int external_pid_tt(struct task_struct * - return(task->thread.mode.tt.extern_pid); - } - --int thread_pid_tt(struct task_struct *task) --{ -- return(task->thread.mode.tt.extern_pid); --} -- - int is_valid_pid(int pid) - { - struct task_struct *task; - -_ diff --git a/linux-uml/linux-uml-2.6.7/defconfig b/linux-uml/linux-uml-2.6.7/defconfig deleted file mode 100644 index 3d0d15502d..0000000000 --- a/linux-uml/linux-uml-2.6.7/defconfig +++ /dev/null @@ -1,441 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_USERMODE=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y - -# -# UML-specific options -# -CONFIG_MODE_TT=y -CONFIG_MODE_SKAS=y -CONFIG_NET=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_HOSTFS=y -CONFIG_HPPFS=y -CONFIG_MCONSOLE=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_HOST_2G_2G is not set -# CONFIG_UML_SMP is not set -# CONFIG_SMP is not set -CONFIG_NEST_LEVEL=0 -CONFIG_KERNEL_HALF_GIGS=1 -# CONFIG_HIGHMEM is not set -CONFIG_PROC_MM=y -CONFIG_KERNEL_STACK_ORDER=2 -CONFIG_UML_REAL_TIME_CLOCK=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_HOTPLUG is not set -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Generic Driver Options -# - -# -# Character Devices -# -CONFIG_STDIO_CONSOLE=y -CONFIG_SSL=y -CONFIG_FD_CHAN=y -CONFIG_NULL_CHAN=y -CONFIG_PORT_CHAN=y -CONFIG_PTY_CHAN=y -CONFIG_TTY_CHAN=y -CONFIG_XTERM_CHAN=y -CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -CONFIG_CON_CHAN="xterm" -CONFIG_SSL_CHAN="pty" -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -# CONFIG_WATCHDOG is not set -CONFIG_UML_SOUND=y -CONFIG_SOUND=y -CONFIG_HOSTAUDIO=y - -# -# Block Devices -# -CONFIG_BLK_DEV_UBD=y -# CONFIG_BLK_DEV_UBD_SYNC is not set -CONFIG_BLK_DEV_COW_COMMON=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_MMAPPER is not set -CONFIG_NETDEVICES=y - -# -# UML Network Devices -# -CONFIG_UML_NET=y -CONFIG_UML_NET_ETHERTAP=y -CONFIG_UML_NET_TUNTAP=y -CONFIG_UML_NET_SLIP=y -CONFIG_UML_NET_DAEMON=y -CONFIG_UML_NET_MCAST=y -# CONFIG_UML_NET_PCAP is not set -CONFIG_UML_NET_SLIRP=y - -# -# Networking support -# - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPPOE is not set -CONFIG_SLIP=y -# CONFIG_SLIP_COMPRESSED is not set -# CONFIG_SLIP_SMART is not set -# CONFIG_SLIP_MODE_SLIP6 is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -CONFIG_MINIX_FS=y -# CONFIG_ROMFS_FS is not set -CONFIG_QUOTA=y -# CONFIG_QFMT_V1 is not set -# CONFIG_QFMT_V2 is not set -CONFIG_QUOTACTL=y -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y -# CONFIG_DEVFS_DEBUG is not set -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS_FS=y -CONFIG_JFFS_FS_VERBOSE=0 -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_EXPORTFS is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Security options -# -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -# CONFIG_CRC32 is not set -# CONFIG_LIBCRC32C is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_PARTITIONS is not set -# CONFIG_MTD_CONCAT is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -CONFIG_MTD_BLKMTD=y - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Kernel hacking -# -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_INFO=y -CONFIG_FRAME_POINTER=y -CONFIG_PT_PROXY=y -# CONFIG_GPROF is not set -# CONFIG_GCOV is not set diff --git a/linux-uml/linux-uml-2.6.7/disable-UnitAtATime.patch b/linux-uml/linux-uml-2.6.7/disable-UnitAtATime.patch deleted file mode 100644 index d638b7f746..0000000000 --- a/linux-uml/linux-uml-2.6.7/disable-UnitAtATime.patch +++ /dev/null @@ -1,22 +0,0 @@ - -Avoid that gcc breaks UML with "unit at a time" compilation mode. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/Makefile | 2 ++ - 1 files changed, 2 insertions(+) - -diff -puN arch/um/Makefile~disable-UnitAtATime arch/um/Makefile ---- uml-linux-2.6.7/arch/um/Makefile~disable-UnitAtATime 2004-06-29 21:03:00.859506704 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Makefile 2004-06-29 21:03:00.861506400 +0200 -@@ -61,6 +61,8 @@ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSU - -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \ - -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE) - -+CFLAGS += $(call check_gcc,-fno-unit-at-a-time,) -+ - LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc - - # These are needed for clean and mrproper, since in that case .config is not -_ diff --git a/linux-uml/linux-uml-2.6.7/fix-warnings.patch b/linux-uml/linux-uml-2.6.7/fix-warnings.patch deleted file mode 100644 index 920df3fcba..0000000000 --- a/linux-uml/linux-uml-2.6.7/fix-warnings.patch +++ /dev/null @@ -1,64 +0,0 @@ - -Fixes some little warnings about "Defined but not used ..." by #ifdef'ing things - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/kernel/time.c | 1 + - uml-linux-2.6.7-paolo/arch/um/kernel/time_kern.c | 4 +++- - uml-linux-2.6.7-paolo/fs/hostfs/hostfs_kern.c | 2 ++ - 3 files changed, 6 insertions(+), 1 deletion(-) - -diff -puN arch/um/kernel/time_kern.c~fix-warnings arch/um/kernel/time_kern.c ---- uml-linux-2.6.7/arch/um/kernel/time_kern.c~fix-warnings 2004-06-29 21:03:02.266292840 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/time_kern.c 2004-06-29 21:03:02.271292080 +0200 -@@ -43,7 +43,9 @@ int timer_irq_inited = 0; - - static int first_tick; - static unsigned long long prev_tsc; -+#ifdef CONFIG_UML_REAL_TIME_CLOCK - static long long delta; /* Deviation per interval */ -+#endif - - extern unsigned long long host_hz; - -@@ -59,7 +61,7 @@ void timer_irq(union uml_pt_regs *regs) - } - - if(first_tick){ --#if defined(CONFIG_UML_REAL_TIME_CLOCK) -+#ifdef CONFIG_UML_REAL_TIME_CLOCK - unsigned long long tsc; - /* We've had 1 tick */ - tsc = time_stamp(); -diff -puN arch/um/kernel/time.c~fix-warnings arch/um/kernel/time.c ---- uml-linux-2.6.7/arch/um/kernel/time.c~fix-warnings 2004-06-29 21:03:02.267292688 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/time.c 2004-06-29 21:03:02.271292080 +0200 -@@ -10,6 +10,7 @@ - #include <sys/time.h> - #include <signal.h> - #include <errno.h> -+#include <string.h> - #include "user_util.h" - #include "kern_util.h" - #include "user.h" -diff -puN fs/hostfs/hostfs_kern.c~fix-warnings fs/hostfs/hostfs_kern.c ---- uml-linux-2.6.7/fs/hostfs/hostfs_kern.c~fix-warnings 2004-06-29 21:03:02.268292536 +0200 -+++ uml-linux-2.6.7-paolo/fs/hostfs/hostfs_kern.c 2004-06-29 21:03:02.271292080 +0200 -@@ -59,6 +59,7 @@ static struct inode_operations hostfs_io - static struct inode_operations hostfs_dir_iops; - static struct address_space_operations hostfs_link_aops; - -+#ifndef MODULE - static int __init hostfs_args(char *options, int *add) - { - char *ptr; -@@ -95,6 +96,7 @@ __uml_setup("hostfs=", hostfs_args, - " The only flag currently supported is 'append', which specifies that all\n" - " files opened by hostfs will be opened in append mode.\n\n" - ); -+#endif - - static char *dentry_name(struct dentry *dentry, int extra) - { -_ diff --git a/linux-uml/linux-uml-2.6.7/mconsole_exec.patch b/linux-uml/linux-uml-2.6.7/mconsole_exec.patch deleted file mode 100644 index fed13ab703..0000000000 --- a/linux-uml/linux-uml-2.6.7/mconsole_exec.patch +++ /dev/null @@ -1,130 +0,0 @@ - - -Adds the "exec" command to mconsole; the command is passed to /bin/sh -c, so -you know its syntax. It uses call_usermodehelper. - - ---- - - uml-linux-2.6.7-paolo/arch/um/Kconfig | 9 +++++ - uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_kern.c | 32 +++++++++++++++++- - uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_user.c | 4 ++ - uml-linux-2.6.7-paolo/arch/um/include/mconsole.h | 1 - 4 files changed, 45 insertions(+), 1 deletion(-) - -diff -puN arch/um/drivers/mconsole_kern.c~mconsole_exec arch/um/drivers/mconsole_kern.c ---- uml-linux-2.6.7/arch/um/drivers/mconsole_kern.c~mconsole_exec 2004-06-21 16:54:17.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_kern.c 2004-06-21 16:54:17.000000000 +0200 -@@ -19,6 +19,7 @@ - #include "linux/fs.h" - #include "linux/namei.h" - #include "linux/proc_fs.h" -+#include "linux/kmod.h" - #include "asm/irq.h" - #include "asm/uaccess.h" - #include "user_util.h" -@@ -118,6 +119,27 @@ void mconsole_log(struct mc_request *req - mconsole_reply(req, "", 0, 0); - } - -+ -+#ifdef CONFIG_MCONSOLE_EXEC -+void mconsole_exec(struct mc_request *req) -+{ -+ int res; -+ -+ char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; -+ char *argv[] = { "/bin/sh", "-c", req->request.data + strlen("exec "), NULL }; -+ res = call_usermodehelper("/bin/sh", argv, envp, 0); -+ -+ if (res < 0) { -+ char buf[60]; -+ snprintf(buf, 60, "call_usermodehelper failed in mconsole_exec with error code: %d", -res); -+ mconsole_reply(req, buf, 1, 0); -+ return; -+ } -+ -+ mconsole_reply(req, "The command has been started successfully.", 0, 0); -+} -+#endif -+ - void mconsole_proc(struct mc_request *req) - { - struct nameidata nd; -@@ -193,6 +215,14 @@ void mconsole_proc(struct mc_request *re - out: ; - } - -+#ifdef CONFIG_MCONSOLE_EXEC -+# define EXEC_HELPTEXT "\ -+ exec <command> - runs the specified command through /bin/sh -c\n" -+#else -+# define EXEC_HELPTEXT "" -+#endif -+ -+ /*exec - execute a command as root inside the UML\n"*/ - #define UML_MCONSOLE_HELPTEXT \ - "Commands: \n\ - version - Get kernel version \n\ -@@ -207,7 +237,7 @@ void mconsole_proc(struct mc_request *re - cad - invoke the Ctl-Alt-Del handler \n\ - stop - pause the UML; it will do nothing until it receives a 'go' \n\ - go - continue the UML after a 'stop' \n\ -- log <string> - make UML enter <string> into the kernel log\n\ -+ log <string> - make UML enter <string> into the kernel log\n" EXEC_HELPTEXT "\ - proc <file> - returns the contents of the UML's /proc/<file>\n\ - " - -diff -puN arch/um/drivers/mconsole_user.c~mconsole_exec arch/um/drivers/mconsole_user.c ---- uml-linux-2.6.7/arch/um/drivers/mconsole_user.c~mconsole_exec 2004-06-21 16:54:17.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/drivers/mconsole_user.c 2004-06-21 16:54:17.000000000 +0200 -@@ -16,6 +16,7 @@ - #include "user.h" - #include "mconsole.h" - #include "umid.h" -+#include "uml-config.h" - - static struct mconsole_command commands[] = { - { "version", mconsole_version, MCONSOLE_INTR }, -@@ -30,6 +31,9 @@ static struct mconsole_command commands[ - { "go", mconsole_go, MCONSOLE_INTR }, - { "log", mconsole_log, MCONSOLE_INTR }, - { "proc", mconsole_proc, MCONSOLE_PROC }, -+#ifdef UML_CONFIG_MCONSOLE_EXEC -+ { "exec", mconsole_exec, MCONSOLE_PROC }, -+#endif - }; - - /* Initialized in mconsole_init, which is an initcall */ -diff -puN arch/um/Kconfig~mconsole_exec arch/um/Kconfig ---- uml-linux-2.6.7/arch/um/Kconfig~mconsole_exec 2004-06-21 16:54:17.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/Kconfig 2004-06-21 16:56:00.000000000 +0200 -@@ -129,6 +129,15 @@ config MCONSOLE - - It is safe to say 'Y' here. - -+config MCONSOLE_EXEC -+ bool "Management console 'exec' support" -+ depends on MCONSOLE -+ help -+ Adds the 'exec' command to mconsole, which allows execution of arbitrary command -+ inside UML. -+ All its parameters are passed to /bin/sh -c inside UML, so you can use the full -+ shell syntax, especially redirections. -+ - config MAGIC_SYSRQ - bool "Magic SysRq key" - depends on MCONSOLE -diff -puN arch/um/include/mconsole.h~mconsole_exec arch/um/include/mconsole.h ---- uml-linux-2.6.7/arch/um/include/mconsole.h~mconsole_exec 2004-06-21 16:54:17.000000000 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/include/mconsole.h 2004-06-21 16:54:17.000000000 +0200 -@@ -80,6 +80,7 @@ extern void mconsole_cad(struct mc_reque - 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_exec(struct mc_request *req); - extern void mconsole_proc(struct mc_request *req); - - extern int mconsole_get_request(int fd, struct mc_request *req); - -_ diff --git a/linux-uml/linux-uml-2.6.7/proc_sysemu.patch b/linux-uml/linux-uml-2.6.7/proc_sysemu.patch deleted file mode 100644 index 4f17341421..0000000000 --- a/linux-uml/linux-uml-2.6.7/proc_sysemu.patch +++ /dev/null @@ -1,242 +0,0 @@ - -Adds /proc/sysemu to toggle SYSEMU usage. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/kernel/process.c | 4 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/ptrace-skas.h | 4 - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c | 62 ++++------ - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c | 59 +++++++++ - 4 files changed, 93 insertions(+), 36 deletions(-) - -diff -puN arch/um/kernel/process.c~proc_sysemu arch/um/kernel/process.c ---- uml-linux-2.6.7/arch/um/kernel/process.c~proc_sysemu 2004-06-29 21:03:04.416965888 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/process.c 2004-06-29 21:03:04.422964976 +0200 -@@ -246,7 +246,7 @@ void __init check_ptrace(void) - printk("OK\n"); - - printk("Checking syscall emulation patch for ptrace..."); -- use_sysemu = 0; -+ set_using_sysemu(0); - pid = start_ptraced_child(&stack); - if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { - struct user_regs_struct regs; -@@ -269,7 +269,7 @@ void __init check_ptrace(void) - - if (!force_sysemu_disabled) { - printk("found\n"); -- use_sysemu = 1; -+ set_using_sysemu(1); - } else { - printk("found but disabled\n"); - } -diff -puN arch/um/kernel/skas/include/ptrace-skas.h~proc_sysemu arch/um/kernel/skas/include/ptrace-skas.h ---- uml-linux-2.6.7/arch/um/kernel/skas/include/ptrace-skas.h~proc_sysemu 2004-06-29 21:03:04.417965736 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/ptrace-skas.h 2004-06-29 21:03:04.422964976 +0200 -@@ -15,7 +15,9 @@ - #ifndef PTRACE_SYSEMU - #define PTRACE_SYSEMU 31 - #endif --extern int use_sysemu; -+ -+void set_using_sysemu(int value); -+int get_using_sysemu(void); - - #include "skas_ptregs.h" - -diff -puN arch/um/kernel/skas/process.c~proc_sysemu arch/um/kernel/skas/process.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process.c~proc_sysemu 2004-06-29 21:03:04.418965584 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c 2004-06-29 21:03:04.423964824 +0200 -@@ -28,10 +28,6 @@ - #include "chan_user.h" - #include "signal_user.h" - --#ifdef PTRACE_SYSEMU --int use_sysemu = 0; --#endif -- - int is_skas_winch(int pid, int fd, void *data) - { - if(pid != getpid()) -@@ -61,7 +57,8 @@ static void handle_segv(int pid) - segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); - } - --static void handle_trap(int pid, union uml_pt_regs *regs) -+/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ -+static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu) - { - int err, syscall_nr, status; - -@@ -72,27 +69,23 @@ static void handle_trap(int pid, union u - return; - } - --#ifdef PTRACE_SYSEMU -- if (!use_sysemu) -+ if (!local_using_sysemu) - { --#endif -- err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); -- if(err < 0) -- panic("handle_trap - nullifying syscall failed errno = %d\n", -- errno); -+ err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); -+ if(err < 0) -+ panic("handle_trap - nullifying syscall failed errno = %d\n", -+ errno); -+ -+ err = ptrace(PTRACE_SYSCALL, pid, 0, 0); -+ if(err < 0) -+ panic("handle_trap - continuing to end of syscall failed, " -+ "errno = %d\n", errno); - -- err = ptrace(PTRACE_SYSCALL, pid, 0, 0); -- if(err < 0) -- panic("handle_trap - continuing to end of syscall failed, " -- "errno = %d\n", errno); -- -- err = waitpid(pid, &status, WUNTRACED); -- if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) -- panic("handle_trap - failed to wait at end of syscall, " -- "errno = %d, status = %d\n", errno, status); --#ifdef PTRACE_SYSEMU -+ err = waitpid(pid, &status, WUNTRACED); -+ if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) -+ panic("handle_trap - failed to wait at end of syscall, " -+ "errno = %d, status = %d\n", errno, status); - } --#endif - - handle_syscall(regs); - } -@@ -147,15 +140,16 @@ void start_userspace(int cpu) - void userspace(union uml_pt_regs *regs) - { - int err, status, op, pid = userspace_pid[0]; -+ int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ - - restore_registers(regs); - --#ifdef PTRACE_SYSEMU -- if (use_sysemu) -+ local_using_sysemu = get_using_sysemu(); -+ -+ if (local_using_sysemu) - err = ptrace(PTRACE_SYSEMU, pid, 0, 0); - else --#endif -- err = ptrace(PTRACE_SYSCALL, pid, 0, 0); -+ err = ptrace(PTRACE_SYSCALL, pid, 0, 0); - if(err) - panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", - errno); -@@ -174,7 +168,7 @@ void userspace(union uml_pt_regs *regs) - handle_segv(pid); - break; - case SIGTRAP: -- handle_trap(pid, regs); -+ handle_trap(pid, regs, local_using_sysemu); - break; - case SIGIO: - case SIGVTALRM: -@@ -193,14 +187,16 @@ void userspace(union uml_pt_regs *regs) - - restore_registers(regs); - --#ifdef PTRACE_SYSEMU -- if (use_sysemu) -+ /*Now we ended the syscall, so re-read local_using_sysemu.*/ -+ local_using_sysemu = get_using_sysemu(); -+ -+ if (local_using_sysemu) - op = singlestepping_skas() ? PTRACE_SINGLESTEP : - PTRACE_SYSEMU; - else --#endif -- op = singlestepping_skas() ? PTRACE_SINGLESTEP : -- PTRACE_SYSCALL; -+ op = singlestepping_skas() ? PTRACE_SINGLESTEP : -+ PTRACE_SYSCALL; -+ - err = ptrace(op, pid, 0, 0); - if(err) - panic("userspace - PTRACE_SYSCALL failed, " -diff -puN arch/um/kernel/skas/process_kern.c~proc_sysemu arch/um/kernel/skas/process_kern.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process_kern.c~proc_sysemu 2004-06-29 21:03:04.419965432 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c 2004-06-29 21:03:04.423964824 +0200 -@@ -6,6 +6,12 @@ - #include "linux/sched.h" - #include "linux/slab.h" - #include "linux/ptrace.h" -+#include "linux/proc_fs.h" -+#include "linux/file.h" -+#include "linux/errno.h" -+#include "linux/init.h" -+#include "asm/uaccess.h" -+#include "asm/atomic.h" - #include "kern_util.h" - #include "time_user.h" - #include "signal_user.h" -@@ -17,6 +23,59 @@ - #include "kern.h" - #include "mode.h" - -+#ifdef PTRACE_SYSEMU -+static atomic_t using_sysemu; -+#endif -+ -+void set_using_sysemu(int value) -+{ -+ atomic_set(&using_sysemu, value); -+} -+ -+int get_using_sysemu(void) -+{ -+ return atomic_read(&using_sysemu); -+} -+ -+int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) -+{ -+ if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ -+ *eof = 1; -+ -+ return strlen(buf); -+} -+ -+int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data) -+{ -+ char tmp[2]; -+ -+ if (copy_from_user(tmp, buf, 1)) -+ return -EFAULT; -+ -+ if (tmp[0] == '0' || tmp[0] == '1') -+ set_using_sysemu(tmp[0] - '0'); -+ return count; /*We use the first char, but pretend to write everything*/ -+} -+ -+int __init make_proc_sysemu(void) -+{ -+ struct proc_dir_entry *ent; -+ -+ ent = create_proc_entry("sysemu", 00600, &proc_root); -+ ent->read_proc = proc_read_sysemu; -+ ent->write_proc = proc_write_sysemu; -+ -+ if (ent == NULL) -+ { -+ printk("Failed to register /proc/sysemu\n"); -+ return(0); -+ } -+ -+ return 0; -+} -+ -+late_initcall(make_proc_sysemu); -+ - int singlestepping_skas(void) - { - int ret = current->ptrace & PT_DTRACE; -_ diff --git a/linux-uml/linux-uml-2.6.7/silly_panic.patch b/linux-uml/linux-uml-2.6.7/silly_panic.patch deleted file mode 100644 index 38d3516691..0000000000 --- a/linux-uml/linux-uml-2.6.7/silly_panic.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- - - uml-linux-2.6.7-paolo/arch/um/kernel/trap_kern.c | 6 ++++-- - 1 files changed, 4 insertions(+), 2 deletions(-) - -diff -puN arch/um/kernel/trap_kern.c~silly_panic arch/um/kernel/trap_kern.c ---- uml-linux-2.6.7/arch/um/kernel/trap_kern.c~silly_panic 2004-06-28 21:42:06.025387464 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/trap_kern.c 2004-06-28 21:43:47.676934080 +0200 -@@ -54,8 +54,10 @@ int handle_page_fault(unsigned long addr - if(is_write && !(vma->vm_flags & VM_WRITE)) - goto out; - page = address & PAGE_MASK; -- if(page == (unsigned long) current_thread + PAGE_SIZE) -- panic("Kernel stack overflow"); -+ if (mode_tt) { -+ if(page == (unsigned long) current_thread + PAGE_SIZE) -+ panic("Kernel stack overflow"); -+ } - pgd = pgd_offset(mm, page); - pmd = pmd_offset(pgd, page); - do { -_ diff --git a/linux-uml/linux-uml-2.6.7/sysemu_cmdParam.patch b/linux-uml/linux-uml-2.6.7/sysemu_cmdParam.patch deleted file mode 100644 index 2422867a17..0000000000 --- a/linux-uml/linux-uml-2.6.7/sysemu_cmdParam.patch +++ /dev/null @@ -1,67 +0,0 @@ - -Adds the "nosysemu" command line parameter to disable SYSEMU - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/kernel/process.c | 26 +++++++++++++++++++++---- - 1 files changed, 22 insertions(+), 4 deletions(-) - -diff -puN arch/um/kernel/process.c~sysemu_cmdParam arch/um/kernel/process.c ---- uml-linux-2.6.7/arch/um/kernel/process.c~sysemu_cmdParam 2004-06-29 21:03:04.131009360 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/process.c 2004-06-29 21:03:04.134008904 +0200 -@@ -196,6 +196,22 @@ static void stop_ptraced_child(int pid, - panic("check_ptrace : munmap failed, errno = %d", errno); - } - -+static int force_sysemu_disabled = 0; -+ -+static int __init nosysemu_cmd_param(char *str, int* add) -+{ -+ force_sysemu_disabled = 1; -+ return 0; -+} -+ -+__uml_setup("nosysemu", nosysemu_cmd_param, -+ "nosysemu\n" -+ " Turns off syscall emulation patch for ptrace (SYSEMU) on.\n" -+ " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n" -+ " behaviour of ptrace() and helps reducing host context switch rate.\n" -+ " To make it working, you need a kernel patch for your host, too.\n" -+ " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information.\n"); -+ - void __init check_ptrace(void) - { - void *stack; -@@ -229,7 +245,6 @@ void __init check_ptrace(void) - stop_ptraced_child(pid, stack, 0); - printk("OK\n"); - --#ifdef PTRACE_SYSEMU - printk("Checking syscall emulation patch for ptrace..."); - use_sysemu = 0; - pid = start_ptraced_child(&stack); -@@ -252,8 +267,12 @@ void __init check_ptrace(void) - - stop_ptraced_child(pid, stack, 0); - -- printk("OK\n"); -- use_sysemu = 1; -+ if (!force_sysemu_disabled) { -+ printk("found\n"); -+ use_sysemu = 1; -+ } else { -+ printk("found but disabled\n"); -+ } - } - else - { -@@ -261,7 +280,6 @@ void __init check_ptrace(void) - stop_ptraced_child(pid, stack, 1); - } - --# endif /* PTRACE_SYSEMU */ - } - - int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) -_ diff --git a/linux-uml/linux-uml-2.6.7/um-sysemu.patch b/linux-uml/linux-uml-2.6.7/um-sysemu.patch deleted file mode 100644 index c97dff2415..0000000000 --- a/linux-uml/linux-uml-2.6.7/um-sysemu.patch +++ /dev/null @@ -1,145 +0,0 @@ - -Turns off syscall emulation patch for ptrace (SYSEMU) on. -SYSEMU is a performance-patch introduced by Laurent Vivier. It changes -behaviour of ptrace() and helps reducing host context switch rate. -To make it working, you need a kernel patch for your host, too. -See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information. - -Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> ---- - - uml-linux-2.6.7-paolo/arch/um/kernel/process.c | 35 ++++++++++ - uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/ptrace-skas.h | 7 ++ - uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c | 22 ++++++ - 3 files changed, 64 insertions(+) - -diff -puN arch/um/kernel/process.c~um-sysemu arch/um/kernel/process.c ---- uml-linux-2.6.7/arch/um/kernel/process.c~um-sysemu 2004-06-29 21:03:03.801059520 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/process.c 2004-06-29 21:03:03.806058760 +0200 -@@ -19,6 +19,7 @@ - #include <asm/sigcontext.h> - #include <asm/unistd.h> - #include <asm/page.h> -+#include <asm/user.h> - #include "user_util.h" - #include "kern_util.h" - #include "user.h" -@@ -227,6 +228,40 @@ void __init check_ptrace(void) - } - stop_ptraced_child(pid, stack, 0); - printk("OK\n"); -+ -+#ifdef PTRACE_SYSEMU -+ printk("Checking syscall emulation patch for ptrace..."); -+ use_sysemu = 0; -+ pid = start_ptraced_child(&stack); -+ if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { -+ struct user_regs_struct regs; -+ -+ if (waitpid(pid, &status, WUNTRACED) < 0) -+ panic("check_ptrace : wait failed, errno = %d", errno); -+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) -+ panic("check_ptrace : expected SIGTRAP, " -+ "got status = %d", status); -+ -+ if (ptrace(PTRACE_GETREGS, pid, 0, ®s) < 0) -+ panic("check_ptrace : failed to read child " -+ "registers, errno = %d", errno); -+ regs.orig_eax = pid; -+ if (ptrace(PTRACE_SETREGS, pid, 0, ®s) < 0) -+ panic("check_ptrace : failed to modify child " -+ "registers, errno = %d", errno); -+ -+ stop_ptraced_child(pid, stack, 0); -+ -+ printk("OK\n"); -+ use_sysemu = 1; -+ } -+ else -+ { -+ printk("missing\n"); -+ stop_ptraced_child(pid, stack, 1); -+ } -+ -+# endif /* PTRACE_SYSEMU */ - } - - int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) -diff -puN arch/um/kernel/skas/include/ptrace-skas.h~um-sysemu arch/um/kernel/skas/include/ptrace-skas.h ---- uml-linux-2.6.7/arch/um/kernel/skas/include/ptrace-skas.h~um-sysemu 2004-06-29 21:03:03.802059368 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/ptrace-skas.h 2004-06-29 21:03:03.806058760 +0200 -@@ -10,6 +10,13 @@ - - #ifdef UML_CONFIG_MODE_SKAS - -+/* syscall emulation path in ptrace */ -+ -+#ifndef PTRACE_SYSEMU -+#define PTRACE_SYSEMU 31 -+#endif -+extern int use_sysemu; -+ - #include "skas_ptregs.h" - - #define HOST_FRAME_SIZE 17 -diff -puN arch/um/kernel/skas/process.c~um-sysemu arch/um/kernel/skas/process.c ---- uml-linux-2.6.7/arch/um/kernel/skas/process.c~um-sysemu 2004-06-29 21:03:03.803059216 +0200 -+++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c 2004-06-29 21:03:03.806058760 +0200 -@@ -28,6 +28,10 @@ - #include "chan_user.h" - #include "signal_user.h" - -+#ifdef PTRACE_SYSEMU -+int use_sysemu = 0; -+#endif -+ - int is_skas_winch(int pid, int fd, void *data) - { - if(pid != getpid()) -@@ -68,6 +72,10 @@ static void handle_trap(int pid, union u - return; - } - -+#ifdef PTRACE_SYSEMU -+ if (!use_sysemu) -+ { -+#endif - err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); - if(err < 0) - panic("handle_trap - nullifying syscall failed errno = %d\n", -@@ -82,6 +90,9 @@ static void handle_trap(int pid, union u - if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) - panic("handle_trap - failed to wait at end of syscall, " - "errno = %d, status = %d\n", errno, status); -+#ifdef PTRACE_SYSEMU -+ } -+#endif - - handle_syscall(regs); - } -@@ -139,6 +150,11 @@ void userspace(union uml_pt_regs *regs) - - restore_registers(regs); - -+#ifdef PTRACE_SYSEMU -+ if (use_sysemu) -+ err = ptrace(PTRACE_SYSEMU, pid, 0, 0); -+ else -+#endif - err = ptrace(PTRACE_SYSCALL, pid, 0, 0); - if(err) - panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", -@@ -177,6 +193,12 @@ void userspace(union uml_pt_regs *regs) - - restore_registers(regs); - -+#ifdef PTRACE_SYSEMU -+ if (use_sysemu) -+ op = singlestepping_skas() ? PTRACE_SINGLESTEP : -+ PTRACE_SYSEMU; -+ else -+#endif - op = singlestepping_skas() ? PTRACE_SINGLESTEP : - PTRACE_SYSCALL; - err = ptrace(op, pid, 0, 0); -_ |