Home | History | Annotate | Line # | Download | only in rumpkern
rumpcopy.c revision 1.9
      1 /*	$NetBSD: rumpcopy.c,v 1.9 2010/11/09 20:55:14 pooka Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     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
     24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25  * SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.9 2010/11/09 20:55:14 pooka Exp $");
     30 
     31 #include <sys/param.h>
     32 #include <sys/lwp.h>
     33 #include <sys/systm.h>
     34 
     35 #include <rump/rump.h>
     36 
     37 #include "rump_private.h"
     38 
     39 int
     40 copyin(const void *uaddr, void *kaddr, size_t len)
     41 {
     42 
     43 	if (__predict_false(uaddr == NULL && len)) {
     44 		return EFAULT;
     45 	}
     46 
     47 	if (curproc->p_vmspace == &vmspace0) {
     48 		memcpy(kaddr, uaddr, len);
     49 	} else {
     50 		rumpuser_sp_copyin(uaddr, kaddr, len);
     51 	}
     52 	return 0;
     53 }
     54 
     55 int
     56 copyout(const void *kaddr, void *uaddr, size_t len)
     57 {
     58 
     59 	if (__predict_false(uaddr == NULL && len)) {
     60 		return EFAULT;
     61 	}
     62 
     63 	if (curproc->p_vmspace == &vmspace0) {
     64 		memcpy(uaddr, kaddr, len);
     65 	} else {
     66 		rumpuser_sp_copyout(kaddr, uaddr, len);
     67 	}
     68 	return 0;
     69 }
     70 
     71 int
     72 subyte(void *uaddr, int byte)
     73 {
     74 
     75 	if (curproc->p_vmspace == &vmspace0)
     76 		*(char *)uaddr = byte;
     77 	else
     78 		rumpuser_sp_copyout(&byte, uaddr, 1);
     79 	return 0;
     80 }
     81 
     82 int
     83 copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done)
     84 {
     85 	uint8_t *to = kdaddr;
     86 	const uint8_t *from = kfaddr;
     87 	size_t actlen = 0;
     88 
     89 	while (len-- > 0 && (*to++ = *from++) != 0)
     90 		actlen++;
     91 
     92 	if (len+1 == 0 && *(to-1) != 0)
     93 		return ENAMETOOLONG;
     94 
     95 	if (done)
     96 		*done = actlen+1; /* + '\0' */
     97 	return 0;
     98 }
     99 
    100 int
    101 copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done)
    102 {
    103 	uint8_t *to;
    104 	int rv;
    105 
    106 	if (len == 0)
    107 		return 0;
    108 
    109 	if (curproc->p_vmspace == &vmspace0)
    110 		return copystr(uaddr, kaddr, len, done);
    111 
    112 	if ((rv = rumpuser_sp_copyin(uaddr, kaddr, len)) != 0)
    113 		return rv;
    114 
    115 	/* figure out if we got a terminated string or not */
    116 	to = (uint8_t *)kaddr + (len-1);
    117 	while (to != kaddr) {
    118 		if (*to == 0)
    119 			goto found;
    120 		to--;
    121 	}
    122 	return ENAMETOOLONG;
    123 
    124  found:
    125 	if (done)
    126 		*done = strlen(kaddr)+1; /* includes termination */
    127 
    128 	return 0;
    129 }
    130 
    131 int
    132 copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done)
    133 {
    134 	size_t slen;
    135 
    136 	if (curproc->p_vmspace == &vmspace0)
    137 		return copystr(kaddr, uaddr, len, done);
    138 
    139 	slen = strlen(kaddr)+1;
    140 	if (slen > len)
    141 		return ENAMETOOLONG;
    142 
    143 	rumpuser_sp_copyout(kaddr, uaddr, slen);
    144 	if (done)
    145 		*done = slen;
    146 
    147 	return 0;
    148 }
    149 
    150 int
    151 kcopy(const void *src, void *dst, size_t len)
    152 {
    153 
    154 	memcpy(dst, src, len);
    155 	return 0;
    156 }
    157