1 /* User memory access */ 2 #include "qemu/osdep.h" 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 */ 10 abi_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 25 abi_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 39 /* Return the length of a string in target memory or -TARGET_EFAULT if 40 access error */ 41 abi_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; 53 len = qemu_strnlen((char *)ptr, max_len); 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 } 65