Module Name: src Committed By: jmcneill Date: Sat Sep 3 12:28:46 UTC 2011
Modified Files: src/sys/arch/usermode/conf: Makefile.usermode files.usermode std.usermode src/sys/arch/usermode/usermode: pmap.c Added Files: src/sys/arch/usermode/include: urkelvisor.h src/sys/arch/usermode/usermode: urkelvisor.c Log Message: Add usermode kernel supervisor, can be disabled with 'no options URKELVISOR' To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/sys/arch/usermode/conf/Makefile.usermode cvs rdiff -u -r1.7 -r1.8 src/sys/arch/usermode/conf/files.usermode cvs rdiff -u -r1.5 -r1.6 src/sys/arch/usermode/conf/std.usermode cvs rdiff -u -r0 -r1.1 src/sys/arch/usermode/include/urkelvisor.h cvs rdiff -u -r1.50 -r1.51 src/sys/arch/usermode/usermode/pmap.c cvs rdiff -u -r0 -r1.1 src/sys/arch/usermode/usermode/urkelvisor.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/usermode/conf/Makefile.usermode diff -u src/sys/arch/usermode/conf/Makefile.usermode:1.15 src/sys/arch/usermode/conf/Makefile.usermode:1.16 --- src/sys/arch/usermode/conf/Makefile.usermode:1.15 Sun Aug 28 23:16:18 2011 +++ src/sys/arch/usermode/conf/Makefile.usermode Sat Sep 3 12:28:45 2011 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.usermode,v 1.15 2011/08/28 23:16:18 jmcneill Exp $ +# $NetBSD: Makefile.usermode,v 1.16 2011/09/03 12:28:45 jmcneill Exp $ MACHINE_ARCH= usermode USETOOLS?= no @@ -23,6 +23,8 @@ CPPFLAGS.init_main.c+= -Dmain=kernmain OPT_SDL= %SDL% +OPT_URKELVISOR= %URKELVISOR% + .if !empty(OPT_SDL) SDL_CFLAGS!= sdl-config --cflags SDL_LIBS!= sdl-config --libs @@ -31,6 +33,7 @@ CPPFLAGS.thunk.c+= ${USERMODE_CPPFLAGS} CPPFLAGS.thunk_sdl.c+= ${SDL_CFLAGS} ${USERMODE_CPPFLAGS} +CPPFLAGS.urkelvisor.c+= ${USERMODE_CPPFLAGS} ## ## (3) libkern and compat @@ -43,11 +46,17 @@ ## MD_OBJS= thunk.o MD_CFILES= ${USERMODE}/usermode/thunk.c +MD_SFILES= + +.if !empty(OPT_URKELVISOR) +MD_OBJS+= urkelvisor.o +MD_CFILES+= ${USERMODE}/usermode/urkelvisor.c +.endif + .if !empty(OPT_SDL) MD_OBJS+= thunk_sdl.o MD_CFILES+= ${USERMODE}/usermode/thunk_sdl.c .endif -MD_SFILES= ## ## (5) link settings @@ -82,6 +91,13 @@ thunk_sdl.o: ${USERMODE}/usermode/thunk_sdl.c ${CC} ${CPPFLAGS.thunk_sdl.c} -c -o $@ ${USERMODE}/usermode/thunk_sdl.c +urkelvisor.d: ${USERMODE}/usermode/urkelvisor.c + ${MKDEP} -f ${.TARGET} -- ${MKDEP_CFLAGS} \ + ${CPPFLAGS.urkelvisor.c} ${USERMODE}/usermode/urkelvisor.c + +urkelvisor.o: ${USERMODE}/usermode/urkelvisor.c + ${CC} ${CPPFLAGS.urkelvisor.c} -c -o $@ ${USERMODE}/usermode/urkelvisor.c + ## ## (7) misc settings ## Index: src/sys/arch/usermode/conf/files.usermode diff -u src/sys/arch/usermode/conf/files.usermode:1.7 src/sys/arch/usermode/conf/files.usermode:1.8 --- src/sys/arch/usermode/conf/files.usermode:1.7 Sat Aug 27 21:43:06 2011 +++ src/sys/arch/usermode/conf/files.usermode Sat Sep 3 12:28:45 2011 @@ -1,4 +1,4 @@ -# $NetBSD: files.usermode,v 1.7 2011/08/27 21:43:06 jmcneill Exp $ +# $NetBSD: files.usermode,v 1.8 2011/09/03 12:28:45 jmcneill Exp $ maxpartitions 8 maxusers 8 16 64 @@ -6,6 +6,7 @@ defparam opt_memsize.h MEMSIZE defflag opt_sdl.h SDL defflag opt_cpu.h CPU_DEBUG +defflag opt_urkelvisor.h URKELVISOR define thunkbus { } Index: src/sys/arch/usermode/conf/std.usermode diff -u src/sys/arch/usermode/conf/std.usermode:1.5 src/sys/arch/usermode/conf/std.usermode:1.6 --- src/sys/arch/usermode/conf/std.usermode:1.5 Mon Aug 22 15:26:55 2011 +++ src/sys/arch/usermode/conf/std.usermode Sat Sep 3 12:28:45 2011 @@ -1,4 +1,4 @@ -# $NetBSD: std.usermode,v 1.5 2011/08/22 15:26:55 reinoud Exp $ +# $NetBSD: std.usermode,v 1.6 2011/09/03 12:28:45 jmcneill Exp $ machine usermode include "conf/std" @@ -8,6 +8,8 @@ options EXEC_ELF64 options EXEC_SCRIPT +options URKELVISOR + # Defaults options NKMEMPAGES=2048 #options NKMEMPAGES_MAX_DEFAULT=2048 Index: src/sys/arch/usermode/usermode/pmap.c diff -u src/sys/arch/usermode/usermode/pmap.c:1.50 src/sys/arch/usermode/usermode/pmap.c:1.51 --- src/sys/arch/usermode/usermode/pmap.c:1.50 Thu Sep 1 16:23:55 2011 +++ src/sys/arch/usermode/usermode/pmap.c Sat Sep 3 12:28:46 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.50 2011/09/01 16:23:55 reinoud Exp $ */ +/* $NetBSD: pmap.c,v 1.51 2011/09/03 12:28:46 jmcneill Exp $ */ /*- * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org> @@ -27,10 +27,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.50 2011/09/01 16:23:55 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.51 2011/09/03 12:28:46 jmcneill Exp $"); #include "opt_memsize.h" #include "opt_kmempages.h" +#include "opt_urkelvisor.h" #include <sys/types.h> #include <sys/param.h> @@ -40,6 +41,10 @@ #include <sys/pool.h> #include <machine/thunk.h> +#ifdef URKELVISOR +#include <machine/urkelvisor.h> +#endif + #include <uvm/uvm.h> struct pv_entry { @@ -299,6 +304,10 @@ (uint64_t) (free_end - (free_start + fpos))/1024/1024); aprint_debug("\t%"PRIu64" MB of kmem left\n", (uint64_t) (kmem_ext_end - kmem_ext_cur_end)/1024/1024); + +#ifdef URKELVISOR + urkelvisor_init(); +#endif } void Added files: Index: src/sys/arch/usermode/include/urkelvisor.h diff -u /dev/null src/sys/arch/usermode/include/urkelvisor.h:1.1 --- /dev/null Sat Sep 3 12:28:46 2011 +++ src/sys/arch/usermode/include/urkelvisor.h Sat Sep 3 12:28:45 2011 @@ -0,0 +1,34 @@ +/* $NetBSD: urkelvisor.h,v 1.1 2011/09/03 12:28:45 jmcneill Exp $ */ + +/*- + * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARCH_USERMODE_INCLUDE_URKELVISOR_H +#define _ARCH_USERMODE_INCLUDE_URKELVISOR_H + +void urkelvisor_init(void); + +#endif /* !_ARCH_USERMODE_INCLUDE_URKELVISOR_H */ Index: src/sys/arch/usermode/usermode/urkelvisor.c diff -u /dev/null src/sys/arch/usermode/usermode/urkelvisor.c:1.1 --- /dev/null Sat Sep 3 12:28:46 2011 +++ src/sys/arch/usermode/usermode/urkelvisor.c Sat Sep 3 12:28:46 2011 @@ -0,0 +1,163 @@ +/* $NetBSD: urkelvisor.c,v 1.1 2011/09/03 12:28:46 jmcneill Exp $ */ + +/*- + * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Usermode kernel supervisor + */ + +#include <sys/cdefs.h> +#ifdef __NetBSD__ +__RCSID("$NetBSD: urkelvisor.c,v 1.1 2011/09/03 12:28:46 jmcneill Exp $"); +#endif + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/ptrace.h> +#include <sys/wait.h> +#include <machine/reg.h> + +#include <err.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include "../include/urkelvisor.h" + +extern vaddr_t kmem_user_start, kmem_user_end; /* usermode/pmap.c */ + +#if defined(__i386__) +#define R_SYSCALL(_regs) ((_regs)->r_eax) +#define R_PC(_regs) ((_regs)->r_eip) +#elif defined(__x86_64__) +#define R_SYSCALL(_regs) ((_regs)->regs[_REG_RAX]) +#define R_PC(_regs) ((_regs)->regs[_REG_RIP]) +#else +#error port me +#endif + +static int +wait_urkel(pid_t urkel_pid) +{ + pid_t pid; + int status; + + pid = waitpid(urkel_pid, &status, 0); + if (pid == -1) + err(EXIT_FAILURE, "waitpid failed"); + + if (WIFEXITED(status)) + exit(WEXITSTATUS(status)); + + return status; +} + +static int +handle_syscall(pid_t urkel_pid) +{ + struct reg uregs; + int sig = 0; + + errno = 0; + ptrace(PT_GETREGS, urkel_pid, &uregs, 0); + if (errno) + err(EXIT_FAILURE, "ptrace(PT_GETREGS, %d, &uregs, 0) failed", + urkel_pid); + + if (R_PC(&uregs) >= kmem_user_start && R_PC(&uregs) < kmem_user_end) { + fprintf(stderr, "caught syscall %d\n", R_SYSCALL(&uregs)); + errno = 0; + ptrace(PT_SYSCALLEMU, urkel_pid, NULL, 0); + if (errno) + err(EXIT_FAILURE, + "ptrace(PT_SYSCALLEMU, %d, NULL, 0) failed", + urkel_pid); + sig = SIGILL; + } + + return sig; +} + +static int +urkelvisor(pid_t urkel_pid) +{ + int status, insyscall, sig; + + insyscall = 0; + sig = 0; + + status = wait_urkel(urkel_pid); + + for (;;) { + errno = 0; + //fprintf(stderr, "sig = %d\n", sig); + ptrace(PT_SYSCALL, urkel_pid, (void *)1, sig); + if (errno) + err(EXIT_FAILURE, "ptrace(PT_SYSCALL, %d, 1, %d) failed", + urkel_pid, sig); + sig = 0; + status = wait_urkel(urkel_pid); + + //fprintf(stderr, "syscall insyscall=%d status=%x\n", + // insyscall, status); + if (WSTOPSIG(status) == SIGTRAP) { + insyscall = !insyscall; + if (insyscall) { + sig = handle_syscall(urkel_pid); + } + } else { + sig = WSTOPSIG(status); + } + } +} + +void +urkelvisor_init(void) +{ + pid_t child_pid; + int status; + + child_pid = fork(); + switch (child_pid) { + case -1: + err(EXIT_FAILURE, "fork() failed"); + /* NOTREACHED */ + case 0: + errno = 0; + ptrace(PT_TRACE_ME, 0, NULL, 0); + if (errno) + err(EXIT_FAILURE, + "ptrace(PT_TRACE_ME, 0, NULL, 0) failed"); + wait(&status); + break; + default: + status = urkelvisor(child_pid); + exit(status); + } +} +