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;

Reply via email to