uaccess.c 1.7 KB

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