
* Update to QEMU v9.0.0 --------- Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Fabiano Rosas <farosas@suse.de> Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Cédric Le Goater <clg@redhat.com> Signed-off-by: Zheyu Ma <zheyuma97@gmail.com> Signed-off-by: Ido Plat <ido.plat@ibm.com> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Signed-off-by: David Hildenbrand <david@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> Signed-off-by: Gregory Price <gregory.price@memverge.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Lorenz Brun <lorenz@brun.one> Signed-off-by: Yao Xingtao <yaoxt.fnst@fujitsu.com> Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr> Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Signed-off-by: Igor Mammedov <imammedo@redhat.com> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Sven Schnelle <svens@stackframe.org> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Helge Deller <deller@gmx.de> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Benjamin Gray <bgray@linux.ibm.com> Signed-off-by: Avihai Horon <avihaih@nvidia.com> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> Signed-off-by: Joonas Kankaala <joonas.a.kankaala@gmail.com> Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> Signed-off-by: Stefan Weil <sw@weilnetz.de> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Glenn Miles <milesg@linux.ibm.com> Signed-off-by: Oleg Sviridov <oleg.sviridov@red-soft.ru> Signed-off-by: Artem Chernyshev <artem.chernyshev@red-soft.ru> Signed-off-by: Yajun Wu <yajunw@nvidia.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Pierre-Clément Tosi <ptosi@google.com> Signed-off-by: Lei Wang <lei4.wang@intel.com> Signed-off-by: Wei Wang <wei.w.wang@intel.com> Signed-off-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Signed-off-by: Wafer <wafer@jaguarmicro.com> Signed-off-by: Yuxue Liu <yuxue.liu@jaguarmicro.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com> Signed-off-by: Zack Buhman <zack@buhman.org> Signed-off-by: Keith Packard <keithp@keithp.com> Signed-off-by: Yuquan Wang wangyuquan1236@phytium.com.cn Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> Signed-off-by: Cindy Lu <lulu@redhat.com> Co-authored-by: Peter Maydell <peter.maydell@linaro.org> Co-authored-by: Fabiano Rosas <farosas@suse.de> Co-authored-by: Peter Xu <peterx@redhat.com> Co-authored-by: Thomas Huth <thuth@redhat.com> Co-authored-by: Cédric Le Goater <clg@redhat.com> Co-authored-by: Zheyu Ma <zheyuma97@gmail.com> Co-authored-by: Ido Plat <ido.plat@ibm.com> Co-authored-by: Ilya Leoshkevich <iii@linux.ibm.com> Co-authored-by: Markus Armbruster <armbru@redhat.com> Co-authored-by: Marc-André Lureau <marcandre.lureau@redhat.com> Co-authored-by: Paolo Bonzini <pbonzini@redhat.com> Co-authored-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Co-authored-by: David Hildenbrand <david@redhat.com> Co-authored-by: Kevin Wolf <kwolf@redhat.com> Co-authored-by: Stefan Reiter <s.reiter@proxmox.com> Co-authored-by: Fiona Ebner <f.ebner@proxmox.com> Co-authored-by: Gregory Price <gregory.price@memverge.com> Co-authored-by: Lorenz Brun <lorenz@brun.one> Co-authored-by: Yao Xingtao <yaoxt.fnst@fujitsu.com> Co-authored-by: Philippe Mathieu-Daudé <philmd@linaro.org> Co-authored-by: Arnaud Minier <arnaud.minier@telecom-paris.fr> Co-authored-by: BALATON Zoltan <balaton@eik.bme.hu> Co-authored-by: Igor Mammedov <imammedo@redhat.com> Co-authored-by: Akihiko Odaki <akihiko.odaki@daynix.com> Co-authored-by: Richard Henderson <richard.henderson@linaro.org> Co-authored-by: Sven Schnelle <svens@stackframe.org> Co-authored-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Co-authored-by: Helge Deller <deller@kernel.org> Co-authored-by: Harsh Prateek Bora <harshpb@linux.ibm.com> Co-authored-by: Benjamin Gray <bgray@linux.ibm.com> Co-authored-by: Nicholas Piggin <npiggin@gmail.com> Co-authored-by: Avihai Horon <avihaih@nvidia.com> Co-authored-by: Michael Tokarev <mjt@tls.msk.ru> Co-authored-by: Joonas Kankaala <joonas.a.kankaala@gmail.com> Co-authored-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> Co-authored-by: Stefan Weil <sw@weilnetz.de> Co-authored-by: Dayu Liu <liu.dayu@zte.com.cn> Co-authored-by: Zhao Liu <zhao1.liu@intel.com> Co-authored-by: Glenn Miles <milesg@linux.vnet.ibm.com> Co-authored-by: Artem Chernyshev <artem.chernyshev@red-soft.ru> Co-authored-by: Yajun Wu <yajunw@nvidia.com> Co-authored-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Co-authored-by: Pierre-Clément Tosi <ptosi@google.com> Co-authored-by: Wei Wang <wei.w.wang@intel.com> Co-authored-by: Martin Hundebøll <martin@geanix.com> Co-authored-by: Michael S. Tsirkin <mst@redhat.com> Co-authored-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Co-authored-by: Wafer <wafer@jaguarmicro.com> Co-authored-by: lyx634449800 <yuxue.liu@jaguarmicro.com> Co-authored-by: Gerd Hoffmann <kraxel@redhat.com> Co-authored-by: Nguyen Dinh Phi <phind.uet@gmail.com> Co-authored-by: Zack Buhman <zack@buhman.org> Co-authored-by: Keith Packard <keithp@keithp.com> Co-authored-by: Yuquan Wang <wangyuquan1236@phytium.com.cn> Co-authored-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> Co-authored-by: Cindy Lu <lulu@redhat.com>
359 lines
13 KiB
C
359 lines
13 KiB
C
#ifndef QEMU_H
|
|
#define QEMU_H
|
|
|
|
#include "cpu.h"
|
|
#include "exec/cpu_ldst.h"
|
|
|
|
#undef DEBUG_REMAP
|
|
|
|
#include "exec/user/abitypes.h"
|
|
|
|
#include "syscall_defs.h"
|
|
#include "target_syscall.h"
|
|
|
|
/*
|
|
* This is the size of the host kernel's sigset_t, needed where we make
|
|
* direct system calls that take a sigset_t pointer and a size.
|
|
*/
|
|
#define SIGSET_T_SIZE (_NSIG / 8)
|
|
|
|
/*
|
|
* This struct is used to hold certain information about the image.
|
|
* Basically, it replicates in user space what would be certain
|
|
* task_struct fields in the kernel
|
|
*/
|
|
struct image_info {
|
|
abi_ulong load_bias;
|
|
abi_ulong load_addr;
|
|
abi_ulong start_code;
|
|
abi_ulong end_code;
|
|
abi_ulong start_data;
|
|
abi_ulong end_data;
|
|
abi_ulong brk;
|
|
abi_ulong start_stack;
|
|
abi_ulong stack_limit;
|
|
abi_ulong vdso;
|
|
abi_ulong entry;
|
|
abi_ulong code_offset;
|
|
abi_ulong data_offset;
|
|
abi_ulong saved_auxv;
|
|
abi_ulong auxv_len;
|
|
abi_ulong argc;
|
|
abi_ulong argv;
|
|
abi_ulong envc;
|
|
abi_ulong envp;
|
|
abi_ulong file_string;
|
|
uint32_t elf_flags;
|
|
int personality;
|
|
abi_ulong alignment;
|
|
bool exec_stack;
|
|
|
|
/* Generic semihosting knows about these pointers. */
|
|
abi_ulong arg_strings; /* strings for argv */
|
|
abi_ulong env_strings; /* strings for envp; ends arg_strings */
|
|
|
|
/* The fields below are used in FDPIC mode. */
|
|
abi_ulong loadmap_addr;
|
|
uint16_t nsegs;
|
|
void *loadsegs;
|
|
abi_ulong pt_dynamic_addr;
|
|
abi_ulong interpreter_loadmap_addr;
|
|
abi_ulong interpreter_pt_dynamic_addr;
|
|
struct image_info *other_info;
|
|
|
|
/* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */
|
|
uint32_t note_flags;
|
|
|
|
#ifdef TARGET_MIPS
|
|
int fp_abi;
|
|
int interp_fp_abi;
|
|
#endif
|
|
};
|
|
|
|
#ifdef TARGET_I386
|
|
/* Information about the current linux thread */
|
|
struct vm86_saved_state {
|
|
uint32_t eax; /* return code */
|
|
uint32_t ebx;
|
|
uint32_t ecx;
|
|
uint32_t edx;
|
|
uint32_t esi;
|
|
uint32_t edi;
|
|
uint32_t ebp;
|
|
uint32_t esp;
|
|
uint32_t eflags;
|
|
uint32_t eip;
|
|
uint16_t cs, ss, ds, es, fs, gs;
|
|
};
|
|
#endif
|
|
|
|
#if defined(TARGET_ARM) && defined(TARGET_ABI32)
|
|
/* FPU emulator */
|
|
#include "nwfpe/fpa11.h"
|
|
#endif
|
|
|
|
struct emulated_sigtable {
|
|
int pending; /* true if signal is pending */
|
|
target_siginfo_t info;
|
|
};
|
|
|
|
typedef struct TaskState {
|
|
pid_t ts_tid; /* tid (or pid) of this task */
|
|
#ifdef TARGET_ARM
|
|
# ifdef TARGET_ABI32
|
|
/* FPA state */
|
|
FPA11 fpa;
|
|
# endif
|
|
#endif
|
|
#if defined(TARGET_ARM) || defined(TARGET_RISCV)
|
|
int swi_errno;
|
|
#endif
|
|
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
|
|
abi_ulong target_v86;
|
|
struct vm86_saved_state vm86_saved_regs;
|
|
struct target_vm86plus_struct vm86plus;
|
|
uint32_t v86flags;
|
|
uint32_t v86mask;
|
|
#endif
|
|
abi_ulong child_tidptr;
|
|
#ifdef TARGET_M68K
|
|
abi_ulong tp_value;
|
|
#endif
|
|
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_RISCV)
|
|
/* Extra fields for semihosted binaries. */
|
|
abi_ulong heap_base;
|
|
abi_ulong heap_limit;
|
|
#endif
|
|
abi_ulong stack_base;
|
|
int used; /* non zero if used */
|
|
struct image_info *info;
|
|
struct linux_binprm *bprm;
|
|
|
|
struct emulated_sigtable sync_signal;
|
|
struct emulated_sigtable sigtab[TARGET_NSIG];
|
|
/*
|
|
* This thread's signal mask, as requested by the guest program.
|
|
* The actual signal mask of this thread may differ:
|
|
* + we don't let SIGSEGV and SIGBUS be blocked while running guest code
|
|
* + sometimes we block all signals to avoid races
|
|
*/
|
|
sigset_t signal_mask;
|
|
/*
|
|
* The signal mask imposed by a guest sigsuspend syscall, if we are
|
|
* currently in the middle of such a syscall
|
|
*/
|
|
sigset_t sigsuspend_mask;
|
|
/* Nonzero if we're leaving a sigsuspend and sigsuspend_mask is valid. */
|
|
int in_sigsuspend;
|
|
|
|
/*
|
|
* Nonzero if process_pending_signals() needs to do something (either
|
|
* handle a pending signal or unblock signals).
|
|
* This flag is written from a signal handler so should be accessed via
|
|
* the qatomic_read() and qatomic_set() functions. (It is not accessed
|
|
* from multiple threads.)
|
|
*/
|
|
int signal_pending;
|
|
|
|
/* This thread's sigaltstack, if it has one */
|
|
struct target_sigaltstack sigaltstack_used;
|
|
|
|
/* Start time of task after system boot in clock ticks */
|
|
uint64_t start_boottime;
|
|
} TaskState;
|
|
|
|
static inline TaskState *get_task_state(CPUState *cs)
|
|
{
|
|
return cs->opaque;
|
|
}
|
|
|
|
abi_long do_brk(abi_ulong new_brk);
|
|
int do_guest_openat(CPUArchState *cpu_env, int dirfd, const char *pathname,
|
|
int flags, mode_t mode, bool safe);
|
|
ssize_t do_guest_readlink(const char *pathname, char *buf, size_t bufsiz);
|
|
|
|
/* user access */
|
|
|
|
#define VERIFY_NONE 0
|
|
#define VERIFY_READ PAGE_READ
|
|
#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
|
|
|
|
static inline bool access_ok_untagged(int type, abi_ulong addr, abi_ulong size)
|
|
{
|
|
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);
|
|
}
|
|
|
|
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.
|
|
These are usually used to access struct data members once the struct has
|
|
been locked - usually with lock_user_struct. */
|
|
|
|
/*
|
|
* Tricky points:
|
|
* - Use __builtin_choose_expr to avoid type promotion from ?:,
|
|
* - Invalid sizes result in a compile time error stemming from
|
|
* the fact that abort has no parameters.
|
|
* - It's easier to use the endian-specific unaligned load/store
|
|
* functions than host-endian unaligned load/store plus tswapN.
|
|
* - The pragmas are necessary only to silence a clang false-positive
|
|
* warning: see https://bugs.llvm.org/show_bug.cgi?id=39113 .
|
|
* - gcc has bugs in its _Pragma() support in some versions, eg
|
|
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83256 -- so we only
|
|
* include the warning-suppression pragmas for clang
|
|
*/
|
|
#if defined(__clang__) && __has_warning("-Waddress-of-packed-member")
|
|
#define PRAGMA_DISABLE_PACKED_WARNING \
|
|
_Pragma("GCC diagnostic push"); \
|
|
_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"")
|
|
|
|
#define PRAGMA_REENABLE_PACKED_WARNING \
|
|
_Pragma("GCC diagnostic pop")
|
|
|
|
#else
|
|
#define PRAGMA_DISABLE_PACKED_WARNING
|
|
#define PRAGMA_REENABLE_PACKED_WARNING
|
|
#endif
|
|
|
|
#define __put_user_e(x, hptr, e) \
|
|
do { \
|
|
PRAGMA_DISABLE_PACKED_WARNING; \
|
|
(__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \
|
|
__builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \
|
|
__builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \
|
|
__builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \
|
|
((hptr), (x)), (void)0); \
|
|
PRAGMA_REENABLE_PACKED_WARNING; \
|
|
} while (0)
|
|
|
|
#define __get_user_e(x, hptr, e) \
|
|
do { \
|
|
PRAGMA_DISABLE_PACKED_WARNING; \
|
|
((x) = (typeof(*hptr))( \
|
|
__builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \
|
|
__builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \
|
|
__builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \
|
|
__builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \
|
|
(hptr)), (void)0); \
|
|
PRAGMA_REENABLE_PACKED_WARNING; \
|
|
} while (0)
|
|
|
|
|
|
#if TARGET_BIG_ENDIAN
|
|
# define __put_user(x, hptr) __put_user_e(x, hptr, be)
|
|
# define __get_user(x, hptr) __get_user_e(x, hptr, be)
|
|
#else
|
|
# define __put_user(x, hptr) __put_user_e(x, hptr, le)
|
|
# define __get_user(x, hptr) __get_user_e(x, hptr, le)
|
|
#endif
|
|
|
|
/* put_user()/get_user() take a guest address and check access */
|
|
/* These are usually used to access an atomic data type, such as an int,
|
|
* that has been passed by address. These internally perform locking
|
|
* and unlocking on the data type.
|
|
*/
|
|
#define put_user(x, gaddr, target_type) \
|
|
({ \
|
|
abi_ulong __gaddr = (gaddr); \
|
|
target_type *__hptr; \
|
|
abi_long __ret = 0; \
|
|
if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
|
|
__put_user((x), __hptr); \
|
|
unlock_user(__hptr, __gaddr, sizeof(target_type)); \
|
|
} else \
|
|
__ret = -TARGET_EFAULT; \
|
|
__ret; \
|
|
})
|
|
|
|
#define get_user(x, gaddr, target_type) \
|
|
({ \
|
|
abi_ulong __gaddr = (gaddr); \
|
|
target_type *__hptr; \
|
|
abi_long __ret = 0; \
|
|
if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
|
|
__get_user((x), __hptr); \
|
|
unlock_user(__hptr, __gaddr, 0); \
|
|
} else { \
|
|
/* avoid warning */ \
|
|
(x) = 0; \
|
|
__ret = -TARGET_EFAULT; \
|
|
} \
|
|
__ret; \
|
|
})
|
|
|
|
#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
|
|
#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
|
|
#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
|
|
#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
|
|
#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
|
|
#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
|
|
#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
|
|
#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
|
|
#define put_user_u8(x, gaddr) put_user((x), (gaddr), uint8_t)
|
|
#define put_user_s8(x, gaddr) put_user((x), (gaddr), int8_t)
|
|
|
|
#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
|
|
#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
|
|
#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
|
|
#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
|
|
#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
|
|
#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
|
|
#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
|
|
#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
|
|
#define get_user_u8(x, gaddr) get_user((x), (gaddr), uint8_t)
|
|
#define get_user_s8(x, gaddr) get_user((x), (gaddr), int8_t)
|
|
|
|
/* copy_from_user() and copy_to_user() are usually used to copy data
|
|
* buffers between the target and host. These internally perform
|
|
* locking/unlocking of the memory.
|
|
*/
|
|
int copy_from_user(void *hptr, abi_ulong gaddr, ssize_t len);
|
|
int copy_to_user(abi_ulong gaddr, void *hptr, ssize_t len);
|
|
|
|
/* Functions for accessing guest memory. The tget and tput functions
|
|
read/write single values, byteswapping as necessary. The lock_user function
|
|
gets a pointer to a contiguous area of guest memory, but does not perform
|
|
any byteswapping. lock_user may return either a pointer to the guest
|
|
memory, or a temporary buffer. */
|
|
|
|
/* 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. */
|
|
void *lock_user(int type, abi_ulong guest_addr, ssize_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. */
|
|
#ifndef DEBUG_REMAP
|
|
static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
|
|
ssize_t len)
|
|
{
|
|
/* no-op */
|
|
}
|
|
#else
|
|
void unlock_user(void *host_ptr, abi_ulong guest_addr, ssize_t len);
|
|
#endif
|
|
|
|
/* Return the length of a string in target memory or -TARGET_EFAULT if
|
|
access error. */
|
|
ssize_t target_strlen(abi_ulong gaddr);
|
|
|
|
/* Like lock_user but for null terminated strings. */
|
|
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) \
|
|
(host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
|
|
#define unlock_user_struct(host_ptr, guest_addr, copy) \
|
|
unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
|
|
|
|
#endif /* QEMU_H */
|