diff options
Diffstat (limited to 'include')
69 files changed, 697 insertions, 331 deletions
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h index 5449b6d742..cf5e8bde1c 100644 --- a/include/block/aio-wait.h +++ b/include/block/aio-wait.h @@ -63,9 +63,6 @@ extern AioWait global_aio_wait; * @ctx: the aio context, or NULL if multiple aio contexts (for which the * caller does not hold a lock) are involved in the polling condition. * @cond: wait while this conditional expression is true - * @unlock: whether to unlock and then lock again @ctx. This applies - * only when waiting for another AioContext from the main loop. - * Otherwise it's ignored. * * Wait while a condition is true. Use this to implement synchronous * operations that require event loop activity. @@ -78,7 +75,7 @@ extern AioWait global_aio_wait; * wait on conditions between two IOThreads since that could lead to deadlock, * go via the main loop instead. */ -#define AIO_WAIT_WHILE_INTERNAL(ctx, cond, unlock) ({ \ +#define AIO_WAIT_WHILE_INTERNAL(ctx, cond) ({ \ bool waited_ = false; \ AioWait *wait_ = &global_aio_wait; \ AioContext *ctx_ = (ctx); \ @@ -95,13 +92,7 @@ extern AioWait global_aio_wait; assert(qemu_get_current_aio_context() == \ qemu_get_aio_context()); \ while ((cond)) { \ - if (unlock && ctx_) { \ - aio_context_release(ctx_); \ - } \ aio_poll(qemu_get_aio_context(), true); \ - if (unlock && ctx_) { \ - aio_context_acquire(ctx_); \ - } \ waited_ = true; \ } \ } \ @@ -109,10 +100,11 @@ extern AioWait global_aio_wait; waited_; }) #define AIO_WAIT_WHILE(ctx, cond) \ - AIO_WAIT_WHILE_INTERNAL(ctx, cond, true) + AIO_WAIT_WHILE_INTERNAL(ctx, cond) +/* TODO replace this with AIO_WAIT_WHILE() in a future patch */ #define AIO_WAIT_WHILE_UNLOCKED(ctx, cond) \ - AIO_WAIT_WHILE_INTERNAL(ctx, cond, false) + AIO_WAIT_WHILE_INTERNAL(ctx, cond) /** * aio_wait_kick: @@ -151,7 +143,7 @@ static inline bool in_aio_context_home_thread(AioContext *ctx) } if (ctx == qemu_get_aio_context()) { - return qemu_mutex_iothread_locked(); + return bql_locked(); } else { return false; } diff --git a/include/block/aio.h b/include/block/aio.h index f08b358077..c802a392e5 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -278,23 +278,6 @@ void aio_context_ref(AioContext *ctx); */ void aio_context_unref(AioContext *ctx); -/* Take ownership of the AioContext. If the AioContext will be shared between - * threads, and a thread does not want to be interrupted, it will have to - * take ownership around calls to aio_poll(). Otherwise, aio_poll() - * automatically takes care of calling aio_context_acquire and - * aio_context_release. - * - * Note that this is separate from bdrv_drained_begin/bdrv_drained_end. A - * thread still has to call those to avoid being interrupted by the guest. - * - * Bottom halves, timers and callbacks can be created or removed without - * acquiring the AioContext. - */ -void aio_context_acquire(AioContext *ctx); - -/* Relinquish ownership of the AioContext. */ -void aio_context_release(AioContext *ctx); - /** * aio_bh_schedule_oneshot_full: Allocate a new bottom half structure that will * run only once and as soon as possible. @@ -716,8 +699,7 @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns, * @max_batch: maximum number of requests in a batch, 0 means that the * engine will use its default */ -void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch, - Error **errp); +void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch); /** * aio_context_set_thread_pool_params: diff --git a/include/block/block-common.h b/include/block/block-common.h index d7599564db..a846023a09 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -70,9 +70,6 @@ * automatically takes the graph rdlock when calling the wrapped function. In * the same way, no_co_wrapper_bdrv_wrlock functions automatically take the * graph wrlock. - * - * If the first parameter of the function is a BlockDriverState, BdrvChild or - * BlockBackend pointer, the AioContext lock for it is taken in the wrapper. */ #define no_co_wrapper #define no_co_wrapper_bdrv_rdlock diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 6b21fbc73f..4ec0b217f0 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -31,11 +31,10 @@ /* * Global state (GS) API. These functions run under the BQL. * - * If a function modifies the graph, it also uses drain and/or - * aio_context_acquire/release to be sure it has unique access. - * aio_context locking is needed together with BQL because of - * the thread-safe I/O API that concurrently runs and accesses - * the graph without the BQL. + * If a function modifies the graph, it also uses the graph lock to be sure it + * has unique access. The graph lock is needed together with BQL because of the + * thread-safe I/O API that concurrently runs and accesses the graph without + * the BQL. * * It is important to note that not all of these functions are * necessarily limited to running under the BQL, but they would @@ -268,20 +267,6 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag); int bdrv_debug_resume(BlockDriverState *bs, const char *tag); bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); -/** - * Locks the AioContext of @bs if it's not the current AioContext. This avoids - * double locking which could lead to deadlocks: This is a coroutine_fn, so we - * know we already own the lock of the current AioContext. - * - * May only be called in the main thread. - */ -void coroutine_fn bdrv_co_lock(BlockDriverState *bs); - -/** - * Unlocks the AioContext of @bs if it's not the current AioContext. - */ -void coroutine_fn bdrv_co_unlock(BlockDriverState *bs); - bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, GHashTable *visited, Transaction *tran, Error **errp); diff --git a/include/block/block-io.h b/include/block/block-io.h index f8729ccc55..b49e0537dd 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -31,8 +31,7 @@ /* * I/O API functions. These functions are thread-safe, and therefore - * can run in any thread as long as the thread has called - * aio_context_acquire/release(). + * can run in any thread. * * These functions can only call functions from I/O and Common categories, * but can be invoked by GS, "I/O or GS" and I/O APIs. @@ -333,11 +332,10 @@ bdrv_co_copy_range(BdrvChild *src, int64_t src_offset, * "I/O or GS" API functions. These functions can run without * the BQL, but only in one specific iothread/main loop. * - * More specifically, these functions use BDRV_POLL_WHILE(bs), which - * requires the caller to be either in the main thread and hold - * the BlockdriverState (bs) AioContext lock, or directly in the - * home thread that runs the bs AioContext. Calling them from - * another thread in another AioContext would cause deadlocks. + * More specifically, these functions use BDRV_POLL_WHILE(bs), which requires + * the caller to be either in the main thread or directly in the home thread + * that runs the bs AioContext. Calling them from another thread in another + * AioContext would cause deadlocks. * * Therefore, these functions are not proper I/O, because they * can't run in *any* iothreads, but only in a specific one. diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 4e31d161c5..151279d481 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -1192,8 +1192,6 @@ struct BlockDriverState { /* The error object in use for blocking operations on backing_hd */ Error *backing_blocker; - /* Protected by AioContext lock */ - /* * If we are reading a disk image, give its size in sectors. * Generally read-only; it is written to by load_snapshot and diff --git a/include/block/blockjob.h b/include/block/blockjob.h index e594c10d23..7061ab7201 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -54,7 +54,7 @@ typedef struct BlockJob { /** * Speed that was set with @block_job_set_speed. - * Always modified and read under QEMU global mutex (GLOBAL_STATE_CODE). + * Always modified and read under the BQL (GLOBAL_STATE_CODE). */ int64_t speed; @@ -66,7 +66,7 @@ typedef struct BlockJob { /** * Block other operations when block job is running. - * Always modified and read under QEMU global mutex (GLOBAL_STATE_CODE). + * Always modified and read under the BQL (GLOBAL_STATE_CODE). */ Error *blocker; @@ -89,7 +89,7 @@ typedef struct BlockJob { /** * BlockDriverStates that are involved in this block job. - * Always modified and read under QEMU global mutex (GLOBAL_STATE_CODE). + * Always modified and read under the BQL (GLOBAL_STATE_CODE). */ GSList *nodes; } BlockJob; diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h index 22b5db1ed9..d7545e82d0 100644 --- a/include/block/graph-lock.h +++ b/include/block/graph-lock.h @@ -110,34 +110,17 @@ void unregister_aiocontext(AioContext *ctx); * * The wrlock can only be taken from the main loop, with BQL held, as only the * main loop is allowed to modify the graph. - * - * If @bs is non-NULL, its AioContext is temporarily released. - * - * This function polls. Callers must not hold the lock of any AioContext other - * than the current one and the one of @bs. */ void no_coroutine_fn TSA_ACQUIRE(graph_lock) TSA_NO_TSA -bdrv_graph_wrlock(BlockDriverState *bs); +bdrv_graph_wrlock(void); /* * bdrv_graph_wrunlock: * Write finished, reset global has_writer to 0 and restart * all readers that are waiting. - * - * If @bs is non-NULL, its AioContext is temporarily released. - */ -void no_coroutine_fn TSA_RELEASE(graph_lock) TSA_NO_TSA -bdrv_graph_wrunlock(BlockDriverState *bs); - -/* - * bdrv_graph_wrunlock_ctx: - * Write finished, reset global has_writer to 0 and restart - * all readers that are waiting. - * - * If @ctx is non-NULL, its lock is temporarily released. */ void no_coroutine_fn TSA_RELEASE(graph_lock) TSA_NO_TSA -bdrv_graph_wrunlock_ctx(AioContext *ctx); +bdrv_graph_wrunlock(void); /* * bdrv_graph_co_rdlock: diff --git a/include/block/snapshot.h b/include/block/snapshot.h index d49c5599d9..304cc6ea61 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -86,8 +86,6 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs, /* * Group operations. All block drivers are involved. - * These functions will properly handle dataplane (take aio_context_acquire - * when appropriate for appropriate block drivers */ bool bdrv_all_can_snapshot(bool has_devices, strList *devices, diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 41115d8919..fef3138d29 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -92,7 +92,7 @@ RAMBlock *qemu_ram_block_by_name(const char *name); * * By the time this function returns, the returned pointer is not protected * by RCU anymore. If the caller is not within an RCU critical section and - * does not hold the iothread lock, it must have other means of protecting the + * does not hold the BQL, it must have other means of protecting the * pointer, such as a reference to the memory region that owns the RAMBlock. */ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset, diff --git a/include/exec/memory.h b/include/exec/memory.h index 831f7c996d..177be23db7 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -43,7 +43,7 @@ typedef struct IOMMUMemoryRegionClass IOMMUMemoryRegionClass; DECLARE_OBJ_CHECKERS(IOMMUMemoryRegion, IOMMUMemoryRegionClass, IOMMU_MEMORY_REGION, TYPE_IOMMU_MEMORY_REGION) -#define TYPE_RAM_DISCARD_MANAGER "qemu:ram-discard-manager" +#define TYPE_RAM_DISCARD_MANAGER "ram-discard-manager" typedef struct RamDiscardManagerClass RamDiscardManagerClass; typedef struct RamDiscardManager RamDiscardManager; DECLARE_OBJ_CHECKERS(RamDiscardManager, RamDiscardManagerClass, @@ -1288,8 +1288,10 @@ void memory_region_init_io(MemoryRegion *mr, * * Note that this function does not do anything to cause the data in the * RAM memory region to be migrated; that is the responsibility of the caller. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_ram_nomigrate(MemoryRegion *mr, +bool memory_region_init_ram_nomigrate(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1310,8 +1312,10 @@ void memory_region_init_ram_nomigrate(MemoryRegion *mr, * * Note that this function does not do anything to cause the data in the * RAM memory region to be migrated; that is the responsibility of the caller. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, +bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1338,8 +1342,10 @@ void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, * * Note that this function does not do anything to cause the data in the * RAM memory region to be migrated; that is the responsibility of the caller. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_resizeable_ram(MemoryRegion *mr, +bool memory_region_init_resizeable_ram(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1370,8 +1376,10 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr, * * Note that this function does not do anything to cause the data in the * RAM memory region to be migrated; that is the responsibility of the caller. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_ram_from_file(MemoryRegion *mr, +bool memory_region_init_ram_from_file(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1398,8 +1406,10 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, * * Note that this function does not do anything to cause the data in the * RAM memory region to be migrated; that is the responsibility of the caller. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_ram_from_fd(MemoryRegion *mr, +bool memory_region_init_ram_from_fd(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1494,8 +1504,10 @@ void memory_region_init_alias(MemoryRegion *mr, * must be unique within any device * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_rom_nomigrate(MemoryRegion *mr, +bool memory_region_init_rom_nomigrate(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1517,8 +1529,10 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr, * must be unique within any device * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, +bool memory_region_init_rom_device_nomigrate(MemoryRegion *mr, Object *owner, const MemoryRegionOps *ops, void *opaque, @@ -1576,8 +1590,10 @@ void memory_region_init_iommu(void *_iommu_mr, * give the RAM block a unique name for migration purposes. * We should lift this restriction and allow arbitrary Objects. * If you pass a non-NULL non-device @owner then we will assert. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_ram(MemoryRegion *mr, +bool memory_region_init_ram(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1603,8 +1619,10 @@ void memory_region_init_ram(MemoryRegion *mr, * must be unique within any device * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_rom(MemoryRegion *mr, +bool memory_region_init_rom(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, @@ -1634,8 +1652,10 @@ void memory_region_init_rom(MemoryRegion *mr, * must be unique within any device * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_rom_device(MemoryRegion *mr, +bool memory_region_init_rom_device(MemoryRegion *mr, Object *owner, const MemoryRegionOps *ops, void *opaque, @@ -1962,7 +1982,7 @@ int memory_region_get_fd(MemoryRegion *mr); * * Use with care; by the time this function returns, the returned pointer is * not protected by RCU anymore. If the caller is not within an RCU critical - * section and does not hold the iothread lock, it must have other means of + * section and does not hold the BQL, it must have other means of * protecting the pointer, such as a reference to the region that includes * the incoming ram_addr_t. * @@ -1979,7 +1999,7 @@ MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset); * * Use with care; by the time this function returns, the returned pointer is * not protected by RCU anymore. If the caller is not within an RCU critical - * section and does not hold the iothread lock, it must have other means of + * section and does not hold the BQL, it must have other means of * protecting the pointer, such as a reference to the region that includes * the incoming ram_addr_t. * diff --git a/include/exec/ramblock.h b/include/exec/ramblock.h index 69c6a53902..3eb79723c6 100644 --- a/include/exec/ramblock.h +++ b/include/exec/ramblock.h @@ -34,7 +34,7 @@ struct RAMBlock { ram_addr_t max_length; void (*resized)(const char*, uint64_t length, void *host); uint32_t flags; - /* Protected by iothread lock. */ + /* Protected by the BQL. */ char idstr[256]; /* RCU-enabled, writes protected by the ramlist lock */ QLIST_ENTRY(RAMBlock) next; diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index e2cebbd15c..5c057ab2ec 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -43,6 +43,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M) * a qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET). * + Property "cpu-type": CPU type to instantiate * + Property "num-irq": number of external IRQ lines + * + Property "num-prio-bits": number of priority bits in the NVIC * + Property "memory": MemoryRegion defining the physical address space * that CPU accesses see. (The NVIC, bitbanding and other CPU-internal * devices will be automatically layered on top of this view.) diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h new file mode 100644 index 0000000000..2fd44a36a9 --- /dev/null +++ b/include/hw/arm/stm32l4x5_soc.h @@ -0,0 +1,57 @@ +/* + * STM32L4x5 SoC family + * + * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr> + * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr> + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * This work is heavily inspired by the stm32f405_soc by Alistair Francis. + * Original code is licensed under the MIT License: + * + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me> + */ + +/* + * The reference used is the STMicroElectronics RM0351 Reference manual + * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs. + * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html + */ + +#ifndef HW_ARM_STM32L4x5_SOC_H +#define HW_ARM_STM32L4x5_SOC_H + +#include "exec/memory.h" +#include "hw/arm/armv7m.h" +#include "qom/object.h" + +#define TYPE_STM32L4X5_SOC "stm32l4x5-soc" +#define TYPE_STM32L4X5XC_SOC "stm32l4x5xc-soc" +#define TYPE_STM32L4X5XE_SOC "stm32l4x5xe-soc" +#define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc" +OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC) + +struct Stm32l4x5SocState { + SysBusDevice parent_obj; + + ARMv7MState armv7m; + + MemoryRegion sram1; + MemoryRegion sram2; + MemoryRegion flash; + MemoryRegion flash_alias; + + Clock *sysclk; + Clock *refclk; +}; + +struct Stm32l4x5SocClass { + SysBusDeviceClass parent_class; + + size_t flash_size; +}; + +#endif diff --git a/include/hw/boards.h b/include/hw/boards.h index da85f86efb..bcfde8a84d 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -24,6 +24,12 @@ OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE) extern MachineState *current_machine; +/** + * machine_class_default_cpu_type: Return the machine default CPU type. + * @mc: Machine class + */ +const char *machine_class_default_cpu_type(MachineClass *mc); + void machine_add_audiodev_property(MachineClass *mc); void machine_run_board_init(MachineState *machine, const char *mem_path, Error **errp); bool machine_usb(MachineState *machine); @@ -419,6 +425,9 @@ struct MachineState { } \ type_init(machine_initfn##_register_types) +extern GlobalProperty hw_compat_8_2[]; +extern const size_t hw_compat_8_2_len; + extern GlobalProperty hw_compat_8_1[]; extern const size_t hw_compat_8_1_len; diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index c0c8320413..238c02c05e 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -430,16 +430,13 @@ struct qemu_work_item; * @gdb_regs: Additional GDB registers. * @gdb_num_regs: Number of total registers accessible to GDB. * @gdb_num_g_regs: Number of registers in GDB 'g' packets. - * @next_cpu: Next CPU sharing TB cache. + * @node: QTAILQ of CPUs sharing TB cache. * @opaque: User data. * @mem_io_pc: Host Program Counter at which the memory was accessed. * @accel: Pointer to accelerator specific state. * @kvm_fd: vCPU file descriptor for KVM. * @work_mutex: Lock to prevent multiple access to @work_list. * @work_list: List of pending asynchronous work. - * @trace_dstate_delayed: Delayed changes to trace_dstate (includes all changes - * to @trace_dstate). - * @trace_dstate: Dynamic tracing state of events for this vCPU (bitmask). * @plugin_mask: Plugin event bitmap. Modified only via async work. * @ignore_memory_transaction_failures: Cached copy of the MachineState * flag of the same name: allows the board to suppress calling of the @@ -780,6 +777,19 @@ void cpu_reset(CPUState *cpu); ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); /** + * cpu_model_from_type: + * @typename: The CPU type name + * + * Extract the CPU model name from the CPU type name. The + * CPU type name is either the combination of the CPU model + * name and suffix, or same to the CPU model name. + * + * Returns: CPU model name or NULL if the CPU class doesn't exist + * The user should g_free() the string once no longer needed. + */ +char *cpu_model_from_type(const char *typename); + +/** * cpu_create: * @typename: The CPU type. * diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index a10ceeabbf..916af29f7c 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -210,6 +210,9 @@ void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids, /* sgx.c */ void pc_machine_init_sgx_epc(PCMachineState *pcms); +extern GlobalProperty pc_compat_8_2[]; +extern const size_t pc_compat_8_2_len; + extern GlobalProperty pc_compat_8_1[]; extern const size_t pc_compat_8_1_len; diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h index fbdef9a7b3..a0a46b888c 100644 --- a/include/hw/intc/loongarch_extioi.h +++ b/include/hw/intc/loongarch_extioi.h @@ -40,25 +40,29 @@ #define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) #define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) +typedef struct ExtIOICore { + uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT]; + DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS); + qemu_irq parent_irq[LS3A_INTC_IP]; +} ExtIOICore; + #define TYPE_LOONGARCH_EXTIOI "loongarch.extioi" OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI) struct LoongArchExtIOI { SysBusDevice parent_obj; + uint32_t num_cpu; /* hardware state */ uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2]; uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT]; uint32_t isr[EXTIOI_IRQS / 32]; - uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT]; uint32_t enable[EXTIOI_IRQS / 32]; uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4]; uint32_t coremap[EXTIOI_IRQS / 4]; uint32_t sw_pending[EXTIOI_IRQS / 32]; - DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS); uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; uint8_t sw_coremap[EXTIOI_IRQS]; - qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP]; qemu_irq irq[EXTIOI_IRQS]; - MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS]; + ExtIOICore *cpu; MemoryRegion extioi_system_mem; }; #endif /* LOONGARCH_EXTIOI_H */ diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h index 6c6194786e..1c1e834849 100644 --- a/include/hw/intc/loongarch_ipi.h +++ b/include/hw/intc/loongarch_ipi.h @@ -47,7 +47,8 @@ struct LoongArchIPI { SysBusDevice parent_obj; MemoryRegion ipi_iocsr_mem; MemoryRegion ipi64_iocsr_mem; - IPICore ipi_core; + uint32_t num_cpu; + IPICore *cpu; }; #endif diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 674f4655e0..6ef9a92394 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -25,7 +25,7 @@ #define VIRT_LOWMEM_BASE 0 #define VIRT_LOWMEM_SIZE 0x10000000 -#define VIRT_HIGHMEM_BASE 0x90000000 +#define VIRT_HIGHMEM_BASE 0x80000000 #define VIRT_GED_EVT_ADDR 0x100e0000 #define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) #define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) @@ -50,6 +50,9 @@ struct LoongArchMachineState { DeviceState *platform_bus_dev; PCIBus *pci_bus; PFlashCFI01 *flash; + MemoryRegion system_iocsr; + MemoryRegion iocsr_mem; + AddressSpace as_iocsr; }; #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") diff --git a/include/hw/mips/bios.h b/include/hw/mips/bios.h deleted file mode 100644 index 44acb6815b..0000000000 --- a/include/hw/mips/bios.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef HW_MIPS_BIOS_H -#define HW_MIPS_BIOS_H - -#include "qemu/units.h" -#include "cpu.h" - -#define BIOS_SIZE (4 * MiB) -#if TARGET_BIG_ENDIAN -#define BIOS_FILENAME "mips_bios.bin" -#else -#define BIOS_FILENAME "mipsel_bios.bin" -#endif - -#endif diff --git a/include/hw/misc/imx7_snvs.h b/include/hw/misc/imx7_snvs.h index 14a1d6fe6b..1272076086 100644 --- a/include/hw/misc/imx7_snvs.h +++ b/include/hw/misc/imx7_snvs.h @@ -20,7 +20,9 @@ enum IMX7SNVSRegisters { SNVS_LPCR = 0x38, SNVS_LPCR_TOP = BIT(6), - SNVS_LPCR_DP_EN = BIT(5) + SNVS_LPCR_DP_EN = BIT(5), + SNVS_LPSRTCMR = 0x050, /* Secure Real Time Counter MSB Register */ + SNVS_LPSRTCLR = 0x054, /* Secure Real Time Counter LSB Register */ }; #define TYPE_IMX7_SNVS "imx7.snvs" @@ -31,6 +33,9 @@ struct IMX7SNVSState { SysBusDevice parent_obj; MemoryRegion mmio; + + uint64_t tick_offset; + uint64_t lpcr; }; #endif /* IMX7_SNVS_H */ diff --git a/include/hw/misc/xlnx-versal-cframe-reg.h b/include/hw/misc/xlnx-versal-cframe-reg.h index 0091505246..83f6a07744 100644 --- a/include/hw/misc/xlnx-versal-cframe-reg.h +++ b/include/hw/misc/xlnx-versal-cframe-reg.h @@ -23,7 +23,7 @@ #include "hw/misc/xlnx-versal-cfu.h" #include "qemu/fifo32.h" -#define TYPE_XLNX_VERSAL_CFRAME_REG "xlnx,cframe-reg" +#define TYPE_XLNX_VERSAL_CFRAME_REG "xlnx-cframe-reg" OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFrameReg, XLNX_VERSAL_CFRAME_REG) #define TYPE_XLNX_VERSAL_CFRAME_BCAST_REG "xlnx.cframe-bcast-reg" diff --git a/include/hw/misc/xlnx-versal-cfu.h b/include/hw/misc/xlnx-versal-cfu.h index be62bab8c8..3de3ee4923 100644 --- a/include/hw/misc/xlnx-versal-cfu.h +++ b/include/hw/misc/xlnx-versal-cfu.h @@ -22,13 +22,13 @@ #include "hw/misc/xlnx-cfi-if.h" #include "qemu/fifo32.h" -#define TYPE_XLNX_VERSAL_CFU_APB "xlnx,versal-cfu-apb" +#define TYPE_XLNX_VERSAL_CFU_APB "xlnx-versal-cfu-apb" OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUAPB, XLNX_VERSAL_CFU_APB) -#define TYPE_XLNX_VERSAL_CFU_FDRO "xlnx,versal-cfu-fdro" +#define TYPE_XLNX_VERSAL_CFU_FDRO "xlnx-versal-cfu-fdro" OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUFDRO, XLNX_VERSAL_CFU_FDRO) -#define TYPE_XLNX_VERSAL_CFU_SFR "xlnx,versal-cfu-sfr" +#define TYPE_XLNX_VERSAL_CFU_SFR "xlnx-versal-cfu-sfr" OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUSFR, XLNX_VERSAL_CFU_SFR) REG32(CFU_ISR, 0x0) diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h index 2857f4169a..dfb8dff197 100644 --- a/include/hw/misc/xlnx-versal-crl.h +++ b/include/hw/misc/xlnx-versal-crl.h @@ -13,7 +13,7 @@ #include "hw/register.h" #include "target/arm/cpu.h" -#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl" +#define TYPE_XLNX_VERSAL_CRL "xlnx-versal-crl" OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL) REG32(ERR_CTRL, 0x0) diff --git a/include/hw/nvram/fw_cfg_acpi.h b/include/hw/nvram/fw_cfg_acpi.h new file mode 100644 index 0000000000..b6553d86fc --- /dev/null +++ b/include/hw/nvram/fw_cfg_acpi.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * ACPI support for fw_cfg + * + */ + +#ifndef FW_CFG_ACPI_H +#define FW_CFG_ACPI_H + +#include "qemu/osdep.h" +#include "exec/hwaddr.h" + +void fw_cfg_acpi_dsdt_add(Aml *scope, const MemMapEntry *fw_cfg_memmap); + +#endif diff --git a/include/hw/nvram/xlnx-efuse.h b/include/hw/nvram/xlnx-efuse.h index 58414e468b..cff7924106 100644 --- a/include/hw/nvram/xlnx-efuse.h +++ b/include/hw/nvram/xlnx-efuse.h @@ -30,7 +30,7 @@ #include "sysemu/block-backend.h" #include "hw/qdev-core.h" -#define TYPE_XLNX_EFUSE "xlnx,efuse" +#define TYPE_XLNX_EFUSE "xlnx-efuse" OBJECT_DECLARE_SIMPLE_TYPE(XlnxEFuse, XLNX_EFUSE); struct XlnxEFuse { diff --git a/include/hw/nvram/xlnx-versal-efuse.h b/include/hw/nvram/xlnx-versal-efuse.h index a873dc5cb0..86e2261b9a 100644 --- a/include/hw/nvram/xlnx-versal-efuse.h +++ b/include/hw/nvram/xlnx-versal-efuse.h @@ -29,8 +29,8 @@ #define XLNX_VERSAL_EFUSE_CTRL_R_MAX ((0x100 / 4) + 1) -#define TYPE_XLNX_VERSAL_EFUSE_CTRL "xlnx,versal-efuse" -#define TYPE_XLNX_VERSAL_EFUSE_CACHE "xlnx,pmc-efuse-cache" +#define TYPE_XLNX_VERSAL_EFUSE_CTRL "xlnx-versal-efuse" +#define TYPE_XLNX_VERSAL_EFUSE_CACHE "xlnx-pmc-efuse-cache" OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalEFuseCtrl, XLNX_VERSAL_EFUSE_CTRL); OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalEFuseCache, XLNX_VERSAL_EFUSE_CACHE); diff --git a/include/hw/nvram/xlnx-zynqmp-efuse.h b/include/hw/nvram/xlnx-zynqmp-efuse.h index 6b051ec4f1..f5beacc2e6 100644 --- a/include/hw/nvram/xlnx-zynqmp-efuse.h +++ b/include/hw/nvram/xlnx-zynqmp-efuse.h @@ -29,7 +29,7 @@ #define XLNX_ZYNQMP_EFUSE_R_MAX ((0x10fc / 4) + 1) -#define TYPE_XLNX_ZYNQMP_EFUSE "xlnx,zynqmp-efuse" +#define TYPE_XLNX_ZYNQMP_EFUSE "xlnx-zynqmp-efuse" OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPEFuse, XLNX_ZYNQMP_EFUSE); struct XlnxZynqMPEFuse { diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h index b0240bd768..dce883573b 100644 --- a/include/hw/pci-host/gpex.h +++ b/include/hw/pci-host/gpex.h @@ -40,6 +40,15 @@ struct GPEXRootState { /*< public >*/ }; +struct GPEXConfig { + MemMapEntry ecam; + MemMapEntry mmio32; + MemMapEntry mmio64; + MemMapEntry pio; + int irq; + PCIBus *bus; +}; + struct GPEXHost { /*< private >*/ PCIExpressHost parent_obj; @@ -55,19 +64,22 @@ struct GPEXHost { int irq_num[GPEX_NUM_IRQS]; bool allow_unmapped_accesses; -}; -struct GPEXConfig { - MemMapEntry ecam; - MemMapEntry mmio32; - MemMapEntry mmio64; - MemMapEntry pio; - int irq; - PCIBus *bus; + struct GPEXConfig gpex_cfg; }; int gpex_set_irq_num(GPEXHost *s, int index, int gsi); void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg); +void acpi_dsdt_add_gpex_host(Aml *scope, uint32_t irq); + +#define PCI_HOST_PIO_BASE "x-pio-base" +#define PCI_HOST_PIO_SIZE "x-pio-size" +#define PCI_HOST_ECAM_BASE "x-ecam-base" +#define PCI_HOST_ECAM_SIZE "x-ecam-size" +#define PCI_HOST_BELOW_4G_MMIO_BASE "x-below-4g-mmio-base" +#define PCI_HOST_BELOW_4G_MMIO_SIZE "x-below-4g-mmio-size" +#define PCI_HOST_ABOVE_4G_MMIO_BASE "x-above-4g-mmio-base" +#define PCI_HOST_ABOVE_4G_MMIO_SIZE "x-above-4g-mmio-size" #endif /* HW_GPEX_H */ diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h index 89c7a3b7fa..a0789df153 100644 --- a/include/hw/pci/shpc.h +++ b/include/hw/pci/shpc.h @@ -52,7 +52,7 @@ void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); -extern VMStateInfo shpc_vmstate_info; +extern const VMStateInfo shpc_vmstate_info; #define SHPC_VMSTATE(_field, _type, _test) \ VMSTATE_BUFFER_UNSAFE_INFO_TEST(_field, _type, _test, 0, \ shpc_vmstate_info, 0) diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h index b7adbdb7b9..816f5d0e84 100644 --- a/include/hw/ppc/xive2_regs.h +++ b/include/hw/ppc/xive2_regs.h @@ -10,7 +10,7 @@ #ifndef PPC_XIVE2_REGS_H #define PPC_XIVE2_REGS_H -#include "cpu.h" +#include "qemu/bswap.h" /* * Thread Interrupt Management Area (TIMA) diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h index 91f7a2452d..06c359c190 100644 --- a/include/hw/qdev-properties-system.h +++ b/include/hw/qdev-properties-system.h @@ -24,6 +24,7 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar; extern const PropertyInfo qdev_prop_pcie_link_speed; extern const PropertyInfo qdev_prop_pcie_link_width; extern const PropertyInfo qdev_prop_cpus390entitlement; +extern const PropertyInfo qdev_prop_iothread_vq_mapping_list; #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) @@ -82,4 +83,8 @@ extern const PropertyInfo qdev_prop_cpus390entitlement; DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_cpus390entitlement, \ CpuS390Entitlement) +#define DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST(_name, _state, _field) \ + DEFINE_PROP(_name, _state, _field, qdev_prop_iothread_vq_mapping_list, \ + IOThreadVirtQueueMappingList *) + #endif diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 25743a29a0..09aa04ca1e 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -230,8 +230,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop); * @target: Device which has properties to be aliased * @source: Object to add alias properties to * - * Add alias properties to the @source object for all qdev properties on - * the @target DeviceState. + * Add alias properties to the @source object for all properties on the @target + * DeviceState. * * This is useful when @target is an internal implementation object * owned by @source, and you want to expose all the properties of that diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index e5c474b26e..f89790fd58 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -23,6 +23,7 @@ #include "hw/riscv/riscv_hart.h" #include "hw/sysbus.h" #include "hw/block/flash.h" +#include "hw/intc/riscv_imsic.h" #define VIRT_CPUS_MAX_BITS 9 #define VIRT_CPUS_MAX (1 << VIRT_CPUS_MAX_BITS) @@ -60,6 +61,7 @@ struct RISCVVirtState { char *oem_table_id; OnOffAuto acpi; const MemMapEntry *memmap; + struct GPEXHost *gpex_host; }; enum { @@ -127,4 +129,28 @@ enum { bool virt_is_acpi_enabled(RISCVVirtState *s); void virt_acpi_setup(RISCVVirtState *vms); +uint32_t imsic_num_bits(uint32_t count); + +/* + * The virt machine physical address space used by some of the devices + * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets, + * number of CPUs, and number of IMSIC guest files. + * + * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS, + * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization + * of virt machine physical address space. + */ + +#define VIRT_IMSIC_GROUP_MAX_SIZE (1U << IMSIC_MMIO_GROUP_MIN_SHIFT) +#if VIRT_IMSIC_GROUP_MAX_SIZE < \ + IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS) +#error "Can't accomodate single IMSIC group in address space" +#endif + +#define VIRT_IMSIC_MAX_SIZE (VIRT_SOCKETS_MAX * \ + VIRT_IMSIC_GROUP_MAX_SIZE) +#if 0x4000000 < VIRT_IMSIC_MAX_SIZE +#error "Can't accomodate all IMSIC groups in address space" +#endif + #endif diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 3692ca82f3..10c4e8288d 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -69,14 +69,19 @@ struct SCSIDevice { DeviceState qdev; VMChangeStateEntry *vmsentry; - QEMUBH *bh; uint32_t id; BlockConf conf; SCSISense unit_attention; bool sense_is_ua; uint8_t sense[SCSI_SENSE_BUF_SIZE]; uint32_t sense_len; + + /* + * The requests list is only accessed from the AioContext that executes + * requests or from the main loop when IOThread processing is stopped. + */ QTAILQ_HEAD(, SCSIRequest) requests; + uint32_t channel; uint32_t lun; int blocksize; diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index a4a22accb9..9b7ef7d02b 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -30,6 +30,7 @@ #include <linux/vfio.h> #endif #include "sysemu/sysemu.h" +#include "hw/vfio/vfio-container-base.h" #define VFIO_MSG_PREFIX "vfio %s: " @@ -72,54 +73,15 @@ typedef struct VFIOMigration { bool initial_data_sent; } VFIOMigration; -typedef struct VFIOAddressSpace { - AddressSpace *as; - QLIST_HEAD(, VFIOContainer) containers; - QLIST_ENTRY(VFIOAddressSpace) list; -} VFIOAddressSpace; - struct VFIOGroup; typedef struct VFIOContainer { - VFIOAddressSpace *space; + VFIOContainerBase bcontainer; int fd; /* /dev/vfio/vfio, empowered by the attached groups */ - MemoryListener listener; - MemoryListener prereg_listener; unsigned iommu_type; - Error *error; - bool initialized; - bool dirty_pages_supported; - uint64_t dirty_pgsizes; - uint64_t max_dirty_bitmap_size; - unsigned long pgsizes; - unsigned int dma_max_mappings; - QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; - QLIST_ENTRY(VFIOContainer) next; - QLIST_HEAD(, VFIODevice) device_list; - GList *iova_ranges; } VFIOContainer; -typedef struct VFIOGuestIOMMU { - VFIOContainer *container; - IOMMUMemoryRegion *iommu_mr; - hwaddr iommu_offset; - IOMMUNotifier n; - QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; -} VFIOGuestIOMMU; - -typedef struct VFIORamDiscardListener { - VFIOContainer *container; - MemoryRegion *mr; - hwaddr offset_within_address_space; - hwaddr size; - uint64_t granularity; - RamDiscardListener listener; - QLIST_ENTRY(VFIORamDiscardListener) next; -} VFIORamDiscardListener; - typedef struct VFIOHostDMAWindow { hwaddr min_iova; hwaddr max_iova; @@ -127,6 +89,14 @@ typedef struct VFIOHostDMAWindow { QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; } VFIOHostDMAWindow; +typedef struct IOMMUFDBackend IOMMUFDBackend; + +typedef struct VFIOIOMMUFDContainer { + VFIOContainerBase bcontainer; + IOMMUFDBackend *be; + uint32_t ioas_id; +} VFIOIOMMUFDContainer; + typedef struct VFIODeviceOps VFIODeviceOps; typedef struct VFIODevice { @@ -134,7 +104,7 @@ typedef struct VFIODevice { QLIST_ENTRY(VFIODevice) container_next; QLIST_ENTRY(VFIODevice) global_next; struct VFIOGroup *group; - VFIOContainer *container; + VFIOContainerBase *bcontainer; char *sysfsdev; char *name; DeviceState *dev; @@ -154,6 +124,8 @@ typedef struct VFIODevice { OnOffAuto pre_copy_dirty_page_tracking; bool dirty_pages_supported; bool dirty_tracking; + int devid; + IOMMUFDBackend *iommufd; } VFIODevice; struct VFIODeviceOps { @@ -201,31 +173,10 @@ typedef struct VFIODisplay { } dmabuf; } VFIODisplay; -typedef struct { - unsigned long *bitmap; - hwaddr size; - hwaddr pages; -} VFIOBitmap; - VFIOAddressSpace *vfio_get_address_space(AddressSpace *as); void vfio_put_address_space(VFIOAddressSpace *space); -bool vfio_devices_all_running_and_saving(VFIOContainer *container); - -/* container->fd */ -int vfio_dma_unmap(VFIOContainer *container, hwaddr iova, - ram_addr_t size, IOMMUTLBEntry *iotlb); -int vfio_dma_map(VFIOContainer *container, hwaddr iova, - ram_addr_t size, void *vaddr, bool readonly); -int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start); -int vfio_query_dirty_bitmap(VFIOContainer *container, VFIOBitmap *vbmap, - hwaddr iova, hwaddr size); /* SPAPR specific */ -int vfio_container_add_section_window(VFIOContainer *container, - MemoryRegionSection *section, - Error **errp); -void vfio_container_del_section_window(VFIOContainer *container, - MemoryRegionSection *section); int vfio_spapr_container_init(VFIOContainer *container, Error **errp); void vfio_spapr_container_deinit(VFIOContainer *container); @@ -259,7 +210,6 @@ typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; extern VFIOGroupList vfio_group_list; extern VFIODeviceList vfio_device_list; - extern const MemoryListener vfio_memory_listener; extern int vfio_kvm_device_fd; @@ -292,11 +242,19 @@ bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp); void vfio_migration_exit(VFIODevice *vbasedev); int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size); -bool vfio_devices_all_running_and_mig_active(VFIOContainer *container); -bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container); -int vfio_devices_query_dirty_bitmap(VFIOContainer *container, +bool +vfio_devices_all_running_and_mig_active(const VFIOContainerBase *bcontainer); +bool +vfio_devices_all_device_dirty_tracking(const VFIOContainerBase *bcontainer); +int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer, VFIOBitmap *vbmap, hwaddr iova, hwaddr size); -int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - uint64_t size, ram_addr_t ram_addr); +int vfio_get_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova, + uint64_t size, ram_addr_t ram_addr); + +/* Returns 0 on success, or a negative errno. */ +int vfio_device_get_name(VFIODevice *vbasedev, Error **errp); +void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp); +void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, + DeviceState *dev, bool ram_discard); #endif /* HW_VFIO_VFIO_COMMON_H */ diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h new file mode 100644 index 0000000000..b2813b0c11 --- /dev/null +++ b/include/hw/vfio/vfio-container-base.h @@ -0,0 +1,140 @@ +/* + * VFIO BASE CONTAINER + * + * Copyright (C) 2023 Intel Corporation. + * Copyright Red Hat, Inc. 2023 + * + * Authors: Yi Liu <yi.l.liu@intel.com> + * Eric Auger <eric.auger@redhat.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_CONTAINER_BASE_H +#define HW_VFIO_VFIO_CONTAINER_BASE_H + +#include "exec/memory.h" + +typedef struct VFIODevice VFIODevice; +typedef struct VFIOIOMMUClass VFIOIOMMUClass; + +typedef struct { + unsigned long *bitmap; + hwaddr size; + hwaddr pages; +} VFIOBitmap; + +typedef struct VFIOAddressSpace { + AddressSpace *as; + QLIST_HEAD(, VFIOContainerBase) containers; + QLIST_ENTRY(VFIOAddressSpace) list; +} VFIOAddressSpace; + +/* + * This is the base object for vfio container backends + */ +typedef struct VFIOContainerBase { + const VFIOIOMMUClass *ops; + VFIOAddressSpace *space; + MemoryListener listener; + Error *error; + bool initialized; + uint64_t dirty_pgsizes; + uint64_t max_dirty_bitmap_size; + unsigned long pgsizes; + unsigned int dma_max_mappings; + bool dirty_pages_supported; + QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; + QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; + QLIST_ENTRY(VFIOContainerBase) next; + QLIST_HEAD(, VFIODevice) device_list; + GList *iova_ranges; +} VFIOContainerBase; + +typedef struct VFIOGuestIOMMU { + VFIOContainerBase *bcontainer; + IOMMUMemoryRegion *iommu_mr; + hwaddr iommu_offset; + IOMMUNotifier n; + QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; +} VFIOGuestIOMMU; + +typedef struct VFIORamDiscardListener { + VFIOContainerBase *bcontainer; + MemoryRegion *mr; + hwaddr offset_within_address_space; + hwaddr size; + uint64_t granularity; + RamDiscardListener listener; + QLIST_ENTRY(VFIORamDiscardListener) next; +} VFIORamDiscardListener; + +int vfio_container_dma_map(VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + void *vaddr, bool readonly); +int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + IOMMUTLBEntry *iotlb); +int vfio_container_add_section_window(VFIOContainerBase *bcontainer, + MemoryRegionSection *section, + Error **errp); +void vfio_container_del_section_window(VFIOContainerBase *bcontainer, + MemoryRegionSection *section); +int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, + bool start); +int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, + VFIOBitmap *vbmap, + hwaddr iova, hwaddr size); + +void vfio_container_init(VFIOContainerBase *bcontainer, + VFIOAddressSpace *space, + const VFIOIOMMUClass *ops); +void vfio_container_destroy(VFIOContainerBase *bcontainer); + + +#define TYPE_VFIO_IOMMU "vfio-iommu" +#define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy" +#define TYPE_VFIO_IOMMU_SPAPR TYPE_VFIO_IOMMU "-spapr" +#define TYPE_VFIO_IOMMU_IOMMUFD TYPE_VFIO_IOMMU "-iommufd" + +/* + * VFIOContainerBase is not an abstract QOM object because it felt + * unnecessary to expose all the IOMMU backends to the QEMU machine + * and human interface. However, we can still abstract the IOMMU + * backend handlers using a QOM interface class. This provides more + * flexibility when referencing the various implementations. + */ +DECLARE_CLASS_CHECKERS(VFIOIOMMUClass, VFIO_IOMMU, TYPE_VFIO_IOMMU) + +struct VFIOIOMMUClass { + InterfaceClass parent_class; + + /* basic feature */ + int (*setup)(VFIOContainerBase *bcontainer, Error **errp); + int (*dma_map)(const VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + void *vaddr, bool readonly); + int (*dma_unmap)(const VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + IOMMUTLBEntry *iotlb); + int (*attach_device)(const char *name, VFIODevice *vbasedev, + AddressSpace *as, Error **errp); + void (*detach_device)(VFIODevice *vbasedev); + /* migration feature */ + int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer, + bool start); + int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer, + VFIOBitmap *vbmap, + hwaddr iova, hwaddr size); + /* PCI specific */ + int (*pci_hot_reset)(VFIODevice *vbasedev, bool single); + + /* SPAPR specific */ + int (*add_window)(VFIOContainerBase *bcontainer, + MemoryRegionSection *section, + Error **errp); + void (*del_window)(VFIOContainerBase *bcontainer, + MemoryRegionSection *section); + void (*release)(VFIOContainerBase *bcontainer); +}; +#endif /* HW_VFIO_VFIO_CONTAINER_BASE_H */ diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index a86d103f82..70c2e8ffee 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -45,6 +45,8 @@ struct vhost_memory; struct vhost_vring_file; struct vhost_vring_state; struct vhost_vring_addr; +struct vhost_vring_worker; +struct vhost_worker_state; struct vhost_scsi_target; struct vhost_iotlb_msg; struct vhost_virtqueue; @@ -85,6 +87,14 @@ typedef int (*vhost_set_vring_err_op)(struct vhost_dev *dev, struct vhost_vring_file *file); typedef int (*vhost_set_vring_busyloop_timeout_op)(struct vhost_dev *dev, struct vhost_vring_state *r); +typedef int (*vhost_attach_vring_worker_op)(struct vhost_dev *dev, + struct vhost_vring_worker *worker); +typedef int (*vhost_get_vring_worker_op)(struct vhost_dev *dev, + struct vhost_vring_worker *worker); +typedef int (*vhost_new_worker_op)(struct vhost_dev *dev, + struct vhost_worker_state *worker); +typedef int (*vhost_free_worker_op)(struct vhost_dev *dev, + struct vhost_worker_state *worker); typedef int (*vhost_set_features_op)(struct vhost_dev *dev, uint64_t features); typedef int (*vhost_get_features_op)(struct vhost_dev *dev, @@ -172,6 +182,10 @@ typedef struct VhostOps { vhost_set_vring_call_op vhost_set_vring_call; vhost_set_vring_err_op vhost_set_vring_err; vhost_set_vring_busyloop_timeout_op vhost_set_vring_busyloop_timeout; + vhost_new_worker_op vhost_new_worker; + vhost_free_worker_op vhost_free_worker; + vhost_get_vring_worker_op vhost_get_vring_worker; + vhost_attach_vring_worker_op vhost_attach_vring_worker; vhost_set_features_op vhost_set_features; vhost_get_features_op vhost_get_features; vhost_set_backend_cap_op vhost_set_backend_cap; diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h index 5407d54fd7..8f54e5edd4 100644 --- a/include/hw/virtio/vhost-vdpa.h +++ b/include/hw/virtio/vhost-vdpa.h @@ -30,42 +30,52 @@ typedef struct VhostVDPAHostNotifier { void *addr; } VhostVDPAHostNotifier; -typedef struct vhost_vdpa { +/* Info shared by all vhost_vdpa device models */ +typedef struct vhost_vdpa_shared { int device_fd; - int index; - uint32_t msg_type; - bool iotlb_batch_begin_sent; - uint32_t address_space_id; MemoryListener listener; struct vhost_vdpa_iova_range iova_range; - uint64_t acked_features; - bool shadow_vqs_enabled; + QLIST_HEAD(, vdpa_iommu) iommu_list; + + /* IOVA mapping used by the Shadow Virtqueue */ + VhostIOVATree *iova_tree; + + /* Copy of backend features */ + uint64_t backend_cap; + + bool iotlb_batch_begin_sent; + /* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */ bool shadow_data; +} VhostVDPAShared; + +typedef struct vhost_vdpa { + int index; + uint32_t address_space_id; + uint64_t acked_features; + bool shadow_vqs_enabled; /* Device suspended successfully */ bool suspended; - /* IOVA mapping used by the Shadow Virtqueue */ - VhostIOVATree *iova_tree; + VhostVDPAShared *shared; GPtrArray *shadow_vqs; const VhostShadowVirtqueueOps *shadow_vq_ops; void *shadow_vq_ops_opaque; struct vhost_dev *dev; Error *migration_blocker; VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; - QLIST_HEAD(, vdpa_iommu) iommu_list; IOMMUNotifier n; } VhostVDPA; int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range); int vhost_vdpa_set_vring_ready(struct vhost_vdpa *v, unsigned idx); -int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, +int vhost_vdpa_dma_map(VhostVDPAShared *s, uint32_t asid, hwaddr iova, hwaddr size, void *vaddr, bool readonly); -int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, +int vhost_vdpa_dma_unmap(VhostVDPAShared *s, uint32_t asid, hwaddr iova, hwaddr size); typedef struct vdpa_iommu { - struct vhost_vdpa *dev; + VhostVDPAShared *dev_shared; IOMMUMemoryRegion *iommu_mr; hwaddr iommu_offset; IOMMUNotifier n; diff --git a/include/hw/virtio/virtio-acpi.h b/include/hw/virtio/virtio-acpi.h new file mode 100644 index 0000000000..844e102569 --- /dev/null +++ b/include/hw/virtio/virtio-acpi.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * ACPI support for virtio + */ + +#ifndef VIRTIO_ACPI_H +#define VIRTIO_ACPI_H + +#include "qemu/osdep.h" +#include "exec/hwaddr.h" + +void virtio_acpi_dsdt_add(Aml *scope, const hwaddr virtio_mmio_base, + const hwaddr virtio_mmio_size, uint32_t mmio_irq, + long int start_index, int num); + +#endif diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index dafec432ce..5e4091e4da 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -21,6 +21,7 @@ #include "sysemu/block-backend.h" #include "sysemu/block-ram-registrar.h" #include "qom/object.h" +#include "qapi/qapi-types-virtio.h" #define TYPE_VIRTIO_BLK "virtio-blk-device" OBJECT_DECLARE_SIMPLE_TYPE(VirtIOBlock, VIRTIO_BLK) @@ -37,6 +38,7 @@ struct VirtIOBlkConf { BlockConf conf; IOThread *iothread; + IOThreadVirtQueueMappingList *iothread_vq_mapping_list; char *serial; uint32_t request_merging; uint16_t num_queues; @@ -54,7 +56,8 @@ struct VirtIOBlockReq; struct VirtIOBlock { VirtIODevice parent_obj; BlockBackend *blk; - void *rq; + QemuMutex rq_lock; + void *rq; /* protected by rq_lock */ VirtIOBlkConf conf; unsigned short sector_mask; bool original_wce; diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 779568ab5d..7be0105918 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -51,6 +51,7 @@ typedef struct virtio_scsi_config VirtIOSCSIConfig; struct VirtIOSCSIConf { uint32_t num_queues; uint32_t virtqueue_size; + bool worker_per_virtqueue; bool seg_max_adjust; uint32_t max_sectors; uint32_t cmd_per_lun; @@ -85,8 +86,9 @@ struct VirtIOSCSI { /* * TMFs deferred to main loop BH. These fields are protected by - * virtio_scsi_acquire(). + * tmf_bh_lock. */ + QemuMutex tmf_bh_lock; QEMUBH *tmf_bh; QTAILQ_HEAD(, VirtIOSCSIReq) tmf_bh_list; @@ -100,20 +102,6 @@ struct VirtIOSCSI { uint32_t host_features; }; -static inline void virtio_scsi_acquire(VirtIOSCSI *s) -{ - if (s->ctx) { - aio_context_acquire(s->ctx); - } -} - -static inline void virtio_scsi_release(VirtIOSCSI *s) -{ - if (s->ctx) { - aio_context_release(s->ctx); - } -} - void virtio_scsi_common_realize(DeviceState *dev, VirtIOHandleOutput ctrl, VirtIOHandleOutput evt, diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h index 6f09c48823..1a5ad693a4 100644 --- a/include/hw/xen/xen_native.h +++ b/include/hw/xen/xen_native.h @@ -532,7 +532,7 @@ static inline int xendevicemodel_set_irq_level(xendevicemodel_handle *dmod, } #endif -#if CONFIG_XEN_CTRL_INTERFACE_VERSION <= 41700 +#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41700 #define GUEST_VIRTIO_MMIO_BASE xen_mk_ullong(0x02000000) #define GUEST_VIRTIO_MMIO_SIZE xen_mk_ullong(0x00100000) #define GUEST_VIRTIO_MMIO_SPI_FIRST 33 diff --git a/include/io/task.h b/include/io/task.h index dc7d32ebd0..0b5342ee84 100644 --- a/include/io/task.h +++ b/include/io/task.h @@ -149,7 +149,7 @@ typedef void (*QIOTaskWorker)(QIOTask *task, * lookups) to be easily run non-blocking. Reporting the * results in the main thread context means that the caller * typically does not need to be concerned about thread - * safety wrt the QEMU global mutex. + * safety wrt the BQL. * * For example, the socket_listen() method will block the caller * while DNS lookups take place if given a name, instead of IP diff --git a/include/migration/register.h b/include/migration/register.h index fed1d04a3c..9ab1f79512 100644 --- a/include/migration/register.h +++ b/include/migration/register.h @@ -17,7 +17,7 @@ #include "hw/vmstate-if.h" typedef struct SaveVMHandlers { - /* This runs inside the iothread lock. */ + /* This runs inside the BQL. */ SaveStateHandler *save_state; /* @@ -30,7 +30,7 @@ typedef struct SaveVMHandlers { int (*save_live_complete_postcopy)(QEMUFile *f, void *opaque); int (*save_live_complete_precopy)(QEMUFile *f, void *opaque); - /* This runs both outside and inside the iothread lock. */ + /* This runs both outside and inside the BQL. */ bool (*is_active)(void *opaque); bool (*has_postcopy)(void *opaque); @@ -43,14 +43,14 @@ typedef struct SaveVMHandlers { */ bool (*is_active_iterate)(void *opaque); - /* This runs outside the iothread lock in the migration case, and + /* This runs outside the BQL in the migration case, and * within the lock in the savevm case. The callback had better only * use data that is local to the migration thread or protected * by other locks. */ int (*save_live_iterate)(QEMUFile *f, void *opaque); - /* This runs outside the iothread lock! */ + /* This runs outside the BQL! */ /* Note for save_live_pending: * must_precopy: * - must be migrated in precopy or in stopped state diff --git a/include/migration/snapshot.h b/include/migration/snapshot.h index e72083b117..9e4dcaaa75 100644 --- a/include/migration/snapshot.h +++ b/include/migration/snapshot.h @@ -16,6 +16,7 @@ #define QEMU_MIGRATION_SNAPSHOT_H #include "qapi/qapi-builtin-types.h" +#include "qapi/qapi-types-run-state.h" /** * save_snapshot: Save an internal snapshot. @@ -61,4 +62,10 @@ bool delete_snapshot(const char *name, bool has_devices, strList *devices, Error **errp); +/** + * load_snapshot_resume: Restore runstate after loading snapshot. + * @state: state to restore + */ +void load_snapshot_resume(RunState state); + #endif diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 9821918631..294d2d8486 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -209,7 +209,7 @@ struct VMStateDescription { bool (*dev_unplug_pending)(void *opaque); const VMStateField *fields; - const VMStateDescription **subsections; + const VMStateDescription * const *subsections; }; extern const VMStateInfo vmstate_info_bool; diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h index 268dfe9986..b1ee473b30 100644 --- a/include/qapi/string-output-visitor.h +++ b/include/qapi/string-output-visitor.h @@ -26,9 +26,9 @@ typedef struct StringOutputVisitor StringOutputVisitor; * If everything else succeeds, pass @result to visit_complete() to * collect the result of the visit. * - * The string output visitor does not implement support for visiting - * QAPI structs, alternates, null, or arbitrary QTypes. It also - * requires a non-null list argument to visit_start_list(). + * The string output visitor does not implement support for alternates, null, + * or arbitrary QTypes. Struct fields are not shown. It also requires a + * non-null list argument to visit_start_list(). */ Visitor *string_output_visitor_new(bool human, char **result); diff --git a/include/qemu/chardev_open.h b/include/qemu/chardev_open.h new file mode 100644 index 0000000000..64e8fcfdcb --- /dev/null +++ b/include/qemu/chardev_open.h @@ -0,0 +1,16 @@ +/* + * QEMU Chardev Helper + * + * Copyright (C) 2023 Intel Corporation. + * + * Authors: Yi Liu <yi.l.liu@intel.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#ifndef QEMU_CHARDEV_OPEN_H +#define QEMU_CHARDEV_OPEN_H + +int open_cdev(const char *devpath, dev_t cdev); +#endif diff --git a/include/qemu/coroutine-core.h b/include/qemu/coroutine-core.h index 230bb56517..503bad6e0e 100644 --- a/include/qemu/coroutine-core.h +++ b/include/qemu/coroutine-core.h @@ -22,7 +22,7 @@ * rather than callbacks, for operations that need to give up control while * waiting for events to complete. * - * These functions are re-entrant and may be used outside the global mutex. + * These functions are re-entrant and may be used outside the BQL. * * Functions that execute in coroutine context cannot be called * directly from normal functions. Use @coroutine_fn to mark such diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index a65be6697f..e6aff45301 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -26,7 +26,7 @@ * rather than callbacks, for operations that need to give up control while * waiting for events to complete. * - * These functions are re-entrant and may be used outside the global mutex. + * These functions are re-entrant and may be used outside the BQL. * * Functions that execute in coroutine context cannot be called * directly from normal functions. Use @coroutine_fn to mark such diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h index 16be02f361..c6295c6ff0 100644 --- a/include/qemu/fifo8.h +++ b/include/qemu/fifo8.h @@ -71,7 +71,7 @@ uint8_t fifo8_pop(Fifo8 *fifo); * fifo8_pop_buf: * @fifo: FIFO to pop from * @max: maximum number of bytes to pop - * @num: actual number of returned bytes + * @numptr: pointer filled with number of bytes returned (can be NULL) * * Pop a number of elements from the FIFO up to a maximum of max. The buffer * containing the popped data is returned. This buffer points directly into @@ -82,16 +82,43 @@ uint8_t fifo8_pop(Fifo8 *fifo); * around in the ring buffer; in this case only a contiguous part of the data * is returned. * - * The number of valid bytes returned is populated in *num; will always return - * at least 1 byte. max must not be 0 or greater than the number of bytes in - * the FIFO. + * The number of valid bytes returned is populated in *numptr; will always + * return at least 1 byte. max must not be 0 or greater than the number of + * bytes in the FIFO. * * Clients are responsible for checking the availability of requested data * using fifo8_num_used(). * * Returns: A pointer to popped data. */ -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num); +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); + +/** + * fifo8_peek_buf: read upto max bytes from the fifo + * @fifo: FIFO to read from + * @max: maximum number of bytes to peek + * @numptr: pointer filled with number of bytes returned (can be NULL) + * + * Peek into a number of elements from the FIFO up to a maximum of max. + * The buffer containing the data peeked into is returned. This buffer points + * directly into the FIFO backing store. Since data is invalidated once any + * of the fifo8_* APIs are called on the FIFO, it is the caller responsibility + * to access it before doing further API calls. + * + * The function may return fewer bytes than requested when the data wraps + * around in the ring buffer; in this case only a contiguous part of the data + * is returned. + * + * The number of valid bytes returned is populated in *numptr; will always + * return at least 1 byte. max must not be 0 or greater than the number of + * bytes in the FIFO. + * + * Clients are responsible for checking the availability of requested data + * using fifo8_num_used(). + * + * Returns: A pointer to peekable data. + */ +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); /** * fifo8_reset: diff --git a/include/qemu/job.h b/include/qemu/job.h index e502787dd8..9ea98b5927 100644 --- a/include/qemu/job.h +++ b/include/qemu/job.h @@ -67,8 +67,6 @@ typedef struct Job { /** * The completion function that will be called when the job completes. - * Called with AioContext lock held, since many callback implementations - * use bdrv_* functions that require to hold the lock. */ BlockCompletionFunc *cb; @@ -264,9 +262,6 @@ struct JobDriver { * * This callback will not be invoked if the job has already failed. * If it fails, abort and then clean will be called. - * - * Called with AioContext lock held, since many callbacs implementations - * use bdrv_* functions that require to hold the lock. */ int (*prepare)(Job *job); @@ -277,9 +272,6 @@ struct JobDriver { * * All jobs will complete with a call to either .commit() or .abort() but * never both. - * - * Called with AioContext lock held, since many callback implementations - * use bdrv_* functions that require to hold the lock. */ void (*commit)(Job *job); @@ -290,9 +282,6 @@ struct JobDriver { * * All jobs will complete with a call to either .commit() or .abort() but * never both. - * - * Called with AioContext lock held, since many callback implementations - * use bdrv_* functions that require to hold the lock. */ void (*abort)(Job *job); @@ -301,9 +290,6 @@ struct JobDriver { * .commit() or .abort(). Regardless of which callback is invoked after * completion, .clean() will always be called, even if the job does not * belong to a transaction group. - * - * Called with AioContext lock held, since many callbacs implementations - * use bdrv_* functions that require to hold the lock. */ void (*clean)(Job *job); @@ -318,17 +304,12 @@ struct JobDriver { * READY). * (If the callback is NULL, the job is assumed to terminate * without I/O.) - * - * Called with AioContext lock held, since many callback implementations - * use bdrv_* functions that require to hold the lock. */ bool (*cancel)(Job *job, bool force); /** * Called when the job is freed. - * Called with AioContext lock held, since many callback implementations - * use bdrv_* functions that require to hold the lock. */ void (*free)(Job *job); }; @@ -424,7 +405,6 @@ void job_ref_locked(Job *job); * Release a reference that was previously acquired with job_ref_locked() or * job_create(). If it's the last reference to the object, it will be freed. * - * Takes AioContext lock internally to invoke a job->driver callback. * Called with job lock held. */ void job_unref_locked(Job *job); diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index 68e70e61aa..5764db157c 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -248,19 +248,19 @@ GSource *iohandler_get_g_source(void); AioContext *iohandler_get_aio_context(void); /** - * qemu_mutex_iothread_locked: Return lock status of the main loop mutex. + * bql_locked: Return lock status of the Big QEMU Lock (BQL) * - * The main loop mutex is the coarsest lock in QEMU, and as such it + * The Big QEMU Lock (BQL) is the coarsest lock in QEMU, and as such it * must always be taken outside other locks. This function helps * functions take different paths depending on whether the current - * thread is running within the main loop mutex. + * thread is running within the BQL. * * This function should never be used in the block layer, because * unit tests, block layer tools and qemu-storage-daemon do not * have a BQL. * Please instead refer to qemu_in_main_thread(). */ -bool qemu_mutex_iothread_locked(void); +bool bql_locked(void); /** * qemu_in_main_thread: return whether it's possible to safely access @@ -312,78 +312,76 @@ bool qemu_in_main_thread(void); } while (0) /** - * qemu_mutex_lock_iothread: Lock the main loop mutex. + * bql_lock: Lock the Big QEMU Lock (BQL). * - * This function locks the main loop mutex. The mutex is taken by + * This function locks the Big QEMU Lock (BQL). The lock is taken by * main() in vl.c and always taken except while waiting on - * external events (such as with select). The mutex should be taken + * external events (such as with select). The lock should be taken * by threads other than the main loop thread when calling * qemu_bh_new(), qemu_set_fd_handler() and basically all other * functions documented in this file. * - * NOTE: tools currently are single-threaded and qemu_mutex_lock_iothread + * NOTE: tools currently are single-threaded and bql_lock * is a no-op there. */ -#define qemu_mutex_lock_iothread() \ - qemu_mutex_lock_iothread_impl(__FILE__, __LINE__) -void qemu_mutex_lock_iothread_impl(const char *file, int line); +#define bql_lock() bql_lock_impl(__FILE__, __LINE__) +void bql_lock_impl(const char *file, int line); /** - * qemu_mutex_unlock_iothread: Unlock the main loop mutex. + * bql_unlock: Unlock the Big QEMU Lock (BQL). * - * This function unlocks the main loop mutex. The mutex is taken by + * This function unlocks the Big QEMU Lock. The lock is taken by * main() in vl.c and always taken except while waiting on - * external events (such as with select). The mutex should be unlocked + * external events (such as with select). The lock should be unlocked * as soon as possible by threads other than the main loop thread, * because it prevents the main loop from processing callbacks, * including timers and bottom halves. * - * NOTE: tools currently are single-threaded and qemu_mutex_unlock_iothread + * NOTE: tools currently are single-threaded and bql_unlock * is a no-op there. */ -void qemu_mutex_unlock_iothread(void); +void bql_unlock(void); /** - * QEMU_IOTHREAD_LOCK_GUARD + * BQL_LOCK_GUARD * - * Wrap a block of code in a conditional qemu_mutex_{lock,unlock}_iothread. + * Wrap a block of code in a conditional bql_{lock,unlock}. */ -typedef struct IOThreadLockAuto IOThreadLockAuto; +typedef struct BQLLockAuto BQLLockAuto; -static inline IOThreadLockAuto *qemu_iothread_auto_lock(const char *file, - int line) +static inline BQLLockAuto *bql_auto_lock(const char *file, int line) { - if (qemu_mutex_iothread_locked()) { + if (bql_locked()) { return NULL; } - qemu_mutex_lock_iothread_impl(file, line); + bql_lock_impl(file, line); /* Anything non-NULL causes the cleanup function to be called */ - return (IOThreadLockAuto *)(uintptr_t)1; + return (BQLLockAuto *)(uintptr_t)1; } -static inline void qemu_iothread_auto_unlock(IOThreadLockAuto *l) +static inline void bql_auto_unlock(BQLLockAuto *l) { - qemu_mutex_unlock_iothread(); + bql_unlock(); } -G_DEFINE_AUTOPTR_CLEANUP_FUNC(IOThreadLockAuto, qemu_iothread_auto_unlock) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(BQLLockAuto, bql_auto_unlock) -#define QEMU_IOTHREAD_LOCK_GUARD() \ - g_autoptr(IOThreadLockAuto) _iothread_lock_auto __attribute__((unused)) \ - = qemu_iothread_auto_lock(__FILE__, __LINE__) +#define BQL_LOCK_GUARD() \ + g_autoptr(BQLLockAuto) _bql_lock_auto __attribute__((unused)) \ + = bql_auto_lock(__FILE__, __LINE__) /* - * qemu_cond_wait_iothread: Wait on condition for the main loop mutex + * qemu_cond_wait_bql: Wait on condition for the Big QEMU Lock (BQL) * - * This function atomically releases the main loop mutex and causes + * This function atomically releases the Big QEMU Lock (BQL) and causes * the calling thread to block on the condition. */ -void qemu_cond_wait_iothread(QemuCond *cond); +void qemu_cond_wait_bql(QemuCond *cond); /* - * qemu_cond_timedwait_iothread: like the previous, but with timeout + * qemu_cond_timedwait_bql: like the previous, but with timeout */ -void qemu_cond_timedwait_iothread(QemuCond *cond, int ms); +void qemu_cond_timedwait_bql(QemuCond *cond, int ms); /* internal interfaces */ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index d30ba73eda..db366d6796 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -678,8 +678,10 @@ typedef struct ThreadContext ThreadContext; * memory area starting at @area with the size of @sz. After a successful call, * each page in the area was faulted in writable at least once, for example, * after allocating file blocks for mapped files. + * + * Return: true on success, else false setting @errp with error. */ -void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, +bool qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, ThreadContext *tc, Error **errp); /** diff --git a/include/qemu/thread.h b/include/qemu/thread.h index dd3822d7ce..fb74e21c08 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -47,7 +47,7 @@ typedef void (*QemuCondWaitFunc)(QemuCond *c, QemuMutex *m, const char *f, typedef bool (*QemuCondTimedWaitFunc)(QemuCond *c, QemuMutex *m, int ms, const char *f, int l); -extern QemuMutexLockFunc qemu_bql_mutex_lock_func; +extern QemuMutexLockFunc bql_mutex_lock_func; extern QemuMutexLockFunc qemu_mutex_lock_func; extern QemuMutexTrylockFunc qemu_mutex_trylock_func; extern QemuRecMutexLockFunc qemu_rec_mutex_lock_func; diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h index 72279f4d25..3afb70160f 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -322,6 +322,8 @@ extern "C" { * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian */ #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ /* * 2 plane YCbCr MSB aligned diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h index 6b9793842c..fc0dcd10ae 100644 --- a/include/standard-headers/linux/fuse.h +++ b/include/standard-headers/linux/fuse.h @@ -209,7 +209,7 @@ * - add FUSE_HAS_EXPIRE_ONLY * * 7.39 - * - add FUSE_DIRECT_IO_RELAX + * - add FUSE_DIRECT_IO_ALLOW_MMAP * - add FUSE_STATX and related structures */ @@ -405,8 +405,7 @@ struct fuse_file_lock { * FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir, * symlink and mknod (single group that matches parent) * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation - * FUSE_DIRECT_IO_RELAX: relax restrictions in FOPEN_DIRECT_IO mode, for now - * allow shared mmap + * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode. */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -445,7 +444,10 @@ struct fuse_file_lock { #define FUSE_HAS_INODE_DAX (1ULL << 33) #define FUSE_CREATE_SUPP_GROUP (1ULL << 34) #define FUSE_HAS_EXPIRE_ONLY (1ULL << 35) -#define FUSE_DIRECT_IO_RELAX (1ULL << 36) +#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36) + +/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ +#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP /** * CUSE INIT request/reply flags diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index e5f558d964..a39193213f 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -80,6 +80,7 @@ #define PCI_HEADER_TYPE_NORMAL 0 #define PCI_HEADER_TYPE_BRIDGE 1 #define PCI_HEADER_TYPE_CARDBUS 2 +#define PCI_HEADER_TYPE_MFD 0x80 /* Multi-Function Device (possible) */ #define PCI_BIST 0x0f /* 8 bits */ #define PCI_BIST_CODE_MASK 0x0f /* Return result */ @@ -637,6 +638,7 @@ #define PCI_EXP_RTCAP 0x1e /* Root Capabilities */ #define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ #define PCI_EXP_RTSTA 0x20 /* Root Status */ +#define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff /* PME Requester ID */ #define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ #define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */ /* @@ -930,12 +932,13 @@ /* Process Address Space ID */ #define PCI_PASID_CAP 0x04 /* PASID feature register */ -#define PCI_PASID_CAP_EXEC 0x02 /* Exec permissions Supported */ -#define PCI_PASID_CAP_PRIV 0x04 /* Privilege Mode Supported */ +#define PCI_PASID_CAP_EXEC 0x0002 /* Exec permissions Supported */ +#define PCI_PASID_CAP_PRIV 0x0004 /* Privilege Mode Supported */ +#define PCI_PASID_CAP_WIDTH 0x1f00 #define PCI_PASID_CTRL 0x06 /* PASID control register */ -#define PCI_PASID_CTRL_ENABLE 0x01 /* Enable bit */ -#define PCI_PASID_CTRL_EXEC 0x02 /* Exec permissions Enable */ -#define PCI_PASID_CTRL_PRIV 0x04 /* Privilege Mode Enable */ +#define PCI_PASID_CTRL_ENABLE 0x0001 /* Enable bit */ +#define PCI_PASID_CTRL_EXEC 0x0002 /* Exec permissions Enable */ +#define PCI_PASID_CTRL_PRIV 0x0004 /* Privilege Mode Enable */ #define PCI_EXT_CAP_PASID_SIZEOF 8 /* Single Root I/O Virtualization */ @@ -975,6 +978,8 @@ #define PCI_LTR_VALUE_MASK 0x000003ff #define PCI_LTR_SCALE_MASK 0x00001c00 #define PCI_LTR_SCALE_SHIFT 10 +#define PCI_LTR_NOSNOOP_VALUE 0x03ff0000 /* Max No-Snoop Latency Value */ +#define PCI_LTR_NOSNOOP_SCALE 0x1c000000 /* Scale for Max Value */ #define PCI_EXT_CAP_LTR_SIZEOF 8 /* Access Control Service */ @@ -1042,9 +1047,16 @@ #define PCI_EXP_DPC_STATUS 0x08 /* DPC Status */ #define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */ #define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR 0x0000 /* Uncorrectable error */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE 0x0002 /* Rcvd ERR_NONFATAL */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE 0x0004 /* Rcvd ERR_FATAL */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT 0x0006 /* Reason in Trig Reason Extension field */ #define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */ #define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */ #define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO 0x0000 /* RP PIO error */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER 0x0020 /* DPC SW Trigger bit */ +#define PCI_EXP_DPC_RP_PIO_FEP 0x1f00 /* RP PIO First Err Ptr */ #define PCI_EXP_DPC_SOURCE_ID 0x0A /* DPC Source Identifier */ @@ -1088,6 +1100,8 @@ #define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */ #define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */ #define PCI_L1SS_CTL2 0x0c /* Control 2 Register */ +#define PCI_L1SS_CTL2_T_PWR_ON_SCALE 0x00000003 /* T_POWER_ON Scale */ +#define PCI_L1SS_CTL2_T_PWR_ON_VALUE 0x000000f8 /* T_POWER_ON Value */ /* Designated Vendor-Specific (DVSEC, PCI_EXT_CAP_ID_DVSEC) */ #define PCI_DVSEC_HEADER1 0x4 /* Designated Vendor-Specific Header1 */ diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h index 5ad07e134a..fd54044936 100644 --- a/include/standard-headers/linux/vhost_types.h +++ b/include/standard-headers/linux/vhost_types.h @@ -185,5 +185,12 @@ struct vhost_vdpa_iova_range { * DRIVER_OK */ #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6 +/* Device may expose the virtqueue's descriptor area, driver area and + * device area to a different group for ASID binding than where its + * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID. + */ +#define VHOST_BACKEND_F_DESC_ASID 0x7 +/* IOTLB don't flush memory mapping across device reset */ +#define VHOST_BACKEND_F_IOTLB_PERSIST 0x8 #endif diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h index 8a7d0dc8b0..bfd1ca643e 100644 --- a/include/standard-headers/linux/virtio_config.h +++ b/include/standard-headers/linux/virtio_config.h @@ -103,6 +103,11 @@ */ #define VIRTIO_F_NOTIFICATION_DATA 38 +/* This feature indicates that the driver uses the data provided by the device + * as a virtqueue identifier in available buffer notifications. + */ +#define VIRTIO_F_NOTIF_CONFIG_DATA 39 + /* * This feature indicates that the driver can reset a queue individually. */ diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h index be912cfc95..b7fdfd0668 100644 --- a/include/standard-headers/linux/virtio_pci.h +++ b/include/standard-headers/linux/virtio_pci.h @@ -166,6 +166,17 @@ struct virtio_pci_common_cfg { uint32_t queue_used_hi; /* read-write */ }; +/* + * Warning: do not use sizeof on this: use offsetofend for + * specific fields you need. + */ +struct virtio_pci_modern_common_cfg { + struct virtio_pci_common_cfg cfg; + + uint16_t queue_notify_data; /* read-write */ + uint16_t queue_reset; /* read-write */ +}; + /* Fields in VIRTIO_PCI_CAP_PCI_CFG: */ struct virtio_pci_cfg_cap { struct virtio_pci_cap cap; diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index 39326f1d4f..0e411aaa29 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -47,7 +47,15 @@ OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass, struct HostMemoryBackendClass { ObjectClass parent_class; - void (*alloc)(HostMemoryBackend *backend, Error **errp); + /** + * alloc: Allocate memory from backend. + * + * @backend: the #HostMemoryBackend. + * @errp: pointer to Error*, to store an error if it happens. + * + * Return: true on success, else false setting @errp with error. + */ + bool (*alloc)(HostMemoryBackend *backend, Error **errp); }; /** diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h new file mode 100644 index 0000000000..9af27ebd6c --- /dev/null +++ b/include/sysemu/iommufd.h @@ -0,0 +1,36 @@ +#ifndef SYSEMU_IOMMUFD_H +#define SYSEMU_IOMMUFD_H + +#include "qom/object.h" +#include "exec/hwaddr.h" +#include "exec/cpu-common.h" + +#define TYPE_IOMMUFD_BACKEND "iommufd" +OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND) + +struct IOMMUFDBackendClass { + ObjectClass parent_class; +}; + +struct IOMMUFDBackend { + Object parent; + + /*< protected >*/ + int fd; /* /dev/iommu file descriptor */ + bool owned; /* is the /dev/iommu opened internally */ + uint32_t users; + + /*< public >*/ +}; + +int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp); +void iommufd_backend_disconnect(IOMMUFDBackend *be); + +int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id, + Error **errp); +void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id); +int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova, + ram_addr_t size, void *vaddr, bool readonly); +int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id, + hwaddr iova, ram_addr_t size); +#endif diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h index 85f05b0e46..b5d5fd3463 100644 --- a/include/sysemu/qtest.h +++ b/include/sysemu/qtest.h @@ -23,6 +23,7 @@ static inline bool qtest_enabled(void) return qtest_allowed; } +#ifndef CONFIG_USER_ONLY void qtest_send_prefix(CharBackend *chr); void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, const char *fmt, ...); void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words)); @@ -35,5 +36,6 @@ void qtest_server_set_send_handler(void (*send)(void *, const char *), void qtest_server_inproc_recv(void *opaque, const char *buf); int64_t qtest_get_virtual_clock(void); +#endif #endif diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 08aae5869f..83995ae4bd 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -70,6 +70,11 @@ int replay_get_instructions(void); /*! Updates instructions counter in replay mode. */ void replay_account_executed_instructions(void); +/** + * replay_can_wait: check if we should pause for wait-io + */ +bool replay_can_wait(void); + /* Processing clocks and other time sources */ /*! Save the specified clock */ diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h index c8c2bd8a61..0117d243c4 100644 --- a/include/sysemu/runstate.h +++ b/include/sysemu/runstate.h @@ -40,6 +40,15 @@ static inline bool shutdown_caused_by_guest(ShutdownCause cause) return cause >= SHUTDOWN_CAUSE_GUEST_SHUTDOWN; } +/* + * In a "live" state, the vcpu clock is ticking, and the runstate notifiers + * think we are running. + */ +static inline bool runstate_is_live(RunState state) +{ + return state == RUN_STATE_RUNNING || state == RUN_STATE_SUSPENDED; +} + void vm_start(void); /** @@ -48,9 +57,20 @@ void vm_start(void); * @step_pending: whether any of the CPUs is about to be single-stepped by gdb */ int vm_prepare_start(bool step_pending); + +/** + * vm_resume: If @state is a live state, start the vm and set the state, + * else just set the state. + * + * @state: the state to restore + */ +void vm_resume(RunState state); + int vm_stop(RunState state); int vm_stop_force_state(RunState state); int vm_shutdown(void); +void vm_set_suspended(bool suspended); +bool vm_get_suspended(void); typedef enum WakeupReason { /* Always keep QEMU_WAKEUP_REASON_NONE = 0 */ diff --git a/include/ui/rect.h b/include/ui/rect.h index 94898f92d0..68f05d78a8 100644 --- a/include/ui/rect.h +++ b/include/ui/rect.h @@ -19,7 +19,7 @@ static inline void qemu_rect_init(QemuRect *rect, uint16_t width, uint16_t height) { rect->x = x; - rect->y = x; + rect->y = y; rect->width = width; rect->height = height; } |