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