diff options
Diffstat (limited to 'linux-user/qemu.h')
| -rw-r--r-- | linux-user/qemu.h | 76 |
1 files changed, 25 insertions, 51 deletions
diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 17aa992165..d25a5dafc0 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -7,8 +7,6 @@ #include "exec/cpu_ldst.h" #undef DEBUG_REMAP -#ifdef DEBUG_REMAP -#endif /* DEBUG_REMAP */ #include "exec/user/abitypes.h" @@ -488,15 +486,23 @@ extern unsigned long guest_stack_size; /* user access */ -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 /* implies read access */ +#define VERIFY_READ PAGE_READ +#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE) -static inline int access_ok(int type, abi_ulong addr, abi_ulong size) +static inline bool access_ok_untagged(int type, abi_ulong addr, abi_ulong size) { - return guest_addr_valid(addr) && - (size == 0 || guest_addr_valid(addr + size - 1)) && - page_check_range((target_ulong)addr, size, - (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0; + if (size == 0 + ? !guest_addr_valid_untagged(addr) + : !guest_range_valid_untagged(addr, size)) { + return false; + } + return page_check_range((target_ulong)addr, size, type) == 0; +} + +static inline bool access_ok(CPUState *cpu, int type, + abi_ulong addr, abi_ulong size) +{ + return access_ok_untagged(type, cpu_untagged_addr(cpu, addr), size); } /* NOTE __get_user and __put_user use host pointers and don't check access. @@ -621,8 +627,8 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size) * buffers between the target and host. These internally perform * locking/unlocking of the memory. */ -abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len); -abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len); +int copy_from_user(void *hptr, abi_ulong gaddr, size_t len); +int copy_to_user(abi_ulong gaddr, void *hptr, size_t len); /* Functions for accessing guest memory. The tget and tput functions read/write single values, byteswapping as necessary. The lock_user function @@ -632,56 +638,24 @@ abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len); /* Lock an area of guest memory into the host. If copy is true then the host area will have the same contents as the guest. */ -static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy) -{ - if (!access_ok(type, guest_addr, len)) - return NULL; -#ifdef DEBUG_REMAP - { - void *addr; - addr = g_malloc(len); - if (copy) - memcpy(addr, g2h(guest_addr), len); - else - memset(addr, 0, len); - return addr; - } -#else - return g2h(guest_addr); -#endif -} +void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy); /* Unlock an area of guest memory. The first LEN bytes must be flushed back to guest memory. host_ptr = NULL is explicitly allowed and does nothing. */ -static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, - long len) -{ - -#ifdef DEBUG_REMAP - if (!host_ptr) - return; - if (host_ptr == g2h(guest_addr)) - return; - if (len > 0) - memcpy(g2h(guest_addr), host_ptr, len); - g_free(host_ptr); +#ifndef DEBUG_REMAP +static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t len) +{ } +#else +void unlock_user(void *host_ptr, abi_ulong guest_addr, long len); #endif -} /* Return the length of a string in target memory or -TARGET_EFAULT if access error. */ -abi_long target_strlen(abi_ulong gaddr); +ssize_t target_strlen(abi_ulong gaddr); /* Like lock_user but for null terminated strings. */ -static inline void *lock_user_string(abi_ulong guest_addr) -{ - abi_long len; - len = target_strlen(guest_addr); - if (len < 0) - return NULL; - return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1); -} +void *lock_user_string(abi_ulong guest_addr); /* Helper macros for locking/unlocking a target struct. */ #define lock_user_struct(type, host_ptr, guest_addr, copy) \ |