Module Name: src Committed By: pooka Date: Mon Dec 16 15:36:30 UTC 2013
Modified Files: src/sys/rump/kern/lib/libsys_linux: component.c src/sys/rump/librump/rumpkern: emul.c lwproc.c rump.c Log Message: Translate return values for emulations, e.g. Linux. For ports without __HAVE_MINIMAL_EMUL, we simply look up the values from p->p_emul->e_errno. For ports which cannot afford to keep an extra pointer per emul structure around, we hope there is __HAVE_SYSCALL_INTERN support and thread the errno values through p_emuldata. Notably, we cannot alter the syscall method like most ports do with syscall_intern, since they do it via p_mdproc, so MI code is not possible there. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/rump/kern/lib/libsys_linux/component.c cvs rdiff -u -r1.159 -r1.160 src/sys/rump/librump/rumpkern/emul.c cvs rdiff -u -r1.25 -r1.26 src/sys/rump/librump/rumpkern/lwproc.c cvs rdiff -u -r1.280 -r1.281 src/sys/rump/librump/rumpkern/rump.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/rump/kern/lib/libsys_linux/component.c diff -u src/sys/rump/kern/lib/libsys_linux/component.c:1.8 src/sys/rump/kern/lib/libsys_linux/component.c:1.9 --- src/sys/rump/kern/lib/libsys_linux/component.c:1.8 Wed Apr 3 23:51:20 2013 +++ src/sys/rump/kern/lib/libsys_linux/component.c Mon Dec 16 15:36:30 2013 @@ -1,8 +1,10 @@ -/* $NetBSD: component.c,v 1.8 2013/04/03 23:51:20 pooka Exp $ */ +/* $NetBSD: component.c,v 1.9 2013/12/16 15:36:30 pooka Exp $ */ #include <sys/param.h> #include <sys/proc.h> +#include <compat/linux/common/linux_errno.h> + #include <uvm/uvm_extern.h> #include "rump_private.h" @@ -11,15 +13,25 @@ extern struct sysent rump_linux_sysent[]; +#ifdef __HAVE_SYSCALL_INTERN +static void +rumplinux_syscall_intern(struct proc *p) +{ + + p->p_emuldata = __UNCONST(native_to_linux_errno); +} +#endif + struct emul emul_rump_sys_linux = { .e_name = "linux-rump", .e_sysent = rump_linux_sysent, #ifndef __HAVE_MINIMAL_EMUL .e_nsysent = RUMP_LINUX_SYS_NSYSENT, + .e_errno = native_to_linux_errno; #endif .e_vm_default_addr = uvm_default_mapaddr, #ifdef __HAVE_SYSCALL_INTERN - .e_syscall_intern = syscall_intern, + .e_syscall_intern = rumplinux_syscall_intern, #endif }; Index: src/sys/rump/librump/rumpkern/emul.c diff -u src/sys/rump/librump/rumpkern/emul.c:1.159 src/sys/rump/librump/rumpkern/emul.c:1.160 --- src/sys/rump/librump/rumpkern/emul.c:1.159 Mon Dec 9 16:54:20 2013 +++ src/sys/rump/librump/rumpkern/emul.c Mon Dec 16 15:36:29 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: emul.c,v 1.159 2013/12/09 16:54:20 pooka Exp $ */ +/* $NetBSD: emul.c,v 1.160 2013/12/16 15:36:29 pooka Exp $ */ /* * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.159 2013/12/09 16:54:20 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.160 2013/12/16 15:36:29 pooka Exp $"); #include <sys/param.h> #include <sys/null.h> @@ -277,7 +277,7 @@ void syscall_intern(struct proc *p) { - /* no you don't */ + p->p_emuldata = NULL; } #endif Index: src/sys/rump/librump/rumpkern/lwproc.c diff -u src/sys/rump/librump/rumpkern/lwproc.c:1.25 src/sys/rump/librump/rumpkern/lwproc.c:1.26 --- src/sys/rump/librump/rumpkern/lwproc.c:1.25 Mon Dec 9 16:21:15 2013 +++ src/sys/rump/librump/rumpkern/lwproc.c Mon Dec 16 15:36:29 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: lwproc.c,v 1.25 2013/12/09 16:21:15 pooka Exp $ */ +/* $NetBSD: lwproc.c,v 1.26 2013/12/16 15:36:29 pooka Exp $ */ /* * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.25 2013/12/09 16:21:15 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.26 2013/12/16 15:36:29 pooka Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -137,6 +137,9 @@ lwproc_newproc(struct proc *parent, int p->p_vmspace = vmspace_kernel(); p->p_emul = emul_default; +#ifdef __HAVE_SYSCALL_INTERN + p->p_emul->e_syscall_intern(p); +#endif if (*parent->p_comm) strcpy(p->p_comm, parent->p_comm); else Index: src/sys/rump/librump/rumpkern/rump.c diff -u src/sys/rump/librump/rumpkern/rump.c:1.280 src/sys/rump/librump/rumpkern/rump.c:1.281 --- src/sys/rump/librump/rumpkern/rump.c:1.280 Mon Dec 9 17:57:11 2013 +++ src/sys/rump/librump/rumpkern/rump.c Mon Dec 16 15:36:30 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rump.c,v 1.280 2013/12/09 17:57:11 pooka Exp $ */ +/* $NetBSD: rump.c,v 1.281 2013/12/16 15:36:30 pooka Exp $ */ /* * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.280 2013/12/09 17:57:11 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.281 2013/12/16 15:36:30 pooka Exp $"); #include <sys/systm.h> #define ELFSIZE ARCH_ELFSIZE @@ -837,6 +837,7 @@ rump_hyp_syscall(int num, void *arg, lon if (__predict_false(num >= SYS_NSYSENT)) return ENOSYS; + /* XXX: always uses native syscall vector */ callp = rump_sysent + num; l = curlwp; rv = sy_invoke(callp, l, (void *)arg, regrv, num); @@ -1016,6 +1017,7 @@ rump_syscall(int num, void *data, size_t struct proc *p; struct emul *e; struct sysent *callp; + const int *etrans = NULL; int rv; rump_schedule(); @@ -1027,6 +1029,30 @@ rump_syscall(int num, void *data, size_t callp = e->e_sysent + num; rv = sy_invoke(callp, curlwp, data, retval, num); + + /* + * I hope that (!__HAVE_MINIMAL_EMUL || __HAVE_SYSCALL_INTERN) is + * an invariant ... + */ +#if !defined(__HAVE_MINIMAL_EMUL) + etrans = e->e_errno; +#elif defined(__HAVE_SYSCALL_INTERN) + etrans = p->p_emuldata; +#endif + + if (etrans) { + rv = etrans[rv]; + /* + * XXX: small hack since Linux etrans vectors on some + * archs contain negative errnos, but rump_syscalls + * uses the -1 + errno ABI. Note that these + * negative values are always the result of translation, + * otherwise the above translation method would not + * work very well. + */ + if (rv < 0) + rv = -rv; + } rump_unschedule(); return rv;