Module Name:    src
Committed By:   pooka
Date:           Thu Nov 25 17:59:03 UTC 2010

Modified Files:
        src/lib/librumpclient: rumpclient.c
        src/lib/librumpuser: rumpuser_sp.c sp_common.c
        src/sys/rump/include/rump: rumpuser.h
        src/sys/rump/librump/rumpkern: rumpcopy.c

Log Message:
*facepalm*, adjust remote copyinstr to work in cases where the end
of the max copyin extends to an unmapped page.

Noticed, as usual, by tests.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/lib/librumpclient/rumpclient.c
cvs rdiff -u -r1.14 -r1.15 src/lib/librumpuser/rumpuser_sp.c
cvs rdiff -u -r1.9 -r1.10 src/lib/librumpuser/sp_common.c
cvs rdiff -u -r1.52 -r1.53 src/sys/rump/include/rump/rumpuser.h
cvs rdiff -u -r1.12 -r1.13 src/sys/rump/librump/rumpkern/rumpcopy.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumpclient/rumpclient.c
diff -u src/lib/librumpclient/rumpclient.c:1.4 src/lib/librumpclient/rumpclient.c:1.5
--- src/lib/librumpclient/rumpclient.c:1.4	Wed Nov 24 17:03:39 2010
+++ src/lib/librumpclient/rumpclient.c	Thu Nov 25 17:59:03 2010
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpclient.c,v 1.4 2010/11/24 17:03:39 pooka Exp $	*/
+/*      $NetBSD: rumpclient.c,v 1.5 2010/11/25 17:59:03 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -32,7 +32,7 @@
 #include <sys/cdefs.h>
 __RCSID("$NetBSD");
 
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/mman.h>
 #include <sys/socket.h>
 
@@ -84,11 +84,15 @@
 }
 
 static int
-send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen)
+send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen,
+	int wantstr)
 {
 	struct rsp_hdr rhdr;
 	int rv;
 
+	if (wantstr)
+		dlen = MIN(dlen, strlen(data)+1);
+
 	rhdr.rsp_len = sizeof(rhdr) + dlen;
 	rhdr.rsp_reqno = reqno;
 	rhdr.rsp_class = RUMPSP_RESP;
@@ -155,17 +159,21 @@
 	struct rsp_copydata *copydata;
 	void *mapaddr;
 	size_t maplen;
+	int reqtype = spc->spc_hdr.rsp_type;
 
-	switch (spc->spc_hdr.rsp_type) {
+	switch (reqtype) {
 	case RUMPSP_COPYIN:
+	case RUMPSP_COPYINSTR:
 		/*LINTED*/
 		copydata = (struct rsp_copydata *)spc->spc_buf;
 		DPRINTF(("rump_sp handlereq: copyin request: %p/%zu\n",
 		    copydata->rcp_addr, copydata->rcp_len));
 		send_copyin_resp(spc, spc->spc_hdr.rsp_reqno,
-		    copydata->rcp_addr, copydata->rcp_len);
+		    copydata->rcp_addr, copydata->rcp_len,
+		    reqtype == RUMPSP_COPYINSTR);
 		break;
 	case RUMPSP_COPYOUT:
+	case RUMPSP_COPYOUTSTR:
 		/*LINTED*/
 		copydata = (struct rsp_copydata *)spc->spc_buf;
 		DPRINTF(("rump_sp handlereq: copyout request: %p/%zu\n",

Index: src/lib/librumpuser/rumpuser_sp.c
diff -u src/lib/librumpuser/rumpuser_sp.c:1.14 src/lib/librumpuser/rumpuser_sp.c:1.15
--- src/lib/librumpuser/rumpuser_sp.c:1.14	Wed Nov 24 20:29:13 2010
+++ src/lib/librumpuser/rumpuser_sp.c	Thu Nov 25 17:59:02 2010
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpuser_sp.c,v 1.14 2010/11/24 20:29:13 pooka Exp $	*/
+/*      $NetBSD: rumpuser_sp.c,v 1.15 2010/11/25 17:59:02 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_sp.c,v 1.14 2010/11/24 20:29:13 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.15 2010/11/25 17:59:02 pooka Exp $");
 
 #include <sys/types.h>
 #include <sys/atomic.h>
@@ -194,22 +194,26 @@
 }
 
 static int
-copyin_req(struct spclient *spc, const void *remaddr, size_t dlen, void **resp)
+copyin_req(struct spclient *spc, const void *remaddr, size_t *dlen,
+	int wantstr, void **resp)
 {
 	struct rsp_hdr rhdr;
 	struct rsp_copydata copydata;
 	struct respwait rw;
 	int rv;
 
-	DPRINTF(("copyin_req: %zu bytes from %p\n", dlen, remaddr));
+	DPRINTF(("copyin_req: %zu bytes from %p\n", *dlen, remaddr));
 
 	rhdr.rsp_len = sizeof(rhdr) + sizeof(copydata);
 	rhdr.rsp_class = RUMPSP_REQ;
-	rhdr.rsp_type = RUMPSP_COPYIN;
+	if (wantstr)
+		rhdr.rsp_type = RUMPSP_COPYINSTR;
+	else
+		rhdr.rsp_type = RUMPSP_COPYIN;
 	rhdr.rsp_sysnum = 0;
 
 	copydata.rcp_addr = __UNCONST(remaddr);
-	copydata.rcp_len = dlen;
+	copydata.rcp_len = *dlen;
 
 	putwait(spc, &rw, &rhdr);
 	rv = dosend(spc, &rhdr, sizeof(rhdr));
@@ -224,6 +228,9 @@
 	DPRINTF(("copyin: response %d\n", rv));
 
 	*resp = rw.rw_data;
+	if (wantstr)
+		*dlen = rw.rw_dlen;
+
 	return rv;
 
 }
@@ -439,8 +446,8 @@
 	return NULL;
 }
 
-int
-rumpuser_sp_copyin(void *arg, const void *uaddr, void *kaddr, size_t len)
+static int
+sp_copyin(void *arg, const void *raddr, void *laddr, size_t *len, int wantstr)
 {
 	struct spclient *spc = arg;
 	void *rdata = NULL; /* XXXuninit */
@@ -448,11 +455,11 @@
 
 	rumpuser__kunlock(0, &nlocks, NULL);
 
-	rv = copyin_req(spc, uaddr, len, &rdata);
+	rv = copyin_req(spc, raddr, len, wantstr, &rdata);
 	if (rv)
 		goto out;
 
-	memcpy(kaddr, rdata, len);
+	memcpy(laddr, rdata, *len);
 	free(rdata);
 
  out:
@@ -463,13 +470,27 @@
 }
 
 int
-rumpuser_sp_copyout(void *arg, const void *kaddr, void *uaddr, size_t dlen)
+rumpuser_sp_copyin(void *arg, const void *raddr, void *laddr, size_t len)
+{
+
+	return sp_copyin(arg, raddr, laddr, &len, 0);
+}
+
+int
+rumpuser_sp_copyinstr(void *arg, const void *raddr, void *laddr, size_t *len)
+{
+
+	return sp_copyin(arg, raddr, laddr, len, 1);
+}
+
+static int
+sp_copyout(void *arg, const void *laddr, void *raddr, size_t dlen)
 {
 	struct spclient *spc = arg;
 	int nlocks, rv;
 
 	rumpuser__kunlock(0, &nlocks, NULL);
-	rv = send_copyout_req(spc, uaddr, kaddr, dlen);
+	rv = send_copyout_req(spc, raddr, laddr, dlen);
 	rumpuser__klock(nlocks, NULL);
 
 	if (rv)
@@ -478,6 +499,20 @@
 }
 
 int
+rumpuser_sp_copyout(void *arg, const void *laddr, void *raddr, size_t dlen)
+{
+
+	return sp_copyout(arg, laddr, raddr, dlen);
+}
+
+int
+rumpuser_sp_copyoutstr(void *arg, const void *laddr, void *raddr, size_t *dlen)
+{
+
+	return sp_copyout(arg, laddr, raddr, *dlen);
+}
+
+int
 rumpuser_sp_anonmmap(void *arg, size_t howmuch, void **addr)
 {
 	struct spclient *spc = arg;

Index: src/lib/librumpuser/sp_common.c
diff -u src/lib/librumpuser/sp_common.c:1.9 src/lib/librumpuser/sp_common.c:1.10
--- src/lib/librumpuser/sp_common.c:1.9	Wed Nov 24 17:20:24 2010
+++ src/lib/librumpuser/sp_common.c	Thu Nov 25 17:59:02 2010
@@ -1,4 +1,4 @@
-/*      $NetBSD: sp_common.c,v 1.9 2010/11/24 17:20:24 pooka Exp $	*/
+/*      $NetBSD: sp_common.c,v 1.10 2010/11/25 17:59:02 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -73,7 +73,10 @@
  */
 
 enum { RUMPSP_REQ, RUMPSP_RESP };
-enum { RUMPSP_SYSCALL, RUMPSP_COPYIN, RUMPSP_COPYOUT, RUMPSP_ANONMMAP };
+enum {	RUMPSP_SYSCALL,
+	RUMPSP_COPYIN, RUMPSP_COPYINSTR,
+	RUMPSP_COPYOUT, RUMPSP_COPYOUTSTR,
+	RUMPSP_ANONMMAP };
 
 struct rsp_hdr {
 	uint64_t rsp_len;
@@ -196,8 +199,10 @@
 		if (n == 0) {
 			return EFAULT;
 		}
-		if (n == -1 && errno != EAGAIN) {
-			return EFAULT;
+		if (n == -1)  {
+			if (errno != EAGAIN)
+				return EFAULT;
+			continue;
 		}
 		sent += n;
 	}
@@ -242,7 +247,9 @@
 		abort();
 		return;
 	}
+	DPRINTF(("rump_sp: client %p woke up waiter at %p\n", spc, rw));
 	rw->rw_data = spc->spc_buf;
+	rw->rw_dlen = (size_t)spc->spc_off;
 	pthread_cond_signal(&rw->rw_cv);
 	pthread_mutex_unlock(&spc->spc_mtx);
 

Index: src/sys/rump/include/rump/rumpuser.h
diff -u src/sys/rump/include/rump/rumpuser.h:1.52 src/sys/rump/include/rump/rumpuser.h:1.53
--- src/sys/rump/include/rump/rumpuser.h:1.52	Mon Nov 22 20:42:19 2010
+++ src/sys/rump/include/rump/rumpuser.h	Thu Nov 25 17:59:02 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpuser.h,v 1.52 2010/11/22 20:42:19 pooka Exp $	*/
+/*	$NetBSD: rumpuser.h,v 1.53 2010/11/25 17:59:02 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -36,7 +36,7 @@
 #include <stdint.h>
 #endif
 
-#define RUMPUSER_VERSION 5
+#define RUMPUSER_VERSION 6
 int rumpuser_getversion(void);
 
 struct msghdr;
@@ -219,7 +219,9 @@
 
 int	rumpuser_sp_init(const struct rumpuser_sp_ops *, const char *);
 int	rumpuser_sp_copyin(void *, const void *, void *, size_t);
+int	rumpuser_sp_copyinstr(void *, const void *, void *, size_t *);
 int	rumpuser_sp_copyout(void *, const void *, void *, size_t);
+int	rumpuser_sp_copyoutstr(void *, const void *, void *, size_t *);
 int	rumpuser_sp_anonmmap(void *, size_t, void **);
 
 #endif /* _RUMP_RUMPUSER_H_ */

Index: src/sys/rump/librump/rumpkern/rumpcopy.c
diff -u src/sys/rump/librump/rumpkern/rumpcopy.c:1.12 src/sys/rump/librump/rumpkern/rumpcopy.c:1.13
--- src/sys/rump/librump/rumpkern/rumpcopy.c:1.12	Mon Nov 22 21:46:04 2010
+++ src/sys/rump/librump/rumpkern/rumpcopy.c	Thu Nov 25 17:59:03 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpcopy.c,v 1.12 2010/11/22 21:46:04 pooka Exp $	*/
+/*	$NetBSD: rumpcopy.c,v 1.13 2010/11/25 17:59:03 pooka Exp $	*/
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.12 2010/11/22 21:46:04 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.13 2010/11/25 17:59:03 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/lwp.h>
@@ -118,8 +118,8 @@
 	if (curproc->p_vmspace == vmspace_kernel())
 		return copystr(uaddr, kaddr, len, done);
 
-	if ((rv = rumpuser_sp_copyin(curproc->p_vmspace->vm_map.pmap,
-	    uaddr, kaddr, len)) != 0)
+	if ((rv = rumpuser_sp_copyinstr(curproc->p_vmspace->vm_map.pmap,
+	    uaddr, kaddr, &len)) != 0)
 		return rv;
 
 	/* figure out if we got a terminated string or not */
@@ -151,8 +151,8 @@
 	if (slen > len)
 		return ENAMETOOLONG;
 
-	error = rumpuser_sp_copyout(curproc->p_vmspace->vm_map.pmap,
-	    kaddr, uaddr, slen);
+	error = rumpuser_sp_copyoutstr(curproc->p_vmspace->vm_map.pmap,
+	    kaddr, uaddr, &slen);
 	if (done)
 		*done = slen;
 

Reply via email to