diff options
Diffstat (limited to 'include')
33 files changed, 331 insertions, 145 deletions
diff --git a/include/block/block-common.h b/include/block/block-common.h index 41686810de..469300fe8d 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -45,11 +45,14 @@ * - co_wrapper_mixed_bdrv_rdlock are co_wrapper_mixed functions but * automatically take and release the graph rdlock when creating a new * coroutine. + * + * These functions should not be called from a coroutine_fn; instead, + * call the wrapped function directly. */ -#define co_wrapper -#define co_wrapper_mixed -#define co_wrapper_bdrv_rdlock -#define co_wrapper_mixed_bdrv_rdlock +#define co_wrapper no_coroutine_fn +#define co_wrapper_mixed no_coroutine_fn coroutine_mixed_fn +#define co_wrapper_bdrv_rdlock no_coroutine_fn +#define co_wrapper_mixed_bdrv_rdlock no_coroutine_fn coroutine_mixed_fn #include "block/blockjob.h" diff --git a/include/block/block-io.h b/include/block/block-io.h index 3398351596..614cbd7eda 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -76,9 +76,15 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); -int64_t bdrv_nb_sectors(BlockDriverState *bs); -int64_t bdrv_getlength(BlockDriverState *bs); -int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); +int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs); +int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs); + +int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs); +int64_t co_wrapper_mixed bdrv_getlength(BlockDriverState *bs); + +int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs); +int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs); + BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts, BlockDriverState *in_bs, Error **errp); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); @@ -136,16 +142,23 @@ bool bdrv_is_read_only(BlockDriverState *bs); bool bdrv_is_writable(BlockDriverState *bs); bool bdrv_is_sg(BlockDriverState *bs); int bdrv_get_flags(BlockDriverState *bs); -bool bdrv_is_inserted(BlockDriverState *bs); -void bdrv_lock_medium(BlockDriverState *bs, bool locked); -void bdrv_eject(BlockDriverState *bs, bool eject_flag); + +bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs); +bool co_wrapper bdrv_is_inserted(BlockDriverState *bs); + +void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked); +void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag); + const char *bdrv_get_format_name(BlockDriverState *bs); bool bdrv_supports_compressed_writes(BlockDriverState *bs); const char *bdrv_get_node_name(const BlockDriverState *bs); const char *bdrv_get_device_name(const BlockDriverState *bs); const char *bdrv_get_device_or_node_name(const BlockDriverState *bs); -int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); + +int coroutine_fn bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); +int co_wrapper_mixed bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); + ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs, Error **errp); BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs); @@ -178,7 +191,10 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size); void bdrv_enable_copy_on_read(BlockDriverState *bs); void bdrv_disable_copy_on_read(BlockDriverState *bs); -void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event); +void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs, + BlkdebugEvent event); +void co_wrapper_mixed bdrv_debug_event(BlockDriverState *bs, + BlkdebugEvent event); #define BLKDBG_EVENT(child, evt) \ do { \ @@ -213,15 +229,10 @@ AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs); */ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx); -/** - * Transfer control to @co in the aio context of @bs - */ -void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co); - AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c); -void bdrv_io_plug(BlockDriverState *bs); -void bdrv_io_unplug(BlockDriverState *bs); +void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs); +void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs); bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 887ace7dbd..ba2e0fce25 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -680,8 +680,10 @@ struct BlockDriver { int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset, bool exact, PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); - int64_t (*bdrv_getlength)(BlockDriverState *bs); - int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs); + int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs); + int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)( + BlockDriverState *bs); + BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs, Error **errp); @@ -691,22 +693,23 @@ struct BlockDriver { int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset); - int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi); + int coroutine_fn (*bdrv_co_get_info)(BlockDriverState *bs, + BlockDriverInfo *bdi); ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs, Error **errp); BlockStatsSpecific *(*bdrv_get_specific_stats)(BlockDriverState *bs); - int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_save_vmstate)( + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_save_vmstate)( BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); - int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_load_vmstate)( + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_load_vmstate)( BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); /* removable device specific */ - bool (*bdrv_is_inserted)(BlockDriverState *bs); - void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag); - void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked); + bool coroutine_fn (*bdrv_co_is_inserted)(BlockDriverState *bs); + void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag); + void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked); /* to control generic scsi devices */ BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs, @@ -722,11 +725,12 @@ struct BlockDriver { int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_check)( BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix); - void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event); + void coroutine_fn (*bdrv_co_debug_event)(BlockDriverState *bs, + BlkdebugEvent event); /* io queue for linux-aio */ - void (*bdrv_io_plug)(BlockDriverState *bs); - void (*bdrv_io_unplug)(BlockDriverState *bs); + void coroutine_fn (*bdrv_co_io_plug)(BlockDriverState *bs); + void coroutine_fn (*bdrv_co_io_unplug)(BlockDriverState *bs); /** * bdrv_drain_begin is called if implemented in the beginning of a diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h index 44367219f4..4430bf4c4a 100644 --- a/include/block/block_int-io.h +++ b/include/block/block_int-io.h @@ -122,7 +122,10 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset, BdrvRequestFlags read_flags, BdrvRequestFlags write_flags); -int refresh_total_sectors(BlockDriverState *bs, int64_t hint); +int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs, + int64_t hint); +int co_wrapper_mixed +bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint); BdrvChild *bdrv_cow_child(BlockDriverState *bs); BdrvChild *bdrv_filter_child(BlockDriverState *bs); diff --git a/include/block/nbd.h b/include/block/nbd.h index 4ede3b2bd0..a4c98169c3 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -24,6 +24,7 @@ #include "io/channel-socket.h" #include "crypto/tlscreds.h" #include "qapi/error.h" +#include "qemu/bswap.h" extern const BlockExportDriver blk_exp_nbd; diff --git a/include/block/qapi.h b/include/block/qapi.h index 865fb974d4..8773b9b191 100644 --- a/include/block/qapi.h +++ b/include/block/qapi.h @@ -35,11 +35,21 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, int bdrv_query_snapshot_info_list(BlockDriverState *bs, SnapshotInfoList **p_list, Error **errp); +void bdrv_query_block_node_info(BlockDriverState *bs, + BlockNodeInfo **p_info, + Error **errp); void bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, + bool flat, + bool skip_implicit_filters, Error **errp); +void bdrv_query_block_graph_info(BlockDriverState *bs, + BlockGraphInfo **p_info, + Error **errp); void bdrv_snapshot_dump(QEMUSnapshotInfo *sn); -void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec); -void bdrv_image_info_dump(ImageInfo *info); +void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec, + const char *prefix, + int indentation); +void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol); #endif diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h index c4b1bda632..7a3f04b58c 100644 --- a/include/exec/helper-proto.h +++ b/include/exec/helper-proto.h @@ -6,34 +6,49 @@ #include "exec/helper-head.h" +/* + * Work around an issue with --enable-lto, in which GCC's ipa-split pass + * decides to split out the noreturn code paths that raise an exception, + * taking the __builtin_return_address() along into the new function, + * where it no longer computes a value that returns to TCG generated code. + * Despite the name, the noinline attribute affects splitter, so this + * prevents the optimization in question. Given that helpers should not + * otherwise be called directly, this should have any other visible effect. + * + * See https://gitlab.com/qemu-project/qemu/-/issues/1454 + */ +#define DEF_HELPER_ATTR __attribute__((noinline)) + #define DEF_HELPER_FLAGS_0(name, flags, ret) \ -dh_ctype(ret) HELPER(name) (void); +dh_ctype(ret) HELPER(name) (void) DEF_HELPER_ATTR; #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ -dh_ctype(ret) HELPER(name) (dh_ctype(t1)); +dh_ctype(ret) HELPER(name) (dh_ctype(t1)) DEF_HELPER_ATTR; #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ -dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)); +dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) DEF_HELPER_ATTR; #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ -dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3)); +dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), \ + dh_ctype(t3)) DEF_HELPER_ATTR; #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ - dh_ctype(t4)); + dh_ctype(t4)) DEF_HELPER_ATTR; #define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ - dh_ctype(t4), dh_ctype(t5)); + dh_ctype(t4), dh_ctype(t5)) DEF_HELPER_ATTR; #define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ - dh_ctype(t4), dh_ctype(t5), dh_ctype(t6)); + dh_ctype(t4), dh_ctype(t5), \ + dh_ctype(t6)) DEF_HELPER_ATTR; #define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7) \ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \ - dh_ctype(t7)); + dh_ctype(t7)) DEF_HELPER_ATTR; #define IN_HELPER_PROTO @@ -51,5 +66,6 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ #undef DEF_HELPER_FLAGS_5 #undef DEF_HELPER_FLAGS_6 #undef DEF_HELPER_FLAGS_7 +#undef DEF_HELPER_ATTR #endif /* HELPER_PROTO_H */ diff --git a/include/exec/memory.h b/include/exec/memory.h index c37ffdbcd1..2e602a2fad 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -129,6 +129,32 @@ struct IOMMUTLBEntry { /* * Bitmap for different IOMMUNotifier capabilities. Each notifier can * register with one or multiple IOMMU Notifier capability bit(s). + * + * Normally there're two use cases for the notifiers: + * + * (1) When the device needs accurate synchronizations of the vIOMMU page + * tables, it needs to register with both MAP|UNMAP notifies (which + * is defined as IOMMU_NOTIFIER_IOTLB_EVENTS below). + * + * Regarding to accurate synchronization, it's when the notified + * device maintains a shadow page table and must be notified on each + * guest MAP (page table entry creation) and UNMAP (invalidation) + * events (e.g. VFIO). Both notifications must be accurate so that + * the shadow page table is fully in sync with the guest view. + * + * (2) When the device doesn't need accurate synchronizations of the + * vIOMMU page tables, it needs to register only with UNMAP or + * DEVIOTLB_UNMAP notifies. + * + * It's when the device maintains a cache of IOMMU translations + * (IOTLB) and is able to fill that cache by requesting translations + * from the vIOMMU through a protocol similar to ATS (Address + * Translation Service). + * + * Note that in this mode the vIOMMU will not maintain a shadowed + * page table for the address space, and the UNMAP messages can cover + * more than the pages that used to get mapped. The IOMMU notifiee + * should be able to take care of over-sized invalidations. */ typedef enum { IOMMU_NOTIFIER_NONE = 0, diff --git a/include/hw/acpi/acpi_aml_interface.h b/include/hw/acpi/acpi_aml_interface.h index 436da069d6..11748a8866 100644 --- a/include/hw/acpi/acpi_aml_interface.h +++ b/include/hw/acpi/acpi_aml_interface.h @@ -3,6 +3,7 @@ #include "qom/object.h" #include "hw/acpi/aml-build.h" +#include "hw/qdev-core.h" #define TYPE_ACPI_DEV_AML_IF "acpi-dev-aml-interface" typedef struct AcpiDevAmlIfClass AcpiDevAmlIfClass; @@ -46,4 +47,6 @@ static inline void call_dev_aml_func(DeviceState *dev, Aml *scope) } } +void qbus_build_aml(BusState *bus, Aml *scope); + #endif diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h index ea6056ab92..a1648220ff 100644 --- a/include/hw/acpi/acpi_dev_interface.h +++ b/include/hw/acpi/acpi_dev_interface.h @@ -52,8 +52,7 @@ struct AcpiDeviceIfClass { /* <public> */ void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev); - void (*madt_cpu)(AcpiDeviceIf *adev, int uid, - const CPUArchIdList *apic_ids, GArray *entry, + void (*madt_cpu)(int uid, const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); }; #endif diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h index b5deee0a9d..467a99461c 100644 --- a/include/hw/acpi/pci.h +++ b/include/hw/acpi/pci.h @@ -27,6 +27,7 @@ #define HW_ACPI_PCI_H #include "hw/acpi/bios-linker-loader.h" +#include "hw/acpi/acpi_aml_interface.h" typedef struct AcpiMcfgInfo { uint64_t base; @@ -36,4 +37,7 @@ typedef struct AcpiMcfgInfo { void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info, const char *oem_id, const char *oem_table_id); Aml *aml_pci_device_dsm(void); + +void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus); +void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope); #endif diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index c7dd59d7f1..e1ddbea96b 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -109,14 +109,19 @@ typedef enum VirtMSIControllerType { } VirtMSIControllerType; typedef enum VirtGICType { - VIRT_GIC_VERSION_MAX, - VIRT_GIC_VERSION_HOST, - VIRT_GIC_VERSION_2, - VIRT_GIC_VERSION_3, - VIRT_GIC_VERSION_4, + VIRT_GIC_VERSION_MAX = 0, + VIRT_GIC_VERSION_HOST = 1, + /* The concrete GIC values have to match the GIC version number */ + VIRT_GIC_VERSION_2 = 2, + VIRT_GIC_VERSION_3 = 3, + VIRT_GIC_VERSION_4 = 4, VIRT_GIC_VERSION_NOSEL, } VirtGICType; +#define VIRT_GIC_VERSION_2_MASK BIT(VIRT_GIC_VERSION_2) +#define VIRT_GIC_VERSION_3_MASK BIT(VIRT_GIC_VERSION_3) +#define VIRT_GIC_VERSION_4_MASK BIT(VIRT_GIC_VERSION_4) + struct VirtMachineClass { MachineClass parent; bool disallow_affinity_adjustment; diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h index dc2c90eedc..926322e242 100644 --- a/include/hw/char/pl011.h +++ b/include/hw/char/pl011.h @@ -27,6 +27,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(PL011State, PL011) /* This shares the same struct (and cast macro) as the base pl011 device */ #define TYPE_PL011_LUMINARY "pl011_luminary" +/* Depth of UART FIFO in bytes, when FIFO mode is enabled (else depth == 1) */ +#define PL011_FIFO_DEPTH 16 + struct PL011State { SysBusDevice parent_obj; @@ -39,7 +42,7 @@ struct PL011State { uint32_t dmacr; uint32_t int_enabled; uint32_t int_level; - uint32_t read_fifo[16]; + uint32_t read_fifo[PL011_FIFO_DEPTH]; uint32_t ilpr; uint32_t ibrd; uint32_t fbrd; diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 46d973e629..89dcbc5e1e 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -109,7 +109,43 @@ struct VTDAddressSpace { QLIST_ENTRY(VTDAddressSpace) next; /* Superset of notifier flags that this address space has */ IOMMUNotifierFlag notifier_flags; - IOVATree *iova_tree; /* Traces mapped IOVA ranges */ + /* + * @iova_tree traces mapped IOVA ranges. + * + * The tree is not needed if no MAP notifier is registered with current + * VTD address space, because all guest invalidate commands can be + * directly passed to the IOMMU UNMAP notifiers without any further + * reshuffling. + * + * The tree OTOH is required for MAP typed iommu notifiers for a few + * reasons. + * + * Firstly, there's no way to identify whether an PSI (Page Selective + * Invalidations) or DSI (Domain Selective Invalidations) event is an + * MAP or UNMAP event within the message itself. Without having prior + * knowledge of existing state vIOMMU doesn't know whether it should + * notify MAP or UNMAP for a PSI message it received when caching mode + * is enabled (for MAP notifiers). + * + * Secondly, PSI messages received from guest driver can be enlarged in + * range, covers but not limited to what the guest driver wanted to + * invalidate. When the range to invalidates gets bigger than the + * limit of a PSI message, it can even become a DSI which will + * invalidate the whole domain. If the vIOMMU directly notifies the + * registered device with the unmodified range, it may confuse the + * registered drivers (e.g. vfio-pci) on either: + * + * (1) Trying to map the same region more than once (for + * VFIO_IOMMU_MAP_DMA, -EEXIST will trigger), or, + * + * (2) Trying to UNMAP a range that is still partially mapped. + * + * That accuracy is not required for UNMAP-only notifiers, but it is a + * must-to-have for notifiers registered with MAP events, because the + * vIOMMU needs to make sure the shadow page table is always in sync + * with the guest IOMMU pgtables for a device. + */ + IOVATree *iova_tree; }; struct VTDIOTLBEntry { diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h index fad97a891d..e8af61f194 100644 --- a/include/hw/i386/microvm.h +++ b/include/hw/i386/microvm.h @@ -50,8 +50,9 @@ */ /* Platform virtio definitions */ -#define VIRTIO_MMIO_BASE 0xfeb00000 -#define VIRTIO_CMDLINE_MAXLEN 64 +#define VIRTIO_MMIO_BASE 0xfeb00000 +#define VIRTIO_CMDLINE_MAXLEN 64 +#define VIRTIO_CMDLINE_TOTAL_MAX_LEN ((VIRTIO_CMDLINE_MAXLEN + 1) * 16) #define GED_MMIO_BASE 0xfea00000 #define GED_MMIO_BASE_MEMHP (GED_MMIO_BASE + 0x100) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 88a120bc23..66e3d059ef 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -9,7 +9,6 @@ #include "hw/block/flash.h" #include "hw/i386/x86.h" -#include "hw/acpi/acpi_dev_interface.h" #include "hw/hotplug.h" #include "qom/object.h" #include "hw/i386/sgx-epc.h" @@ -193,9 +192,8 @@ bool pc_system_ovmf_table_find(const char *entry, uint8_t **data, void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size); /* hw/i386/acpi-common.c */ -void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, - const CPUArchIdList *apic_ids, GArray *entry, - bool force_enabled); +void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids, + GArray *entry, bool force_enabled); /* sgx.c */ void pc_machine_init_sgx_epc(PCMachineState *pcms); diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index 6c8a8a92cb..25acd5c34c 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -86,7 +86,6 @@ bool isa_realize_and_unref(ISADevice *dev, ISABus *bus, Error **errp); ISADevice *isa_create_simple(ISABus *bus, const char *name); ISADevice *isa_vga_init(ISABus *bus); -void isa_build_aml(ISABus *bus, Aml *scope); /** * isa_register_ioport: Install an I/O port region on the ISA bus. diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 2e503904dc..990dcdbb2e 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -140,6 +140,15 @@ void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key, bool read_only); /** + * fw_cfg_read_bytes_ptr: + * @s: fw_cfg device being modified + * @key: selector key value for new fw_cfg item + * + * Reads an existing fw_cfg data pointer. + */ +void *fw_cfg_read_bytes_ptr(FWCfgState *s, uint16_t key); + +/** * fw_cfg_add_string: * @s: fw_cfg device being modified * @key: selector key value for new fw_cfg item diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 85ee458cd2..d5a40cd058 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -270,7 +270,7 @@ typedef void (*pci_bus_dev_fn)(PCIBus *b, PCIDevice *d, void *opaque); typedef void (*pci_bus_fn)(PCIBus *b, void *opaque); typedef void *(*pci_bus_ret_fn)(PCIBus *b, void *opaque); -bool pci_bus_is_express(PCIBus *bus); +bool pci_bus_is_express(const PCIBus *bus); void pci_root_bus_init(PCIBus *bus, size_t bus_size, DeviceState *parent, const char *name, diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index fd484afb30..6c40e3733f 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -63,7 +63,8 @@ struct PCIESlot { /* Indicates whether any type of hot-plug is allowed on the slot */ bool hotplug; - bool native_hotplug; + /* broken ACPI hotplug compat knob to preserve 6.1 ABI intact */ + bool hide_native_hotplug_cap; QLIST_ENTRY(PCIESlot) next; }; diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h index 1891a19b21..d78e979f05 100644 --- a/include/monitor/hmp-target.h +++ b/include/monitor/hmp-target.h @@ -51,5 +51,11 @@ void hmp_info_local_apic(Monitor *mon, const QDict *qdict); void hmp_info_sev(Monitor *mon, const QDict *qdict); void hmp_info_sgx(Monitor *mon, const QDict *qdict); void hmp_info_via(Monitor *mon, const QDict *qdict); +void hmp_memory_dump(Monitor *mon, const QDict *qdict); +void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict); +void hmp_info_registers(Monitor *mon, const QDict *qdict); +void hmp_gva2gpa(Monitor *mon, const QDict *qdict); +void hmp_gpa2hva(Monitor *mon, const QDict *qdict); +void hmp_gpa2hpa(Monitor *mon, const QDict *qdict); #endif /* MONITOR_HMP_TARGET_H */ diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 1b3bdcb446..2220f14fc9 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -18,6 +18,8 @@ #include "qapi/qapi-types-common.h" bool hmp_handle_error(Monitor *mon, Error *err); +void hmp_help_cmd(Monitor *mon, const char *name); +strList *hmp_split_at_comma(const char *str); void hmp_info_name(Monitor *mon, const QDict *qdict); void hmp_info_version(Monitor *mon, const QDict *qdict); @@ -54,6 +56,7 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict); void hmp_cont(Monitor *mon, const QDict *qdict); void hmp_system_wakeup(Monitor *mon, const QDict *qdict); void hmp_nmi(Monitor *mon, const QDict *qdict); +void hmp_info_network(Monitor *mon, const QDict *qdict); void hmp_set_link(Monitor *mon, const QDict *qdict); void hmp_balloon(Monitor *mon, const QDict *qdict); void hmp_loadvm(Monitor *mon, const QDict *qdict); @@ -77,6 +80,9 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target, const char *arg, const char *read_only, bool force, Error **errp); #endif +void hmp_change_medium(Monitor *mon, const char *device, const char *target, + const char *arg, const char *read_only, bool force, + Error **errp); void hmp_migrate(Monitor *mon, const QDict *qdict); void hmp_device_add(Monitor *mon, const QDict *qdict); void hmp_device_del(Monitor *mon, const QDict *qdict); @@ -150,6 +156,27 @@ void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict); void hmp_human_readable_text_helper(Monitor *mon, HumanReadableText *(*qmp_handler)(Error **)); void hmp_info_stats(Monitor *mon, const QDict *qdict); +void hmp_singlestep(Monitor *mon, const QDict *qdict); +void hmp_watchdog_action(Monitor *mon, const QDict *qdict); void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict); +void hmp_info_capture(Monitor *mon, const QDict *qdict); +void hmp_stopcapture(Monitor *mon, const QDict *qdict); +void hmp_wavcapture(Monitor *mon, const QDict *qdict); +void hmp_trace_event(Monitor *mon, const QDict *qdict); +void hmp_trace_file(Monitor *mon, const QDict *qdict); +void hmp_info_trace_events(Monitor *mon, const QDict *qdict); +void hmp_help(Monitor *mon, const QDict *qdict); +void hmp_info_help(Monitor *mon, const QDict *qdict); +void hmp_info_sync_profile(Monitor *mon, const QDict *qdict); +void hmp_info_history(Monitor *mon, const QDict *qdict); +void hmp_logfile(Monitor *mon, const QDict *qdict); +void hmp_log(Monitor *mon, const QDict *qdict); +void hmp_gdbserver(Monitor *mon, const QDict *qdict); +void hmp_print(Monitor *mon, const QDict *qdict); +void hmp_sum(Monitor *mon, const QDict *qdict); +void hmp_ioport_read(Monitor *mon, const QDict *qdict); +void hmp_ioport_write(Monitor *mon, const QDict *qdict); +void hmp_boot_set(Monitor *mon, const QDict *qdict); +void hmp_info_mtree(Monitor *mon, const QDict *qdict); #endif diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 1e6f4c9bd7..033390f699 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -35,6 +35,7 @@ int monitor_puts(Monitor *mon, const char *str); int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) G_GNUC_PRINTF(2, 0); int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3); +void monitor_printc(Monitor *mon, int ch); void monitor_flush(Monitor *mon); int monitor_set_cpu(Monitor *mon, int cpu_index); int monitor_get_cpu_index(Monitor *mon); diff --git a/include/monitor/qmp-helpers.h b/include/monitor/qmp-helpers.h index 4718c63c73..318c3357a2 100644 --- a/include/monitor/qmp-helpers.h +++ b/include/monitor/qmp-helpers.h @@ -22,5 +22,8 @@ bool qmp_add_client_vnc(int fd, bool has_skipauth, bool skipauth, bool qmp_add_client_dbus_display(int fd, bool has_skipauth, bool skipauth, bool has_tls, bool tls, Error **errp); #endif +bool qmp_add_client_char(int fd, bool has_skipauth, bool skipauth, + bool has_tls, bool tls, const char *protocol, + Error **errp); #endif diff --git a/include/net/net.h b/include/net/net.h index dc20b31e9f..fad589cc1d 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -115,6 +115,8 @@ struct NetClientState { QTAILQ_HEAD(, NetFilterState) filters; }; +typedef QTAILQ_HEAD(NetClientStateList, NetClientState) NetClientStateList; + typedef struct NICState { NetClientState *ncs; NICConf *conf; @@ -196,7 +198,6 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models, const char *default_model); void print_net_client(Monitor *mon, NetClientState *nc); -void hmp_info_network(Monitor *mon, const QDict *qdict); void net_socket_rs_init(SocketReadState *rs, SocketReadStateFinalize *finalize, bool vnet_hdr); @@ -222,6 +223,7 @@ extern NICInfo nd_table[MAX_NICS]; extern const char *host_net_devices[]; /* from net.c */ +extern NetClientStateList net_clients; bool netdev_is_modern(const char *optarg); void netdev_parse_modern(const char *optarg); void net_client_parse(QemuOptsList *opts_list, const char *str); diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h index 346d05f2aa..3cbe52246b 100644 --- a/include/qemu/bswap.h +++ b/include/qemu/bswap.h @@ -1,97 +1,44 @@ #ifndef BSWAP_H #define BSWAP_H -#ifdef CONFIG_MACHINE_BSWAP_H -# include <sys/endian.h> -# include <machine/bswap.h> -#elif defined(__FreeBSD__) -# include <sys/endian.h> -#elif defined(__HAIKU__) -# include <endian.h> -#elif defined(CONFIG_BYTESWAP_H) -# include <byteswap.h> -#define BSWAP_FROM_BYTESWAP -# else -#define BSWAP_FROM_FALLBACKS -#endif /* ! CONFIG_MACHINE_BSWAP_H */ - #ifdef __cplusplus extern "C" { #endif -#ifdef BSWAP_FROM_BYTESWAP -static inline uint16_t bswap16(uint16_t x) -{ - return bswap_16(x); -} - -static inline uint32_t bswap32(uint32_t x) -{ - return bswap_32(x); -} - -static inline uint64_t bswap64(uint64_t x) -{ - return bswap_64(x); -} -#endif - -#ifdef BSWAP_FROM_FALLBACKS -static inline uint16_t bswap16(uint16_t x) -{ - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); -} - -static inline uint32_t bswap32(uint32_t x) -{ - return (((x & 0x000000ffU) << 24) | - ((x & 0x0000ff00U) << 8) | - ((x & 0x00ff0000U) >> 8) | - ((x & 0xff000000U) >> 24)); -} - -static inline uint64_t bswap64(uint64_t x) -{ - return (((x & 0x00000000000000ffULL) << 56) | - ((x & 0x000000000000ff00ULL) << 40) | - ((x & 0x0000000000ff0000ULL) << 24) | - ((x & 0x00000000ff000000ULL) << 8) | - ((x & 0x000000ff00000000ULL) >> 8) | - ((x & 0x0000ff0000000000ULL) >> 24) | - ((x & 0x00ff000000000000ULL) >> 40) | - ((x & 0xff00000000000000ULL) >> 56)); -} -#endif - -#undef BSWAP_FROM_BYTESWAP -#undef BSWAP_FROM_FALLBACKS +#undef bswap16 +#define bswap16(_x) __builtin_bswap16(_x) +#undef bswap32 +#define bswap32(_x) __builtin_bswap32(_x) +#undef bswap64 +#define bswap64(_x) __builtin_bswap64(_x) static inline void bswap16s(uint16_t *s) { - *s = bswap16(*s); + *s = __builtin_bswap16(*s); } static inline void bswap32s(uint32_t *s) { - *s = bswap32(*s); + *s = __builtin_bswap32(*s); } static inline void bswap64s(uint64_t *s) { - *s = bswap64(*s); + *s = __builtin_bswap64(*s); } #if HOST_BIG_ENDIAN #define be_bswap(v, size) (v) -#define le_bswap(v, size) glue(bswap, size)(v) +#define le_bswap(v, size) glue(__builtin_bswap, size)(v) #define be_bswaps(v, size) -#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0) +#define le_bswaps(p, size) \ + do { *p = glue(__builtin_bswap, size)(*p); } while (0) #else #define le_bswap(v, size) (v) -#define be_bswap(v, size) glue(bswap, size)(v) +#define be_bswap(v, size) glue(__builtin_bswap, size)(v) #define le_bswaps(v, size) -#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0) +#define be_bswaps(p, size) \ + do { *p = glue(__builtin_bswap, size)(*p); } while (0) #endif /** diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index c850001408..88c9facbf2 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -171,7 +171,51 @@ extern "C" { * .... * } */ +#ifdef __clang__ +#define coroutine_fn __attribute__((__annotate__("coroutine_fn"))) +#else #define coroutine_fn +#endif + +/** + * Mark a function that can suspend when executed in coroutine context, + * but can handle running in non-coroutine context too. + */ +#ifdef __clang__ +#define coroutine_mixed_fn __attribute__((__annotate__("coroutine_mixed_fn"))) +#else +#define coroutine_mixed_fn +#endif + +/** + * Mark a function that should not be called from a coroutine context. + * Usually there will be an analogous, coroutine_fn function that should + * be used instead. + * + * When the function is also marked as coroutine_mixed_fn, the function should + * only be called if the caller does not know whether it is in coroutine + * context. + * + * Functions that are only no_coroutine_fn, on the other hand, should not + * be called from within coroutines at all. This for example includes + * functions that block. + * + * In the future it would be nice to enable compiler or static checker + * support for catching such errors. This annotation is the first step + * towards this, and in the meantime it serves as documentation. + * + * For example: + * + * static void no_coroutine_fn foo(void) { + * .... + * } + */ +#ifdef __clang__ +#define no_coroutine_fn __attribute__((__annotate__("no_coroutine_fn"))) +#else +#define no_coroutine_fn +#endif + /* * For mingw, as of v6.0.0, the function implementing the assert macro is diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index a772e14193..fb338ba576 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -59,6 +59,8 @@ get_plugin_meminfo_rw(qemu_plugin_meminfo_t i) #ifdef CONFIG_PLUGIN extern QemuOptsList qemu_plugin_opts; +#define QEMU_PLUGIN_ASSERT(cond) g_assert(cond) + static inline void qemu_plugin_add_opts(void) { qemu_add_opts(&qemu_plugin_opts); @@ -118,7 +120,10 @@ struct qemu_plugin_insn { void *haddr; GArray *cbs[PLUGIN_N_CB_TYPES][PLUGIN_N_CB_SUBTYPES]; bool calls_helpers; + + /* if set, the instruction calls helpers that might access guest memory */ bool mem_helper; + bool mem_only; }; @@ -158,6 +163,10 @@ struct qemu_plugin_tb { void *haddr1; void *haddr2; bool mem_only; + + /* if set, the TB calls helpers that might access guest memory */ + bool mem_helper; + GArray *cbs[PLUGIN_N_CB_SUBTYPES]; }; @@ -243,6 +252,8 @@ void qemu_plugin_user_postfork(bool is_child); #else /* !CONFIG_PLUGIN */ +#define QEMU_PLUGIN_ASSERT(cond) + static inline void qemu_plugin_add_opts(void) { } diff --git a/include/qemu/readline.h b/include/qemu/readline.h index 622aa4564f..b05e4782da 100644 --- a/include/qemu/readline.h +++ b/include/qemu/readline.h @@ -44,6 +44,8 @@ typedef struct ReadLineState { } ReadLineState; void readline_add_completion(ReadLineState *rs, const char *str); +void readline_add_completion_of(ReadLineState *rs, + const char *pfx, const char *str); void readline_set_completion_index(ReadLineState *rs, int completion_index); const char *readline_get_history(ReadLineState *rs, unsigned int index); diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 7c6703bce3..7841084199 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -237,11 +237,10 @@ static inline void qemu_spin_init(QemuSpin *spin) #endif } -/* const parameter because the only purpose here is the TSAN annotation */ -static inline void qemu_spin_destroy(const QemuSpin *spin) +static inline void qemu_spin_destroy(QemuSpin *spin) { #ifdef CONFIG_TSAN - __tsan_mutex_destroy((void *)spin, __tsan_mutex_not_static); + __tsan_mutex_destroy(spin, __tsan_mutex_not_static); #endif } diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h index 031a27ba10..b1196ab93c 100644 --- a/include/sysemu/block-backend-io.h +++ b/include/sysemu/block-backend-io.h @@ -54,13 +54,26 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, void blk_inc_in_flight(BlockBackend *blk); void blk_dec_in_flight(BlockBackend *blk); -bool blk_is_inserted(BlockBackend *blk); + +bool coroutine_fn blk_co_is_inserted(BlockBackend *blk); +bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk); + bool blk_is_available(BlockBackend *blk); -void blk_lock_medium(BlockBackend *blk, bool locked); -void blk_eject(BlockBackend *blk, bool eject_flag); -int64_t blk_getlength(BlockBackend *blk); + +void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked); +void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked); + +void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag); +void co_wrapper blk_eject(BlockBackend *blk, bool eject_flag); + +int64_t coroutine_fn blk_co_getlength(BlockBackend *blk); +int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk); + void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr); -int64_t blk_nb_sectors(BlockBackend *blk); + +int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk); +int64_t co_wrapper_mixed blk_nb_sectors(BlockBackend *blk); + void *blk_try_blockalign(BlockBackend *blk, size_t size); void *blk_blockalign(BlockBackend *blk, size_t size); bool blk_is_writable(BlockBackend *blk); @@ -74,8 +87,12 @@ void blk_iostatus_set_err(BlockBackend *blk, int error); int blk_get_max_iov(BlockBackend *blk); int blk_get_max_hw_iov(BlockBackend *blk); -void blk_io_plug(BlockBackend *blk); -void blk_io_unplug(BlockBackend *blk); +void coroutine_fn blk_co_io_plug(BlockBackend *blk); +void co_wrapper blk_io_plug(BlockBackend *blk); + +void coroutine_fn blk_co_io_unplug(BlockBackend *blk); +void co_wrapper blk_io_unplug(BlockBackend *blk); + AioContext *blk_get_aio_context(BlockBackend *blk); BlockAcctStats *blk_get_stats(BlockBackend *blk); void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, diff --git a/include/monitor/stats.h b/include/sysemu/stats.h index fcf0983154..fcf0983154 100644 --- a/include/monitor/stats.h +++ b/include/sysemu/stats.h diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 6f497172f8..c5112da0ef 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -155,13 +155,6 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_rem_i64 0 #endif -/* For 32-bit targets, some sort of unsigned widening multiply is required. */ -#if TCG_TARGET_REG_BITS == 32 \ - && !(defined(TCG_TARGET_HAS_mulu2_i32) \ - || defined(TCG_TARGET_HAS_muluh_i32)) -# error "Missing unsigned widening multiply" -#endif - #if !defined(TCG_TARGET_HAS_v64) \ && !defined(TCG_TARGET_HAS_v128) \ && !defined(TCG_TARGET_HAS_v256) @@ -405,6 +398,8 @@ typedef TCGv_ptr TCGv_env; #define TCG_CALL_NO_SIDE_EFFECTS 0x0004 /* Helper is G_NORETURN. */ #define TCG_CALL_NO_RETURN 0x0008 +/* Helper is part of Plugins. */ +#define TCG_CALL_PLUGIN 0x0010 /* convenience version of most used call flags */ #define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS |