*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.diff -r1.4 -r1.5 src/lib/librumpclient/rumpclient.c
(pooka)
--- src/lib/librumpclient/rumpclient.c 2010/11/24 17:03:39 1.4
+++ src/lib/librumpclient/rumpclient.c 2010/11/25 17:59:03 1.5
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rumpclient.c,v 1.4 2010/11/24 17:03:39 pooka Exp $ */ | 1 | /* $NetBSD: rumpclient.c,v 1.5 2010/11/25 17:59:03 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2010 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -22,27 +22,27 @@ | @@ -22,27 +22,27 @@ | |||
22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
25 | * SUCH DAMAGE. | 25 | * SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | /* | 28 | /* | |
29 | * Client side routines for rump syscall proxy. | 29 | * Client side routines for rump syscall proxy. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include <sys/cdefs.h> | 32 | #include <sys/cdefs.h> | |
33 | __RCSID("$NetBSD"); | 33 | __RCSID("$NetBSD"); | |
34 | 34 | |||
35 | #include <sys/types.h> | 35 | #include <sys/param.h> | |
36 | #include <sys/mman.h> | 36 | #include <sys/mman.h> | |
37 | #include <sys/socket.h> | 37 | #include <sys/socket.h> | |
38 | 38 | |||
39 | #include <arpa/inet.h> | 39 | #include <arpa/inet.h> | |
40 | #include <netinet/in.h> | 40 | #include <netinet/in.h> | |
41 | #include <netinet/tcp.h> | 41 | #include <netinet/tcp.h> | |
42 | 42 | |||
43 | #include <assert.h> | 43 | #include <assert.h> | |
44 | #include <errno.h> | 44 | #include <errno.h> | |
45 | #include <fcntl.h> | 45 | #include <fcntl.h> | |
46 | #include <poll.h> | 46 | #include <poll.h> | |
47 | #include <pthread.h> | 47 | #include <pthread.h> | |
48 | #include <stdarg.h> | 48 | #include <stdarg.h> | |
@@ -74,31 +74,35 @@ syscall_req(struct spclient *spc, int sy | @@ -74,31 +74,35 @@ syscall_req(struct spclient *spc, int sy | |||
74 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | 74 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | |
75 | rv = dosend(spc, data, dlen); | 75 | rv = dosend(spc, data, dlen); | |
76 | if (rv) { | 76 | if (rv) { | |
77 | unputwait(spc, &rw); | 77 | unputwait(spc, &rw); | |
78 | return rv; | 78 | return rv; | |
79 | } | 79 | } | |
80 | 80 | |||
81 | rv = waitresp(spc, &rw); | 81 | rv = waitresp(spc, &rw); | |
82 | *resp = rw.rw_data; | 82 | *resp = rw.rw_data; | |
83 | return rv; | 83 | return rv; | |
84 | } | 84 | } | |
85 | 85 | |||
86 | static int | 86 | static int | |
87 | send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen) | 87 | send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen, | |
88 | int wantstr) | |||
88 | { | 89 | { | |
89 | struct rsp_hdr rhdr; | 90 | struct rsp_hdr rhdr; | |
90 | int rv; | 91 | int rv; | |
91 | 92 | |||
93 | if (wantstr) | |||
94 | dlen = MIN(dlen, strlen(data)+1); | |||
95 | ||||
92 | rhdr.rsp_len = sizeof(rhdr) + dlen; | 96 | rhdr.rsp_len = sizeof(rhdr) + dlen; | |
93 | rhdr.rsp_reqno = reqno; | 97 | rhdr.rsp_reqno = reqno; | |
94 | rhdr.rsp_class = RUMPSP_RESP; | 98 | rhdr.rsp_class = RUMPSP_RESP; | |
95 | rhdr.rsp_type = RUMPSP_COPYIN; | 99 | rhdr.rsp_type = RUMPSP_COPYIN; | |
96 | rhdr.rsp_sysnum = 0; | 100 | rhdr.rsp_sysnum = 0; | |
97 | 101 | |||
98 | sendlock(spc); | 102 | sendlock(spc); | |
99 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | 103 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | |
100 | rv = dosend(spc, data, dlen); | 104 | rv = dosend(spc, data, dlen); | |
101 | sendunlock(spc); | 105 | sendunlock(spc); | |
102 | 106 | |||
103 | return rv; | 107 | return rv; | |
104 | } | 108 | } | |
@@ -145,37 +149,41 @@ rumpclient_syscall(int sysnum, const voi | @@ -145,37 +149,41 @@ rumpclient_syscall(int sysnum, const voi | |||
145 | memcpy(retval, &resp->rsys_retval, sizeof(resp->rsys_retval)); | 149 | memcpy(retval, &resp->rsys_retval, sizeof(resp->rsys_retval)); | |
146 | rv = resp->rsys_error; | 150 | rv = resp->rsys_error; | |
147 | free(rdata); | 151 | free(rdata); | |
148 | 152 | |||
149 | return rv; | 153 | return rv; | |
150 | } | 154 | } | |
151 | 155 | |||
152 | static void | 156 | static void | |
153 | handlereq(struct spclient *spc) | 157 | handlereq(struct spclient *spc) | |
154 | { | 158 | { | |
155 | struct rsp_copydata *copydata; | 159 | struct rsp_copydata *copydata; | |
156 | void *mapaddr; | 160 | void *mapaddr; | |
157 | size_t maplen; | 161 | size_t maplen; | |
162 | int reqtype = spc->spc_hdr.rsp_type; | |||
158 | 163 | |||
159 | switch (spc->spc_hdr.rsp_type) { | 164 | switch (reqtype) { | |
160 | case RUMPSP_COPYIN: | 165 | case RUMPSP_COPYIN: | |
166 | case RUMPSP_COPYINSTR: | |||
161 | /*LINTED*/ | 167 | /*LINTED*/ | |
162 | copydata = (struct rsp_copydata *)spc->spc_buf; | 168 | copydata = (struct rsp_copydata *)spc->spc_buf; | |
163 | DPRINTF(("rump_sp handlereq: copyin request: %p/%zu\n", | 169 | DPRINTF(("rump_sp handlereq: copyin request: %p/%zu\n", | |
164 | copydata->rcp_addr, copydata->rcp_len)); | 170 | copydata->rcp_addr, copydata->rcp_len)); | |
165 | send_copyin_resp(spc, spc->spc_hdr.rsp_reqno, | 171 | send_copyin_resp(spc, spc->spc_hdr.rsp_reqno, | |
166 | copydata->rcp_addr, copydata->rcp_len); | 172 | copydata->rcp_addr, copydata->rcp_len, | |
173 | reqtype == RUMPSP_COPYINSTR); | |||
167 | break; | 174 | break; | |
168 | case RUMPSP_COPYOUT: | 175 | case RUMPSP_COPYOUT: | |
176 | case RUMPSP_COPYOUTSTR: | |||
169 | /*LINTED*/ | 177 | /*LINTED*/ | |
170 | copydata = (struct rsp_copydata *)spc->spc_buf; | 178 | copydata = (struct rsp_copydata *)spc->spc_buf; | |
171 | DPRINTF(("rump_sp handlereq: copyout request: %p/%zu\n", | 179 | DPRINTF(("rump_sp handlereq: copyout request: %p/%zu\n", | |
172 | copydata->rcp_addr, copydata->rcp_len)); | 180 | copydata->rcp_addr, copydata->rcp_len)); | |
173 | /*LINTED*/ | 181 | /*LINTED*/ | |
174 | memcpy(copydata->rcp_addr, copydata->rcp_data, | 182 | memcpy(copydata->rcp_addr, copydata->rcp_data, | |
175 | copydata->rcp_len); | 183 | copydata->rcp_len); | |
176 | break; | 184 | break; | |
177 | case RUMPSP_ANONMMAP: | 185 | case RUMPSP_ANONMMAP: | |
178 | /*LINTED*/ | 186 | /*LINTED*/ | |
179 | maplen = *(size_t *)spc->spc_buf; | 187 | maplen = *(size_t *)spc->spc_buf; | |
180 | mapaddr = mmap(NULL, maplen, PROT_READ|PROT_WRITE, | 188 | mapaddr = mmap(NULL, maplen, PROT_READ|PROT_WRITE, | |
181 | MAP_ANON, -1, 0); | 189 | MAP_ANON, -1, 0); |
--- src/lib/librumpuser/rumpuser_sp.c 2010/11/24 20:29:13 1.14
+++ src/lib/librumpuser/rumpuser_sp.c 2010/11/25 17:59:02 1.15
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rumpuser_sp.c,v 1.14 2010/11/24 20:29:13 pooka Exp $ */ | 1 | /* $NetBSD: rumpuser_sp.c,v 1.15 2010/11/25 17:59:02 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2010 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -28,27 +28,27 @@ | @@ -28,27 +28,27 @@ | |||
28 | /* | 28 | /* | |
29 | * Sysproxy routines. This provides system RPC support over host sockets. | 29 | * Sysproxy routines. This provides system RPC support over host sockets. | |
30 | * The most notable limitation is that the client and server must share | 30 | * The most notable limitation is that the client and server must share | |
31 | * the same ABI. This does not mean that they have to be the same | 31 | * the same ABI. This does not mean that they have to be the same | |
32 | * machine or that they need to run the same version of the host OS, | 32 | * machine or that they need to run the same version of the host OS, | |
33 | * just that they must agree on the data structures. This even *might* | 33 | * just that they must agree on the data structures. This even *might* | |
34 | * work correctly from one hardware architecture to another. | 34 | * work correctly from one hardware architecture to another. | |
35 | * | 35 | * | |
36 | * Not finished yet, i.e. don't use in production. Lacks locking plus | 36 | * Not finished yet, i.e. don't use in production. Lacks locking plus | |
37 | * handling of multiple clients and unexpected connection closes. | 37 | * handling of multiple clients and unexpected connection closes. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #include <sys/cdefs.h> | 40 | #include <sys/cdefs.h> | |
41 | __RCSID("$NetBSD: rumpuser_sp.c,v 1.14 2010/11/24 20:29:13 pooka Exp $"); | 41 | __RCSID("$NetBSD: rumpuser_sp.c,v 1.15 2010/11/25 17:59:02 pooka Exp $"); | |
42 | 42 | |||
43 | #include <sys/types.h> | 43 | #include <sys/types.h> | |
44 | #include <sys/atomic.h> | 44 | #include <sys/atomic.h> | |
45 | #include <sys/mman.h> | 45 | #include <sys/mman.h> | |
46 | #include <sys/socket.h> | 46 | #include <sys/socket.h> | |
47 | 47 | |||
48 | #include <arpa/inet.h> | 48 | #include <arpa/inet.h> | |
49 | #include <netinet/in.h> | 49 | #include <netinet/in.h> | |
50 | #include <netinet/tcp.h> | 50 | #include <netinet/tcp.h> | |
51 | 51 | |||
52 | #include <assert.h> | 52 | #include <assert.h> | |
53 | #include <errno.h> | 53 | #include <errno.h> | |
54 | #include <fcntl.h> | 54 | #include <fcntl.h> | |
@@ -184,56 +184,63 @@ send_syscall_resp(struct spclient *spc, | @@ -184,56 +184,63 @@ send_syscall_resp(struct spclient *spc, | |||
184 | 184 | |||
185 | sysresp.rsys_error = error; | 185 | sysresp.rsys_error = error; | |
186 | memcpy(sysresp.rsys_retval, retval, sizeof(sysresp.rsys_retval)); | 186 | memcpy(sysresp.rsys_retval, retval, sizeof(sysresp.rsys_retval)); | |
187 | 187 | |||
188 | sendlock(spc); | 188 | sendlock(spc); | |
189 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | 189 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | |
190 | rv = dosend(spc, &sysresp, sizeof(sysresp)); | 190 | rv = dosend(spc, &sysresp, sizeof(sysresp)); | |
191 | sendunlock(spc); | 191 | sendunlock(spc); | |
192 | 192 | |||
193 | return rv; | 193 | return rv; | |
194 | } | 194 | } | |
195 | 195 | |||
196 | static int | 196 | static int | |
197 | copyin_req(struct spclient *spc, const void *remaddr, size_t dlen, void **resp) | 197 | copyin_req(struct spclient *spc, const void *remaddr, size_t *dlen, | |
198 | int wantstr, void **resp) | |||
198 | { | 199 | { | |
199 | struct rsp_hdr rhdr; | 200 | struct rsp_hdr rhdr; | |
200 | struct rsp_copydata copydata; | 201 | struct rsp_copydata copydata; | |
201 | struct respwait rw; | 202 | struct respwait rw; | |
202 | int rv; | 203 | int rv; | |
203 | 204 | |||
204 | DPRINTF(("copyin_req: %zu bytes from %p\n", dlen, remaddr)); | 205 | DPRINTF(("copyin_req: %zu bytes from %p\n", *dlen, remaddr)); | |
205 | 206 | |||
206 | rhdr.rsp_len = sizeof(rhdr) + sizeof(copydata); | 207 | rhdr.rsp_len = sizeof(rhdr) + sizeof(copydata); | |
207 | rhdr.rsp_class = RUMPSP_REQ; | 208 | rhdr.rsp_class = RUMPSP_REQ; | |
208 | rhdr.rsp_type = RUMPSP_COPYIN; | 209 | if (wantstr) | |
210 | rhdr.rsp_type = RUMPSP_COPYINSTR; | |||
211 | else | |||
212 | rhdr.rsp_type = RUMPSP_COPYIN; | |||
209 | rhdr.rsp_sysnum = 0; | 213 | rhdr.rsp_sysnum = 0; | |
210 | 214 | |||
211 | copydata.rcp_addr = __UNCONST(remaddr); | 215 | copydata.rcp_addr = __UNCONST(remaddr); | |
212 | copydata.rcp_len = dlen; | 216 | copydata.rcp_len = *dlen; | |
213 | 217 | |||
214 | putwait(spc, &rw, &rhdr); | 218 | putwait(spc, &rw, &rhdr); | |
215 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | 219 | rv = dosend(spc, &rhdr, sizeof(rhdr)); | |
216 | rv = dosend(spc, ©data, sizeof(copydata)); | 220 | rv = dosend(spc, ©data, sizeof(copydata)); | |
217 | if (rv) { | 221 | if (rv) { | |
218 | unputwait(spc, &rw); | 222 | unputwait(spc, &rw); | |
219 | return rv; | 223 | return rv; | |
220 | } | 224 | } | |
221 | 225 | |||
222 | rv = waitresp(spc, &rw); | 226 | rv = waitresp(spc, &rw); | |
223 | 227 | |||
224 | DPRINTF(("copyin: response %d\n", rv)); | 228 | DPRINTF(("copyin: response %d\n", rv)); | |
225 | 229 | |||
226 | *resp = rw.rw_data; | 230 | *resp = rw.rw_data; | |
231 | if (wantstr) | |||
232 | *dlen = rw.rw_dlen; | |||
233 | ||||
227 | return rv; | 234 | return rv; | |
228 | 235 | |||
229 | } | 236 | } | |
230 | 237 | |||
231 | static int | 238 | static int | |
232 | send_copyout_req(struct spclient *spc, const void *remaddr, | 239 | send_copyout_req(struct spclient *spc, const void *remaddr, | |
233 | const void *data, size_t dlen) | 240 | const void *data, size_t dlen) | |
234 | { | 241 | { | |
235 | struct rsp_hdr rhdr; | 242 | struct rsp_hdr rhdr; | |
236 | struct rsp_copydata copydata; | 243 | struct rsp_copydata copydata; | |
237 | int rv; | 244 | int rv; | |
238 | 245 | |||
239 | DPRINTF(("copyout_req (async): %zu bytes to %p\n", dlen, remaddr)); | 246 | DPRINTF(("copyout_req (async): %zu bytes to %p\n", dlen, remaddr)); | |
@@ -429,65 +436,93 @@ struct sysbouncearg { | @@ -429,65 +436,93 @@ struct sysbouncearg { | |||
429 | uint8_t *sba_data; | 436 | uint8_t *sba_data; | |
430 | }; | 437 | }; | |
431 | static void * | 438 | static void * | |
432 | serv_syscallbouncer(void *arg) | 439 | serv_syscallbouncer(void *arg) | |
433 | { | 440 | { | |
434 | struct sysbouncearg *barg = arg; | 441 | struct sysbouncearg *barg = arg; | |
435 | 442 | |||
436 | serv_handlesyscall(barg->sba_spc, &barg->sba_hdr, barg->sba_data); | 443 | serv_handlesyscall(barg->sba_spc, &barg->sba_hdr, barg->sba_data); | |
437 | spcrelease(barg->sba_spc); | 444 | spcrelease(barg->sba_spc); | |
438 | free(arg); | 445 | free(arg); | |
439 | return NULL; | 446 | return NULL; | |
440 | } | 447 | } | |
441 | 448 | |||
442 | int | 449 | static int | |
443 | rumpuser_sp_copyin(void *arg, const void *uaddr, void *kaddr, size_t len) | 450 | sp_copyin(void *arg, const void *raddr, void *laddr, size_t *len, int wantstr) | |
444 | { | 451 | { | |
445 | struct spclient *spc = arg; | 452 | struct spclient *spc = arg; | |
446 | void *rdata = NULL; /* XXXuninit */ | 453 | void *rdata = NULL; /* XXXuninit */ | |
447 | int rv, nlocks; | 454 | int rv, nlocks; | |
448 | 455 | |||
449 | rumpuser__kunlock(0, &nlocks, NULL); | 456 | rumpuser__kunlock(0, &nlocks, NULL); | |
450 | 457 | |||
451 | rv = copyin_req(spc, uaddr, len, &rdata); | 458 | rv = copyin_req(spc, raddr, len, wantstr, &rdata); | |
452 | if (rv) | 459 | if (rv) | |
453 | goto out; | 460 | goto out; | |
454 | 461 | |||
455 | memcpy(kaddr, rdata, len); | 462 | memcpy(laddr, rdata, *len); | |
456 | free(rdata); | 463 | free(rdata); | |
457 | 464 | |||
458 | out: | 465 | out: | |
459 | rumpuser__klock(nlocks, NULL); | 466 | rumpuser__klock(nlocks, NULL); | |
460 | if (rv) | 467 | if (rv) | |
461 | return EFAULT; | 468 | return EFAULT; | |
462 | return 0; | 469 | return 0; | |
463 | } | 470 | } | |
464 | 471 | |||
465 | int | 472 | int | |
466 | rumpuser_sp_copyout(void *arg, const void *kaddr, void *uaddr, size_t dlen) | 473 | rumpuser_sp_copyin(void *arg, const void *raddr, void *laddr, size_t len) | |
474 | { | |||
475 | ||||
476 | return sp_copyin(arg, raddr, laddr, &len, 0); | |||
477 | } | |||
478 | ||||
479 | int | |||
480 | rumpuser_sp_copyinstr(void *arg, const void *raddr, void *laddr, size_t *len) | |||
481 | { | |||
482 | ||||
483 | return sp_copyin(arg, raddr, laddr, len, 1); | |||
484 | } | |||
485 | ||||
486 | static int | |||
487 | sp_copyout(void *arg, const void *laddr, void *raddr, size_t dlen) | |||
467 | { | 488 | { | |
468 | struct spclient *spc = arg; | 489 | struct spclient *spc = arg; | |
469 | int nlocks, rv; | 490 | int nlocks, rv; | |
470 | 491 | |||
471 | rumpuser__kunlock(0, &nlocks, NULL); | 492 | rumpuser__kunlock(0, &nlocks, NULL); | |
472 | rv = send_copyout_req(spc, uaddr, kaddr, dlen); | 493 | rv = send_copyout_req(spc, raddr, laddr, dlen); | |
473 | rumpuser__klock(nlocks, NULL); | 494 | rumpuser__klock(nlocks, NULL); | |
474 | 495 | |||
475 | if (rv) | 496 | if (rv) | |
476 | return EFAULT; | 497 | return EFAULT; | |
477 | return 0; | 498 | return 0; | |
478 | } | 499 | } | |
479 | 500 | |||
480 | int | 501 | int | |
502 | rumpuser_sp_copyout(void *arg, const void *laddr, void *raddr, size_t dlen) | |||
503 | { | |||
504 | ||||
505 | return sp_copyout(arg, laddr, raddr, dlen); | |||
506 | } | |||
507 | ||||
508 | int | |||
509 | rumpuser_sp_copyoutstr(void *arg, const void *laddr, void *raddr, size_t *dlen) | |||
510 | { | |||
511 | ||||
512 | return sp_copyout(arg, laddr, raddr, *dlen); | |||
513 | } | |||
514 | ||||
515 | int | |||
481 | rumpuser_sp_anonmmap(void *arg, size_t howmuch, void **addr) | 516 | rumpuser_sp_anonmmap(void *arg, size_t howmuch, void **addr) | |
482 | { | 517 | { | |
483 | struct spclient *spc = arg; | 518 | struct spclient *spc = arg; | |
484 | void *resp, *rdata; | 519 | void *resp, *rdata; | |
485 | int nlocks, rv; | 520 | int nlocks, rv; | |
486 | 521 | |||
487 | rumpuser__kunlock(0, &nlocks, NULL); | 522 | rumpuser__kunlock(0, &nlocks, NULL); | |
488 | 523 | |||
489 | rv = anonmmap_req(spc, howmuch, &rdata); | 524 | rv = anonmmap_req(spc, howmuch, &rdata); | |
490 | if (rv) { | 525 | if (rv) { | |
491 | rv = EFAULT; | 526 | rv = EFAULT; | |
492 | goto out; | 527 | goto out; | |
493 | } | 528 | } |
--- src/lib/librumpuser/sp_common.c 2010/11/24 17:20:24 1.9
+++ src/lib/librumpuser/sp_common.c 2010/11/25 17:59:02 1.10
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: sp_common.c,v 1.9 2010/11/24 17:20:24 pooka Exp $ */ | 1 | /* $NetBSD: sp_common.c,v 1.10 2010/11/25 17:59:02 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2010 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -63,27 +63,30 @@ mydprintf(const char *fmt, ...) | @@ -63,27 +63,30 @@ mydprintf(const char *fmt, ...) | |||
63 | va_start(ap, fmt); | 63 | va_start(ap, fmt); | |
64 | vfprintf(stderr, fmt, ap); | 64 | vfprintf(stderr, fmt, ap); | |
65 | va_end(ap); | 65 | va_end(ap); | |
66 | } | 66 | } | |
67 | #else | 67 | #else | |
68 | #define DPRINTF(x) | 68 | #define DPRINTF(x) | |
69 | #endif | 69 | #endif | |
70 | 70 | |||
71 | /* | 71 | /* | |
72 | * Bah, I hate writing on-off-wire conversions in C | 72 | * Bah, I hate writing on-off-wire conversions in C | |
73 | */ | 73 | */ | |
74 | 74 | |||
75 | enum { RUMPSP_REQ, RUMPSP_RESP }; | 75 | enum { RUMPSP_REQ, RUMPSP_RESP }; | |
76 | enum { RUMPSP_SYSCALL, RUMPSP_COPYIN, RUMPSP_COPYOUT, RUMPSP_ANONMMAP }; | 76 | enum { RUMPSP_SYSCALL, | |
77 | RUMPSP_COPYIN, RUMPSP_COPYINSTR, | |||
78 | RUMPSP_COPYOUT, RUMPSP_COPYOUTSTR, | |||
79 | RUMPSP_ANONMMAP }; | |||
77 | 80 | |||
78 | struct rsp_hdr { | 81 | struct rsp_hdr { | |
79 | uint64_t rsp_len; | 82 | uint64_t rsp_len; | |
80 | uint64_t rsp_reqno; | 83 | uint64_t rsp_reqno; | |
81 | uint16_t rsp_class; | 84 | uint16_t rsp_class; | |
82 | uint16_t rsp_type; | 85 | uint16_t rsp_type; | |
83 | /* | 86 | /* | |
84 | * We want this structure 64bit-aligned for typecast fun, | 87 | * We want this structure 64bit-aligned for typecast fun, | |
85 | * so might as well use the following for something. | 88 | * so might as well use the following for something. | |
86 | */ | 89 | */ | |
87 | uint32_t rsp_sysnum; | 90 | uint32_t rsp_sysnum; | |
88 | }; | 91 | }; | |
89 | #define HDRSZ sizeof(struct rsp_hdr) | 92 | #define HDRSZ sizeof(struct rsp_hdr) | |
@@ -186,28 +189,30 @@ dosend(struct spclient *spc, const void | @@ -186,28 +189,30 @@ dosend(struct spclient *spc, const void | |||
186 | for (sent = 0, n = 0; sent < dlen; ) { | 189 | for (sent = 0, n = 0; sent < dlen; ) { | |
187 | if (n) { | 190 | if (n) { | |
188 | if (poll(&pfd, 1, INFTIM) == -1) { | 191 | if (poll(&pfd, 1, INFTIM) == -1) { | |
189 | if (errno == EINTR) | 192 | if (errno == EINTR) | |
190 | continue; | 193 | continue; | |
191 | return errno; | 194 | return errno; | |
192 | } | 195 | } | |
193 | } | 196 | } | |
194 | 197 | |||
195 | n = send(fd, sdata + sent, dlen - sent, MSG_NOSIGNAL); | 198 | n = send(fd, sdata + sent, dlen - sent, MSG_NOSIGNAL); | |
196 | if (n == 0) { | 199 | if (n == 0) { | |
197 | return EFAULT; | 200 | return EFAULT; | |
198 | } | 201 | } | |
199 | if (n == -1 && errno != EAGAIN) { | 202 | if (n == -1) { | |
200 | return EFAULT; | 203 | if (errno != EAGAIN) | |
204 | return EFAULT; | |||
205 | continue; | |||
201 | } | 206 | } | |
202 | sent += n; | 207 | sent += n; | |
203 | } | 208 | } | |
204 | 209 | |||
205 | return 0; | 210 | return 0; | |
206 | } | 211 | } | |
207 | 212 | |||
208 | static void | 213 | static void | |
209 | putwait(struct spclient *spc, struct respwait *rw, struct rsp_hdr *rhdr) | 214 | putwait(struct spclient *spc, struct respwait *rw, struct rsp_hdr *rhdr) | |
210 | { | 215 | { | |
211 | 216 | |||
212 | rw->rw_data = NULL; | 217 | rw->rw_data = NULL; | |
213 | rw->rw_dlen = 0; | 218 | rw->rw_dlen = 0; | |
@@ -232,27 +237,29 @@ kickwaiter(struct spclient *spc) | @@ -232,27 +237,29 @@ kickwaiter(struct spclient *spc) | |||
232 | { | 237 | { | |
233 | struct respwait *rw; | 238 | struct respwait *rw; | |
234 | 239 | |||
235 | pthread_mutex_lock(&spc->spc_mtx); | 240 | pthread_mutex_lock(&spc->spc_mtx); | |
236 | TAILQ_FOREACH(rw, &spc->spc_respwait, rw_entries) { | 241 | TAILQ_FOREACH(rw, &spc->spc_respwait, rw_entries) { | |
237 | if (rw->rw_reqno == spc->spc_hdr.rsp_reqno) | 242 | if (rw->rw_reqno == spc->spc_hdr.rsp_reqno) | |
238 | break; | 243 | break; | |
239 | } | 244 | } | |
240 | if (rw == NULL) { | 245 | if (rw == NULL) { | |
241 | printf("PANIC: no waiter\n"); | 246 | printf("PANIC: no waiter\n"); | |
242 | abort(); | 247 | abort(); | |
243 | return; | 248 | return; | |
244 | } | 249 | } | |
250 | DPRINTF(("rump_sp: client %p woke up waiter at %p\n", spc, rw)); | |||
245 | rw->rw_data = spc->spc_buf; | 251 | rw->rw_data = spc->spc_buf; | |
252 | rw->rw_dlen = (size_t)spc->spc_off; | |||
246 | pthread_cond_signal(&rw->rw_cv); | 253 | pthread_cond_signal(&rw->rw_cv); | |
247 | pthread_mutex_unlock(&spc->spc_mtx); | 254 | pthread_mutex_unlock(&spc->spc_mtx); | |
248 | 255 | |||
249 | spc->spc_buf = NULL; | 256 | spc->spc_buf = NULL; | |
250 | spc->spc_off = 0; | 257 | spc->spc_off = 0; | |
251 | } | 258 | } | |
252 | 259 | |||
253 | static void | 260 | static void | |
254 | kickall(struct spclient *spc) | 261 | kickall(struct spclient *spc) | |
255 | { | 262 | { | |
256 | struct respwait *rw; | 263 | struct respwait *rw; | |
257 | 264 | |||
258 | /* DIAGASSERT(mutex_owned(spc_lock)) */ | 265 | /* DIAGASSERT(mutex_owned(spc_lock)) */ |
--- src/sys/rump/include/rump/rumpuser.h 2010/11/22 20:42:19 1.52
+++ src/sys/rump/include/rump/rumpuser.h 2010/11/25 17:59:02 1.53
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rumpuser.h,v 1.52 2010/11/22 20:42:19 pooka Exp $ */ | 1 | /* $NetBSD: rumpuser.h,v 1.53 2010/11/25 17:59:02 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2007 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2007 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Development of this software was supported by Google Summer of Code. | 6 | * Development of this software was supported by Google Summer of Code. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -26,27 +26,27 @@ | @@ -26,27 +26,27 @@ | |||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #ifndef _RUMP_RUMPUSER_H_ | 30 | #ifndef _RUMP_RUMPUSER_H_ | |
31 | #define _RUMP_RUMPUSER_H_ | 31 | #define _RUMP_RUMPUSER_H_ | |
32 | 32 | |||
33 | #ifdef _KERNEL | 33 | #ifdef _KERNEL | |
34 | #include <sys/stdint.h> | 34 | #include <sys/stdint.h> | |
35 | #else | 35 | #else | |
36 | #include <stdint.h> | 36 | #include <stdint.h> | |
37 | #endif | 37 | #endif | |
38 | 38 | |||
39 | #define RUMPUSER_VERSION 5 | 39 | #define RUMPUSER_VERSION 6 | |
40 | int rumpuser_getversion(void); | 40 | int rumpuser_getversion(void); | |
41 | 41 | |||
42 | struct msghdr; | 42 | struct msghdr; | |
43 | struct pollfd; | 43 | struct pollfd; | |
44 | struct sockaddr; | 44 | struct sockaddr; | |
45 | 45 | |||
46 | typedef void (*kernel_lockfn)(int, void *); | 46 | typedef void (*kernel_lockfn)(int, void *); | |
47 | typedef void (*kernel_unlockfn)(int, int *, void *); | 47 | typedef void (*kernel_unlockfn)(int, int *, void *); | |
48 | 48 | |||
49 | int rumpuser_getfileinfo(const char *, uint64_t *, int *, int *); | 49 | int rumpuser_getfileinfo(const char *, uint64_t *, int *, int *); | |
50 | #define RUMPUSER_FT_OTHER 0 | 50 | #define RUMPUSER_FT_OTHER 0 | |
51 | #define RUMPUSER_FT_DIR 1 | 51 | #define RUMPUSER_FT_DIR 1 | |
52 | #define RUMPUSER_FT_REG 2 | 52 | #define RUMPUSER_FT_REG 2 | |
@@ -209,17 +209,19 @@ struct rumpuser_sp_ops { | @@ -209,17 +209,19 @@ struct rumpuser_sp_ops { | |||
209 | void (*spop_unschedule)(void); | 209 | void (*spop_unschedule)(void); | |
210 | 210 | |||
211 | void (*spop_lwproc_switch)(struct lwp *); | 211 | void (*spop_lwproc_switch)(struct lwp *); | |
212 | void (*spop_lwproc_release)(void); | 212 | void (*spop_lwproc_release)(void); | |
213 | int (*spop_lwproc_newproc)(void *); | 213 | int (*spop_lwproc_newproc)(void *); | |
214 | int (*spop_lwproc_newlwp)(pid_t); | 214 | int (*spop_lwproc_newlwp)(pid_t); | |
215 | struct lwp * (*spop_lwproc_curlwp)(void); | 215 | struct lwp * (*spop_lwproc_curlwp)(void); | |
216 | int (*spop_syscall)(int, void *, register_t *); | 216 | int (*spop_syscall)(int, void *, register_t *); | |
217 | pid_t (*spop_getpid)(void); | 217 | pid_t (*spop_getpid)(void); | |
218 | }; | 218 | }; | |
219 | 219 | |||
220 | int rumpuser_sp_init(const struct rumpuser_sp_ops *, const char *); | 220 | int rumpuser_sp_init(const struct rumpuser_sp_ops *, const char *); | |
221 | int rumpuser_sp_copyin(void *, const void *, void *, size_t); | 221 | int rumpuser_sp_copyin(void *, const void *, void *, size_t); | |
222 | int rumpuser_sp_copyinstr(void *, const void *, void *, size_t *); | |||
222 | int rumpuser_sp_copyout(void *, const void *, void *, size_t); | 223 | int rumpuser_sp_copyout(void *, const void *, void *, size_t); | |
224 | int rumpuser_sp_copyoutstr(void *, const void *, void *, size_t *); | |||
223 | int rumpuser_sp_anonmmap(void *, size_t, void **); | 225 | int rumpuser_sp_anonmmap(void *, size_t, void **); | |
224 | 226 | |||
225 | #endif /* _RUMP_RUMPUSER_H_ */ | 227 | #endif /* _RUMP_RUMPUSER_H_ */ |
--- src/sys/rump/librump/rumpkern/rumpcopy.c 2010/11/22 21:46:04 1.12
+++ src/sys/rump/librump/rumpkern/rumpcopy.c 2010/11/25 17:59:03 1.13
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rumpcopy.c,v 1.12 2010/11/22 21:46:04 pooka Exp $ */ | 1 | /* $NetBSD: rumpcopy.c,v 1.13 2010/11/25 17:59:03 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2009 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2009 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -16,27 +16,27 @@ | @@ -16,27 +16,27 @@ | |||
16 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 16 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
25 | * SUCH DAMAGE. | 25 | * SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | __KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.12 2010/11/22 21:46:04 pooka Exp $"); | 29 | __KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.13 2010/11/25 17:59:03 pooka Exp $"); | |
30 | 30 | |||
31 | #include <sys/param.h> | 31 | #include <sys/param.h> | |
32 | #include <sys/lwp.h> | 32 | #include <sys/lwp.h> | |
33 | #include <sys/systm.h> | 33 | #include <sys/systm.h> | |
34 | #include <sys/uio.h> | 34 | #include <sys/uio.h> | |
35 | 35 | |||
36 | #include <rump/rumpuser.h> | 36 | #include <rump/rumpuser.h> | |
37 | 37 | |||
38 | #include "rump_private.h" | 38 | #include "rump_private.h" | |
39 | 39 | |||
40 | int | 40 | int | |
41 | copyin(const void *uaddr, void *kaddr, size_t len) | 41 | copyin(const void *uaddr, void *kaddr, size_t len) | |
42 | { | 42 | { | |
@@ -108,28 +108,28 @@ copystr(const void *kfaddr, void *kdaddr | @@ -108,28 +108,28 @@ copystr(const void *kfaddr, void *kdaddr | |||
108 | 108 | |||
109 | int | 109 | int | |
110 | copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) | 110 | copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) | |
111 | { | 111 | { | |
112 | uint8_t *to; | 112 | uint8_t *to; | |
113 | int rv; | 113 | int rv; | |
114 | 114 | |||
115 | if (len == 0) | 115 | if (len == 0) | |
116 | return 0; | 116 | return 0; | |
117 | 117 | |||
118 | if (curproc->p_vmspace == vmspace_kernel()) | 118 | if (curproc->p_vmspace == vmspace_kernel()) | |
119 | return copystr(uaddr, kaddr, len, done); | 119 | return copystr(uaddr, kaddr, len, done); | |
120 | 120 | |||
121 | if ((rv = rumpuser_sp_copyin(curproc->p_vmspace->vm_map.pmap, | 121 | if ((rv = rumpuser_sp_copyinstr(curproc->p_vmspace->vm_map.pmap, | |
122 | uaddr, kaddr, len)) != 0) | 122 | uaddr, kaddr, &len)) != 0) | |
123 | return rv; | 123 | return rv; | |
124 | 124 | |||
125 | /* figure out if we got a terminated string or not */ | 125 | /* figure out if we got a terminated string or not */ | |
126 | to = (uint8_t *)kaddr + (len-1); | 126 | to = (uint8_t *)kaddr + (len-1); | |
127 | while (to != kaddr) { | 127 | while (to != kaddr) { | |
128 | if (*to == 0) | 128 | if (*to == 0) | |
129 | goto found; | 129 | goto found; | |
130 | to--; | 130 | to--; | |
131 | } | 131 | } | |
132 | return ENAMETOOLONG; | 132 | return ENAMETOOLONG; | |
133 | 133 | |||
134 | found: | 134 | found: | |
135 | if (done) | 135 | if (done) | |
@@ -141,28 +141,28 @@ copyinstr(const void *uaddr, void *kaddr | @@ -141,28 +141,28 @@ copyinstr(const void *uaddr, void *kaddr | |||
141 | int | 141 | int | |
142 | copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done) | 142 | copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done) | |
143 | { | 143 | { | |
144 | size_t slen; | 144 | size_t slen; | |
145 | int error; | 145 | int error; | |
146 | 146 | |||
147 | if (curproc->p_vmspace == vmspace_kernel()) | 147 | if (curproc->p_vmspace == vmspace_kernel()) | |
148 | return copystr(kaddr, uaddr, len, done); | 148 | return copystr(kaddr, uaddr, len, done); | |
149 | 149 | |||
150 | slen = strlen(kaddr)+1; | 150 | slen = strlen(kaddr)+1; | |
151 | if (slen > len) | 151 | if (slen > len) | |
152 | return ENAMETOOLONG; | 152 | return ENAMETOOLONG; | |
153 | 153 | |||
154 | error = rumpuser_sp_copyout(curproc->p_vmspace->vm_map.pmap, | 154 | error = rumpuser_sp_copyoutstr(curproc->p_vmspace->vm_map.pmap, | |
155 | kaddr, uaddr, slen); | 155 | kaddr, uaddr, &slen); | |
156 | if (done) | 156 | if (done) | |
157 | *done = slen; | 157 | *done = slen; | |
158 | 158 | |||
159 | return error; | 159 | return error; | |
160 | } | 160 | } | |
161 | 161 | |||
162 | int | 162 | int | |
163 | kcopy(const void *src, void *dst, size_t len) | 163 | kcopy(const void *src, void *dst, size_t len) | |
164 | { | 164 | { | |
165 | 165 | |||
166 | memcpy(dst, src, len); | 166 | memcpy(dst, src, len); | |
167 | return 0; | 167 | return 0; | |
168 | } | 168 | } |