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;