diff options
Diffstat (limited to 'include/qemu')
| -rw-r--r-- | include/qemu/bitops.h | 29 | ||||
| -rw-r--r-- | include/qemu/compiler.h | 51 | ||||
| -rw-r--r-- | include/qemu/coroutine.h | 6 | ||||
| -rw-r--r-- | include/qemu/int128.h | 10 | ||||
| -rw-r--r-- | include/qemu/lockable.h | 88 | ||||
| -rw-r--r-- | include/qemu/mmap-alloc.h | 16 | ||||
| -rw-r--r-- | include/qemu/osdep.h | 34 | ||||
| -rw-r--r-- | include/qemu/plugin.h | 1 | ||||
| -rw-r--r-- | include/qemu/sockets.h | 11 | ||||
| -rw-r--r-- | include/qemu/thread-posix.h | 14 | ||||
| -rw-r--r-- | include/qemu/thread-win32.h | 6 | ||||
| -rw-r--r-- | include/qemu/thread.h | 15 |
12 files changed, 155 insertions, 126 deletions
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h index a72f69fea8..03213ce952 100644 --- a/include/qemu/bitops.h +++ b/include/qemu/bitops.h @@ -292,6 +292,35 @@ static inline uint64_t ror64(uint64_t word, unsigned int shift) } /** + * hswap32 - swap 16-bit halfwords within a 32-bit value + * @h: value to swap + */ +static inline uint32_t hswap32(uint32_t h) +{ + return rol32(h, 16); +} + +/** + * hswap64 - swap 16-bit halfwords within a 64-bit value + * @h: value to swap + */ +static inline uint64_t hswap64(uint64_t h) +{ + uint64_t m = 0x0000ffff0000ffffull; + h = rol64(h, 32); + return ((h & m) << 16) | ((h >> 16) & m); +} + +/** + * wswap64 - swap 32-bit words within a 64-bit value + * @h: value to swap + */ +static inline uint64_t wswap64(uint64_t h) +{ + return rol64(h, 32); +} + +/** * extract32: * @value: the value to extract the bit field from * @start: the lowest bit in the bit field (numbered from 0) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 091c45248b..3baa5e3790 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -72,18 +72,7 @@ int:(x) ? -1 : 1; \ } -/* QEMU_BUILD_BUG_MSG() emits the message given if _Static_assert is - * supported; otherwise, it will be omitted from the compiler error - * message (but as it remains present in the source code, it can still - * be useful when debugging). */ -#if defined(CONFIG_STATIC_ASSERT) #define QEMU_BUILD_BUG_MSG(x, msg) _Static_assert(!(x), msg) -#elif defined(__COUNTER__) -#define QEMU_BUILD_BUG_MSG(x, msg) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \ - glue(qemu_build_bug_on__, __COUNTER__) __attribute__((unused)) -#else -#define QEMU_BUILD_BUG_MSG(x, msg) -#endif #define QEMU_BUILD_BUG_ON(x) QEMU_BUILD_BUG_MSG(x, "not expecting: " #x) @@ -173,46 +162,6 @@ #define QEMU_ALWAYS_INLINE #endif -/* Implement C11 _Generic via GCC builtins. Example: - * - * QEMU_GENERIC(x, (float, sinf), (long double, sinl), sin) (x) - * - * The first argument is the discriminator. The last is the default value. - * The middle ones are tuples in "(type, expansion)" format. - */ - -/* First, find out the number of generic cases. */ -#define QEMU_GENERIC(x, ...) \ - QEMU_GENERIC_(typeof(x), __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) - -/* There will be extra arguments, but they are not used. */ -#define QEMU_GENERIC_(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, count, ...) \ - QEMU_GENERIC##count(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) - -/* Two more helper macros, this time to extract items from a parenthesized - * list. - */ -#define QEMU_FIRST_(a, b) a -#define QEMU_SECOND_(a, b) b - -/* ... and a final one for the common part of the "recursion". */ -#define QEMU_GENERIC_IF(x, type_then, else_) \ - __builtin_choose_expr(__builtin_types_compatible_p(x, \ - QEMU_FIRST_ type_then), \ - QEMU_SECOND_ type_then, else_) - -/* CPP poor man's "recursion". */ -#define QEMU_GENERIC1(x, a0, ...) (a0) -#define QEMU_GENERIC2(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC1(x, __VA_ARGS__)) -#define QEMU_GENERIC3(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC2(x, __VA_ARGS__)) -#define QEMU_GENERIC4(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC3(x, __VA_ARGS__)) -#define QEMU_GENERIC5(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC4(x, __VA_ARGS__)) -#define QEMU_GENERIC6(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC5(x, __VA_ARGS__)) -#define QEMU_GENERIC7(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC6(x, __VA_ARGS__)) -#define QEMU_GENERIC8(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC7(x, __VA_ARGS__)) -#define QEMU_GENERIC9(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC8(x, __VA_ARGS__)) -#define QEMU_GENERIC10(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC9(x, __VA_ARGS__)) - /** * qemu_build_not_reached() * diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index 292e61aef0..4829ff373d 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -210,13 +210,15 @@ void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock); /** * Removes the next coroutine from the CoQueue, and wake it up. * Returns true if a coroutine was removed, false if the queue is empty. + * OK to run from coroutine and non-coroutine context. */ -bool coroutine_fn qemu_co_queue_next(CoQueue *queue); +bool qemu_co_queue_next(CoQueue *queue); /** * Empties the CoQueue; all coroutines are woken up. + * OK to run from coroutine and non-coroutine context. */ -void coroutine_fn qemu_co_queue_restart_all(CoQueue *queue); +void qemu_co_queue_restart_all(CoQueue *queue); /** * Removes the next coroutine from the CoQueue, and wake it up. Unlike diff --git a/include/qemu/int128.h b/include/qemu/int128.h index 52fc238421..64500385e3 100644 --- a/include/qemu/int128.h +++ b/include/qemu/int128.h @@ -11,6 +11,11 @@ static inline Int128 int128_make64(uint64_t a) return a; } +static inline Int128 int128_makes64(int64_t a) +{ + return a; +} + static inline Int128 int128_make128(uint64_t lo, uint64_t hi) { return (__uint128_t)hi << 64 | lo; @@ -167,6 +172,11 @@ static inline Int128 int128_make64(uint64_t a) return (Int128) { a, 0 }; } +static inline Int128 int128_makes64(int64_t a) +{ + return (Int128) { a, a >> 63 }; +} + static inline Int128 int128_make128(uint64_t lo, uint64_t hi) { return (Int128) { lo, hi }; diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h index b620023141..86db7cb04c 100644 --- a/include/qemu/lockable.h +++ b/include/qemu/lockable.h @@ -24,79 +24,71 @@ struct QemuLockable { QemuLockUnlockFunc *unlock; }; -/* This function gives an error if an invalid, non-NULL pointer type is passed - * to QEMU_MAKE_LOCKABLE. For optimized builds, we can rely on dead-code elimination - * from the compiler, and give the errors already at link time. - */ -#if defined(__OPTIMIZE__) && !defined(__SANITIZE_ADDRESS__) -void unknown_lock_type(void *); -#else -static inline void unknown_lock_type(void *unused) -{ - abort(); -} -#endif - static inline __attribute__((__always_inline__)) QemuLockable * qemu_make_lockable(void *x, QemuLockable *lockable) { - /* We cannot test this in a macro, otherwise we get compiler + /* + * We cannot test this in a macro, otherwise we get compiler * warnings like "the address of 'm' will always evaluate as 'true'". */ return x ? lockable : NULL; } -/* Auxiliary macros to simplify QEMU_MAKE_LOCABLE. */ -#define QEMU_LOCK_FUNC(x) ((QemuLockUnlockFunc *) \ - QEMU_GENERIC(x, \ - (QemuMutex *, qemu_mutex_lock), \ - (QemuRecMutex *, qemu_rec_mutex_lock), \ - (CoMutex *, qemu_co_mutex_lock), \ - (QemuSpin *, qemu_spin_lock), \ - unknown_lock_type)) - -#define QEMU_UNLOCK_FUNC(x) ((QemuLockUnlockFunc *) \ - QEMU_GENERIC(x, \ - (QemuMutex *, qemu_mutex_unlock), \ - (QemuRecMutex *, qemu_rec_mutex_unlock), \ - (CoMutex *, qemu_co_mutex_unlock), \ - (QemuSpin *, qemu_spin_unlock), \ - unknown_lock_type)) - -/* In C, compound literals have the lifetime of an automatic variable. +static inline __attribute__((__always_inline__)) QemuLockable * +qemu_null_lockable(void *x) +{ + if (x != NULL) { + qemu_build_not_reached(); + } + return NULL; +} + +/* + * In C, compound literals have the lifetime of an automatic variable. * In C++ it would be different, but then C++ wouldn't need QemuLockable * either... */ -#define QEMU_MAKE_LOCKABLE_(x) (&(QemuLockable) { \ - .object = (x), \ - .lock = QEMU_LOCK_FUNC(x), \ - .unlock = QEMU_UNLOCK_FUNC(x), \ +#define QML_OBJ_(x, name) (&(QemuLockable) { \ + .object = (x), \ + .lock = (QemuLockUnlockFunc *) qemu_ ## name ## _lock, \ + .unlock = (QemuLockUnlockFunc *) qemu_ ## name ## _unlock \ }) -/* QEMU_MAKE_LOCKABLE - Make a polymorphic QemuLockable +/** + * QEMU_MAKE_LOCKABLE - Make a polymorphic QemuLockable * - * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin). + * @x: a lock object (currently one of QemuMutex, QemuRecMutex, + * CoMutex, QemuSpin). * * Returns a QemuLockable object that can be passed around * to a function that can operate with locks of any kind, or * NULL if @x is %NULL. + * + * Note the special case for void *, so that we may pass "NULL". */ -#define QEMU_MAKE_LOCKABLE(x) \ - QEMU_GENERIC(x, \ - (QemuLockable *, (x)), \ - qemu_make_lockable((x), QEMU_MAKE_LOCKABLE_(x))) +#define QEMU_MAKE_LOCKABLE(x) \ + _Generic((x), QemuLockable *: (x), \ + void *: qemu_null_lockable(x), \ + QemuMutex *: qemu_make_lockable(x, QML_OBJ_(x, mutex)), \ + QemuRecMutex *: qemu_make_lockable(x, QML_OBJ_(x, rec_mutex)), \ + CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)), \ + QemuSpin *: qemu_make_lockable(x, QML_OBJ_(x, spin))) -/* QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable +/** + * QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable * - * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin). + * @x: a lock object (currently one of QemuMutex, QemuRecMutex, + * CoMutex, QemuSpin). * * Returns a QemuLockable object that can be passed around * to a function that can operate with locks of any kind. */ -#define QEMU_MAKE_LOCKABLE_NONNULL(x) \ - QEMU_GENERIC(x, \ - (QemuLockable *, (x)), \ - QEMU_MAKE_LOCKABLE_(x)) +#define QEMU_MAKE_LOCKABLE_NONNULL(x) \ + _Generic((x), QemuLockable *: (x), \ + QemuMutex *: QML_OBJ_(x, mutex), \ + QemuRecMutex *: QML_OBJ_(x, rec_mutex), \ + CoMutex *: QML_OBJ_(x, co_mutex), \ + QemuSpin *: QML_OBJ_(x, spin)) static inline void qemu_lockable_lock(QemuLockable *x) { diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h index 456ff87df1..90d0eee705 100644 --- a/include/qemu/mmap-alloc.h +++ b/include/qemu/mmap-alloc.h @@ -7,18 +7,22 @@ size_t qemu_fd_getpagesize(int fd); size_t qemu_mempath_getpagesize(const char *mem_path); /** - * qemu_ram_mmap: mmap the specified file or device. + * qemu_ram_mmap: mmap anonymous memory, the specified file or device. + * + * mmap() abstraction to map guest RAM, simplifying flag handling, taking + * care of alignment requirements and installing guard pages. * * Parameters: * @fd: the file or the device to mmap * @size: the number of bytes to be mmaped * @align: if not zero, specify the alignment of the starting mapping address; * otherwise, the alignment in use will be determined by QEMU. - * @readonly: true for a read-only mapping, false for read/write. - * @shared: map has RAM_SHARED flag. - * @is_pmem: map has RAM_PMEM flag. + * @qemu_map_flags: QEMU_MAP_* flags * @map_offset: map starts at offset of map_offset from the start of fd * + * Internally, MAP_PRIVATE, MAP_ANONYMOUS and MAP_SHARED_VALIDATE are set + * implicitly based on other parameters. + * * Return: * On success, return a pointer to the mapped area. * On failure, return MAP_FAILED. @@ -26,9 +30,7 @@ size_t qemu_mempath_getpagesize(const char *mem_path); void *qemu_ram_mmap(int fd, size_t size, size_t align, - bool readonly, - bool shared, - bool is_pmem, + uint32_t qemu_map_flags, off_t map_offset); void qemu_ram_munmap(int fd, void *ptr, size_t size); diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 236a045671..0a54bf7be8 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -195,6 +195,9 @@ extern "C" { #ifndef MAP_FIXED_NOREPLACE #define MAP_FIXED_NOREPLACE 0 #endif +#ifndef MAP_NORESERVE +#define MAP_NORESERVE 0 +#endif #ifndef ENOMEDIUM #define ENOMEDIUM ENODEV #endif @@ -362,10 +365,35 @@ extern "C" { int qemu_daemon(int nochdir, int noclose); void *qemu_try_memalign(size_t alignment, size_t size); void *qemu_memalign(size_t alignment, size_t size); -void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared); +void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared, + bool noreserve); void qemu_vfree(void *ptr); void qemu_anon_ram_free(void *ptr, size_t size); +/* + * Abstraction of PROT_ and MAP_ flags as passed to mmap(), for example, + * consumed by qemu_ram_mmap(). + */ + +/* Map PROT_READ instead of PROT_READ | PROT_WRITE. */ +#define QEMU_MAP_READONLY (1 << 0) + +/* Use MAP_SHARED instead of MAP_PRIVATE. */ +#define QEMU_MAP_SHARED (1 << 1) + +/* + * Use MAP_SYNC | MAP_SHARED_VALIDATE if supported. Ignored without + * QEMU_MAP_SHARED. If mapping fails, warn and fallback to !QEMU_MAP_SYNC. + */ +#define QEMU_MAP_SYNC (1 << 2) + +/* + * Use MAP_NORESERVE to skip reservation of swap space (or huge pages if + * applicable). Bail out if not supported/effective. + */ +#define QEMU_MAP_NORESERVE (1 << 3) + + #define QEMU_MADV_INVALID -1 #if defined(CONFIG_MADVISE) @@ -410,7 +438,7 @@ void qemu_anon_ram_free(void *ptr, size_t size); #ifdef MADV_REMOVE #define QEMU_MADV_REMOVE MADV_REMOVE #else -#define QEMU_MADV_REMOVE QEMU_MADV_INVALID +#define QEMU_MADV_REMOVE QEMU_MADV_DONTNEED #endif #elif defined(CONFIG_POSIX_MADVISE) @@ -424,7 +452,7 @@ void qemu_anon_ram_free(void *ptr, size_t size); #define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID #define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID #define QEMU_MADV_NOHUGEPAGE QEMU_MADV_INVALID -#define QEMU_MADV_REMOVE QEMU_MADV_INVALID +#define QEMU_MADV_REMOVE QEMU_MADV_DONTNEED #else /* no-op */ diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index c5a79a89f0..0fefbc6084 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -79,7 +79,6 @@ enum plugin_dyn_cb_subtype { struct qemu_plugin_dyn_cb { union qemu_plugin_cb_sig f; void *userp; - unsigned tcg_flags; enum plugin_dyn_cb_subtype type; /* @rw applies to mem callbacks only (both regular and inline) */ enum qemu_plugin_mem_rw rw; diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 7d1f813576..0c34bf2398 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -111,4 +111,15 @@ SocketAddress *socket_remote_address(int fd, Error **errp); */ SocketAddress *socket_address_flatten(SocketAddressLegacy *addr); +/** + * socket_address_parse_named_fd: + * + * Modify @addr, replacing a named fd by its corresponding number. + * Needed for callers that plan to pass @addr to a context where the + * current monitor is not available. + * + * Return 0 on success. + */ +int socket_address_parse_named_fd(SocketAddress *addr, Error **errp); + #endif /* QEMU_SOCKETS_H */ diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h index c903525062..b792e6ef37 100644 --- a/include/qemu/thread-posix.h +++ b/include/qemu/thread-posix.h @@ -4,12 +4,6 @@ #include <pthread.h> #include <semaphore.h> -typedef QemuMutex QemuRecMutex; -#define qemu_rec_mutex_destroy qemu_mutex_destroy -#define qemu_rec_mutex_lock_impl qemu_mutex_lock_impl -#define qemu_rec_mutex_trylock_impl qemu_mutex_trylock_impl -#define qemu_rec_mutex_unlock qemu_mutex_unlock - struct QemuMutex { pthread_mutex_t lock; #ifdef CONFIG_DEBUG_MUTEX @@ -19,6 +13,14 @@ struct QemuMutex { bool initialized; }; +/* + * QemuRecMutex cannot be a typedef of QemuMutex lest we have two + * compatible cases in _Generic. See qemu/lockable.h. + */ +typedef struct QemuRecMutex { + QemuMutex m; +} QemuRecMutex; + struct QemuCond { pthread_cond_t cond; bool initialized; diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h index d0a1a9597e..d95af4498f 100644 --- a/include/qemu/thread-win32.h +++ b/include/qemu/thread-win32.h @@ -18,12 +18,6 @@ struct QemuRecMutex { bool initialized; }; -void qemu_rec_mutex_destroy(QemuRecMutex *mutex); -void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line); -int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, - int line); -void qemu_rec_mutex_unlock(QemuRecMutex *mutex); - struct QemuCond { CONDITION_VARIABLE var; bool initialized; diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 5435763184..460568d67d 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -28,6 +28,12 @@ int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line); void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line); void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line); +void qemu_rec_mutex_init(QemuRecMutex *mutex); +void qemu_rec_mutex_destroy(QemuRecMutex *mutex); +void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line); +int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line); +void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line); + typedef void (*QemuMutexLockFunc)(QemuMutex *m, const char *f, int l); typedef int (*QemuMutexTrylockFunc)(QemuMutex *m, const char *f, int l); typedef void (*QemuRecMutexLockFunc)(QemuRecMutex *m, const char *f, int l); @@ -104,6 +110,9 @@ extern QemuCondTimedWaitFunc qemu_cond_timedwait_func; #define qemu_mutex_unlock(mutex) \ qemu_mutex_unlock_impl(mutex, __FILE__, __LINE__) +#define qemu_rec_mutex_unlock(mutex) \ + qemu_rec_mutex_unlock_impl(mutex, __FILE__, __LINE__) + static inline void (qemu_mutex_lock)(QemuMutex *mutex) { qemu_mutex_lock(mutex); @@ -129,8 +138,10 @@ static inline int (qemu_rec_mutex_trylock)(QemuRecMutex *mutex) return qemu_rec_mutex_trylock(mutex); } -/* Prototypes for other functions are in thread-posix.h/thread-win32.h. */ -void qemu_rec_mutex_init(QemuRecMutex *mutex); +static inline void (qemu_rec_mutex_unlock)(QemuRecMutex *mutex) +{ + qemu_rec_mutex_unlock(mutex); +} void qemu_cond_init(QemuCond *cond); void qemu_cond_destroy(QemuCond *cond); |