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