]> git.proxmox.com Git - mirror_qemu.git/blame - bsd-user/uaccess.c
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
[mirror_qemu.git] / bsd-user / uaccess.c
CommitLineData
84778508 1/* User memory access */
2231197c 2#include "qemu/osdep.h"
84778508
BS
3
4#include "qemu.h"
5
6/* copy_from_user() and copy_to_user() are usually used to copy data
7 * buffers between the target and host. These internally perform
8 * locking/unlocking of the memory.
9 */
10abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
11{
12 abi_long ret = 0;
13 void *ghptr;
14
15 if ((ghptr = lock_user(VERIFY_READ, gaddr, len, 1))) {
16 memcpy(hptr, ghptr, len);
17 unlock_user(ghptr, gaddr, 0);
18 } else
19 ret = -TARGET_EFAULT;
20
21 return ret;
22}
23
24
25abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
26{
27 abi_long ret = 0;
28 void *ghptr;
29
30 if ((ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0))) {
31 memcpy(ghptr, hptr, len);
32 unlock_user(ghptr, gaddr, len);
33 } else
34 ret = -TARGET_EFAULT;
35
36 return ret;
37}
38
84778508
BS
39/* Return the length of a string in target memory or -TARGET_EFAULT if
40 access error */
41abi_long target_strlen(abi_ulong guest_addr1)
42{
43 uint8_t *ptr;
44 abi_ulong guest_addr;
45 int max_len, len;
46
47 guest_addr = guest_addr1;
48 for(;;) {
49 max_len = TARGET_PAGE_SIZE - (guest_addr & ~TARGET_PAGE_MASK);
50 ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
51 if (!ptr)
52 return -TARGET_EFAULT;
fff2a02f 53 len = qemu_strnlen((char *)ptr, max_len);
84778508
BS
54 unlock_user(ptr, guest_addr, 0);
55 guest_addr += len;
56 /* we don't allow wrapping or integer overflow */
57 if (guest_addr == 0 ||
58 (guest_addr - guest_addr1) > 0x7fffffff)
59 return -TARGET_EFAULT;
60 if (len != max_len)
61 break;
62 }
63 return guest_addr - guest_addr1;
64}