diff options
Diffstat (limited to 'include')
42 files changed, 832 insertions, 216 deletions
diff --git a/include/block/block.h b/include/block/block.h index 4a2725267d..b3e2674845 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -302,10 +302,13 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_get_backing_file_depth(BlockDriverState *bs); void bdrv_refresh_filename(BlockDriverState *bs); -int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp); +int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc, + Error **errp); int64_t bdrv_nb_sectors(BlockDriverState *bs); int64_t bdrv_getlength(BlockDriverState *bs); int64_t 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); void bdrv_refresh_limits(BlockDriverState *bs, Error **errp); int bdrv_commit(BlockDriverState *bs); @@ -464,9 +467,6 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it); BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); bool bdrv_is_encrypted(BlockDriverState *bs); -bool bdrv_key_required(BlockDriverState *bs); -int bdrv_set_key(BlockDriverState *bs, const char *key); -void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp); void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque); const char *bdrv_get_node_name(const BlockDriverState *bs); @@ -620,4 +620,7 @@ void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child, Error **errp); void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp); +bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, + uint32_t granularity, Error **errp); + #endif diff --git a/include/block/block_int.h b/include/block/block_int.h index 15fa602150..5c6b761d81 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -37,11 +37,11 @@ #include "qemu/main-loop.h" #include "qemu/throttle.h" -#define BLOCK_FLAG_ENCRYPT 1 #define BLOCK_FLAG_LAZY_REFCOUNTS 8 #define BLOCK_OPT_SIZE "size" #define BLOCK_OPT_ENCRYPT "encryption" +#define BLOCK_OPT_ENCRYPT_FORMAT "encrypt.format" #define BLOCK_OPT_COMPAT6 "compat6" #define BLOCK_OPT_HWVERSION "hwversion" #define BLOCK_OPT_BACKING_FILE "backing_file" @@ -204,11 +204,14 @@ struct BlockDriver { int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs); const char *protocol_name; - int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset, Error **errp); + int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset, + PreallocMode prealloc, Error **errp); int64_t (*bdrv_getlength)(BlockDriverState *bs); bool has_variable_length; int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs); + BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs, + Error **errp); int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov); @@ -321,7 +324,7 @@ struct BlockDriver { * Drain and stop any internal sources of requests in the driver, and * remain so until next I/O callback (e.g. bdrv_co_writev) is called. */ - void (*bdrv_drain)(BlockDriverState *bs); + void coroutine_fn (*bdrv_co_drain)(BlockDriverState *bs); void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child, Error **errp); @@ -381,6 +384,20 @@ struct BlockDriver { uint64_t parent_perm, uint64_t parent_shared, uint64_t *nperm, uint64_t *nshared); + /** + * Bitmaps should be marked as 'IN_USE' in the image on reopening image + * as rw. This handler should realize it. It also should unset readonly + * field of BlockDirtyBitmap's in case of success. + */ + int (*bdrv_reopen_bitmaps_rw)(BlockDriverState *bs, Error **errp); + bool (*bdrv_can_store_new_dirty_bitmap)(BlockDriverState *bs, + const char *name, + uint32_t granularity, + Error **errp); + void (*bdrv_remove_persistent_dirty_bitmap)(BlockDriverState *bs, + const char *name, + Error **errp); + QLIST_ENTRY(BlockDriver) list; }; @@ -529,7 +546,6 @@ struct BlockDriverState { int open_flags; /* flags used to open the file, re-used for re-open */ bool read_only; /* if true, the media is read only */ bool encrypted; /* if true, the media is encrypted */ - bool valid_key; /* if true, a valid encryption key has been set */ bool sg; /* if true, the device is a /dev/sg* */ bool probed; /* if true, format was probed rather than specified */ bool force_share; /* if true, always allow all shared permissions */ diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h index ad6558af56..a79a58d2c3 100644 --- a/include/block/dirty-bitmap.h +++ b/include/block/dirty-bitmap.h @@ -25,11 +25,15 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs); +void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs); +void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, + const char *name, + Error **errp); void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap); void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs); -uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap); +uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap); uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap); @@ -66,8 +70,16 @@ void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap, void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap, uint64_t start, uint64_t count, bool finish); +void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, + uint64_t start, uint64_t count, + bool finish); void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap); +void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value); +void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload); +void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, + bool persistent); + /* Functions that require manual locking. */ void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap); void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap); @@ -82,5 +94,13 @@ void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num); int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap); int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap); void bdrv_dirty_bitmap_truncate(BlockDriverState *bs); +bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap); +bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); +bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); +bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); +bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); +BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, + BdrvDirtyBitmap *bitmap); +char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp); #endif diff --git a/include/block/nbd.h b/include/block/nbd.h index 6d75d5a670..9c3d0a5868 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Red Hat, Inc. + * Copyright (C) 2016-2017 Red Hat, Inc. * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws> * * Network Block Device @@ -83,18 +83,37 @@ typedef struct NBDReply NBDReply; #define NBD_FLAG_C_FIXED_NEWSTYLE (1 << 0) /* Fixed newstyle protocol. */ #define NBD_FLAG_C_NO_ZEROES (1 << 1) /* End handshake without zeroes. */ -/* Reply types. */ +/* Option requests. */ +#define NBD_OPT_EXPORT_NAME (1) +#define NBD_OPT_ABORT (2) +#define NBD_OPT_LIST (3) +/* #define NBD_OPT_PEEK_EXPORT (4) not in use */ +#define NBD_OPT_STARTTLS (5) +#define NBD_OPT_INFO (6) +#define NBD_OPT_GO (7) +#define NBD_OPT_STRUCTURED_REPLY (8) + +/* Option reply types. */ #define NBD_REP_ERR(value) ((UINT32_C(1) << 31) | (value)) #define NBD_REP_ACK (1) /* Data sending finished. */ #define NBD_REP_SERVER (2) /* Export description. */ - -#define NBD_REP_ERR_UNSUP NBD_REP_ERR(1) /* Unknown option */ -#define NBD_REP_ERR_POLICY NBD_REP_ERR(2) /* Server denied */ -#define NBD_REP_ERR_INVALID NBD_REP_ERR(3) /* Invalid length */ -#define NBD_REP_ERR_PLATFORM NBD_REP_ERR(4) /* Not compiled in */ -#define NBD_REP_ERR_TLS_REQD NBD_REP_ERR(5) /* TLS required */ -#define NBD_REP_ERR_SHUTDOWN NBD_REP_ERR(7) /* Server shutting down */ +#define NBD_REP_INFO (3) /* NBD_OPT_INFO/GO. */ + +#define NBD_REP_ERR_UNSUP NBD_REP_ERR(1) /* Unknown option */ +#define NBD_REP_ERR_POLICY NBD_REP_ERR(2) /* Server denied */ +#define NBD_REP_ERR_INVALID NBD_REP_ERR(3) /* Invalid length */ +#define NBD_REP_ERR_PLATFORM NBD_REP_ERR(4) /* Not compiled in */ +#define NBD_REP_ERR_TLS_REQD NBD_REP_ERR(5) /* TLS required */ +#define NBD_REP_ERR_UNKNOWN NBD_REP_ERR(6) /* Export unknown */ +#define NBD_REP_ERR_SHUTDOWN NBD_REP_ERR(7) /* Server shutting down */ +#define NBD_REP_ERR_BLOCK_SIZE_REQD NBD_REP_ERR(8) /* Need INFO_BLOCK_SIZE */ + +/* Info types, used during NBD_REP_INFO */ +#define NBD_INFO_EXPORT 0 +#define NBD_INFO_NAME 1 +#define NBD_INFO_DESCRIPTION 2 +#define NBD_INFO_BLOCK_SIZE 3 /* Request flags, sent from client to server during transmission phase */ #define NBD_CMD_FLAG_FUA (1 << 0) /* 'force unit access' during write */ @@ -123,13 +142,26 @@ enum { * aren't overflowing some other buffer. */ #define NBD_MAX_NAME_SIZE 256 +/* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */ +struct NBDExportInfo { + /* Set by client before nbd_receive_negotiate() */ + bool request_sizes; + /* Set by server results during nbd_receive_negotiate() */ + uint64_t size; + uint16_t flags; + uint32_t min_block; + uint32_t opt_block; + uint32_t max_block; +}; +typedef struct NBDExportInfo NBDExportInfo; + ssize_t nbd_rwv(QIOChannel *ioc, struct iovec *iov, size_t niov, size_t length, bool do_read, Error **errp); -int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, +int nbd_receive_negotiate(QIOChannel *ioc, const char *name, QCryptoTLSCreds *tlscreds, const char *hostname, - QIOChannel **outioc, - off_t *size, Error **errp); -int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size, + QIOChannel **outioc, NBDExportInfo *info, + Error **errp); +int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info, Error **errp); ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request); ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp); diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h index 2cbb262f66..71cd069478 100644 --- a/include/chardev/char-fe.h +++ b/include/chardev/char-fe.h @@ -4,6 +4,7 @@ #include "chardev/char.h" typedef void IOEventHandler(void *opaque, int event); +typedef int BackendChangeHandler(void *opaque); /* This is the backend as seen by frontend, the actual backend is * Chardev */ @@ -12,6 +13,7 @@ struct CharBackend { IOEventHandler *chr_event; IOCanReadHandler *chr_can_read; IOReadHandler *chr_read; + BackendChangeHandler *chr_be_change; void *opaque; int tag; int fe_open; @@ -44,16 +46,35 @@ void qemu_chr_fe_deinit(CharBackend *b, bool del); * * Returns the driver associated with a CharBackend or NULL if no * associated Chardev. + * Note: avoid this function as the driver should never be accessed directly, + * especially by the frontends that support chardevice hotswap. + * Consider qemu_chr_fe_backend_connected() to check for driver existence */ Chardev *qemu_chr_fe_get_driver(CharBackend *be); /** + * @qemu_chr_fe_backend_connected: + * + * Returns true if there is a chardevice associated with @be. + */ +bool qemu_chr_fe_backend_connected(CharBackend *be); + +/** + * @qemu_chr_fe_backend_open: + * + * Returns true if chardevice associated with @be is open. + */ +bool qemu_chr_fe_backend_open(CharBackend *be); + +/** * @qemu_chr_fe_set_handlers: * @b: a CharBackend * @fd_can_read: callback to get the amount of data the frontend may * receive * @fd_read: callback to receive data from char * @fd_event: event callback + * @be_change: backend change callback; passing NULL means hot backend change + * is not supported and will not be attempted * @opaque: an opaque pointer for the callbacks * @context: a main loop context or NULL for the default * @set_open: whether to call qemu_chr_fe_set_open() implicitely when @@ -68,6 +89,7 @@ void qemu_chr_fe_set_handlers(CharBackend *b, IOCanReadHandler *fd_can_read, IOReadHandler *fd_read, IOEventHandler *fd_event, + BackendChangeHandler *be_change, void *opaque, GMainContext *context, bool set_open); diff --git a/include/chardev/char.h b/include/chardev/char.h index 8a9ade4931..1604ea9143 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -81,6 +81,16 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); /** + * @qemu_chr_parse_opts: + * + * Parse the options to the ChardevBackend struct. + * + * Returns: a new backend or NULL on error + */ +ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, + Error **errp); + +/** * @qemu_chr_new: * * Create a new character backend from a URI. @@ -93,6 +103,15 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); Chardev *qemu_chr_new(const char *label, const char *filename); /** + * @qemu_chr_change: + * + * Change an existing character backend + * + * @opts the new backend options + */ +void qemu_chr_change(QemuOpts *opts, Error **errp); + +/** * @qemu_chr_cleanup: * * Delete all chardevs (when leaving qemu) diff --git a/include/crypto/block.h b/include/crypto/block.h index 013a435f1b..f0e543bee1 100644 --- a/include/crypto/block.h +++ b/include/crypto/block.h @@ -71,6 +71,7 @@ typedef enum { /** * qcrypto_block_open: * @options: the encryption options + * @optprefix: name prefix for options * @readfunc: callback for reading data from the volume * @opaque: data to pass to @readfunc * @flags: bitmask of QCryptoBlockOpenFlags values @@ -102,6 +103,7 @@ typedef enum { * Returns: a block encryption format, or NULL on error */ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, + const char *optprefix, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, @@ -109,7 +111,8 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, /** * qcrypto_block_create: - * @format: the encryption format + * @options: the encryption options + * @optprefix: name prefix for options * @initfunc: callback for initializing volume header * @writefunc: callback for writing data to the volume header * @opaque: data to pass to @initfunc and @writefunc @@ -133,6 +136,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, * Returns: a block encryption format, or NULL on error */ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, + const char *optprefix, QCryptoBlockInitFunc initfunc, QCryptoBlockWriteFunc writefunc, void *opaque, diff --git a/include/elf.h b/include/elf.h index 0dbd3e968b..cd51434877 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1476,6 +1476,7 @@ typedef struct elf64_shdr { #define NT_TASKSTRUCT 4 #define NT_AUXV 6 #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ +#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */ #define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */ #define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 (lower half) */ #define NT_S390_PREFIX 0x305 /* s390 prefix register */ diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 8096d64a1d..bf8da2aa5a 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -290,6 +290,9 @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, uint16_t idxmap) { } +static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr) +{ +} #endif #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index f9708bbcd6..9aa7756d92 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -58,15 +58,6 @@ void gdb_register_coprocessor(CPUState *cpu, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos); -static inline int cpu_index(CPUState *cpu) -{ -#if defined(CONFIG_USER_ONLY) - return cpu->host_tid; -#else - return cpu->cpu_index + 1; -#endif -} - /* The GDB remote protocol transfers values in target byte order. This means * we can use the raw memory access routines to access the value buffer. * Conveniently, these also handle the case where the buffer is mis-aligned. diff --git a/include/exec/memory.h b/include/exec/memory.h index 8503685455..400dd4491b 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -25,6 +25,7 @@ #include "qemu/notify.h" #include "qom/object.h" #include "qemu/rcu.h" +#include "hw/qdev-core.h" #define RAM_ADDR_INVALID (~(ram_addr_t)0) @@ -35,6 +36,16 @@ #define MEMORY_REGION(obj) \ OBJECT_CHECK(MemoryRegion, (obj), TYPE_MEMORY_REGION) +#define TYPE_IOMMU_MEMORY_REGION "qemu:iommu-memory-region" +#define IOMMU_MEMORY_REGION(obj) \ + OBJECT_CHECK(IOMMUMemoryRegion, (obj), TYPE_IOMMU_MEMORY_REGION) +#define IOMMU_MEMORY_REGION_CLASS(klass) \ + OBJECT_CLASS_CHECK(IOMMUMemoryRegionClass, (klass), \ + TYPE_IOMMU_MEMORY_REGION) +#define IOMMU_MEMORY_REGION_GET_CLASS(obj) \ + OBJECT_GET_CLASS(IOMMUMemoryRegionClass, (obj), \ + TYPE_IOMMU_MEMORY_REGION) + typedef struct MemoryRegionOps MemoryRegionOps; typedef struct MemoryRegionMmio MemoryRegionMmio; @@ -189,26 +200,27 @@ struct MemoryRegionOps { const MemoryRegionMmio old_mmio; }; -typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps; +typedef struct IOMMUMemoryRegionClass { + /* private */ + struct DeviceClass parent_class; -struct MemoryRegionIOMMUOps { /* * Return a TLB entry that contains a given address. Flag should * be the access permission of this translation operation. We can * set flag to IOMMU_NONE to mean that we don't need any * read/write permission checks, like, when for region replay. */ - IOMMUTLBEntry (*translate)(MemoryRegion *iommu, hwaddr addr, + IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr, IOMMUAccessFlags flag); /* Returns minimum supported page size */ - uint64_t (*get_min_page_size)(MemoryRegion *iommu); + uint64_t (*get_min_page_size)(IOMMUMemoryRegion *iommu); /* Called when IOMMU Notifier flag changed */ - void (*notify_flag_changed)(MemoryRegion *iommu, + void (*notify_flag_changed)(IOMMUMemoryRegion *iommu, IOMMUNotifierFlag old_flags, IOMMUNotifierFlag new_flags); /* Set this up to provide customized IOMMU replay function */ - void (*replay)(MemoryRegion *iommu, IOMMUNotifier *notifier); -}; + void (*replay)(IOMMUMemoryRegion *iommu, IOMMUNotifier *notifier); +} IOMMUMemoryRegionClass; typedef struct CoalescedMemoryRange CoalescedMemoryRange; typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; @@ -227,9 +239,9 @@ struct MemoryRegion { bool flush_coalesced_mmio; bool global_locking; uint8_t dirty_log_mask; + bool is_iommu; RAMBlock *ram_block; Object *owner; - const MemoryRegionIOMMUOps *iommu_ops; const MemoryRegionOps *ops; void *opaque; @@ -252,6 +264,11 @@ struct MemoryRegion { const char *name; unsigned ioeventfd_nb; MemoryRegionIoeventfd *ioeventfds; +}; + +struct IOMMUMemoryRegion { + MemoryRegion parent_obj; + QLIST_HEAD(, IOMMUNotifier) iommu_notify; IOMMUNotifierFlag iommu_notify_flags; }; @@ -403,8 +420,9 @@ void memory_region_init_io(MemoryRegion *mr, uint64_t size); /** - * memory_region_init_ram: Initialize RAM memory region. Accesses into the - * region will modify memory directly. + * memory_region_init_ram_nomigrate: Initialize RAM memory region. Accesses + * into the region will modify memory + * directly. * * @mr: the #MemoryRegion to be initialized. * @owner: the object that tracks the region's reference count @@ -412,12 +430,15 @@ void memory_region_init_io(MemoryRegion *mr, * must be unique within any device * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. + * + * 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. */ -void memory_region_init_ram(MemoryRegion *mr, - struct Object *owner, - const char *name, - uint64_t size, - Error **errp); +void memory_region_init_ram_nomigrate(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp); /** * memory_region_init_resizeable_ram: Initialize memory region with resizeable @@ -434,6 +455,9 @@ void memory_region_init_ram(MemoryRegion *mr, * @max_size: max size of the region. * @resized: callback to notify owner about used size change. * @errp: pointer to Error*, to store an error if it happens. + * + * 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. */ void memory_region_init_resizeable_ram(MemoryRegion *mr, struct Object *owner, @@ -457,6 +481,9 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr, * @share: %true if memory must be mmaped with the MAP_SHARED flag * @path: the path in which to allocate the RAM. * @errp: pointer to Error*, to store an error if it happens. + * + * 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. */ void memory_region_init_ram_from_file(MemoryRegion *mr, struct Object *owner, @@ -477,6 +504,9 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, * @share: %true if memory must be mmaped with the MAP_SHARED flag * @fd: the fd to mmap. * @errp: pointer to Error*, to store an error if it happens. + * + * 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. */ void memory_region_init_ram_from_fd(MemoryRegion *mr, struct Object *owner, @@ -498,6 +528,9 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr, * must be unique within any device * @size: size of the region. * @ptr: memory to be mapped; must contain at least @size bytes. + * + * 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. */ void memory_region_init_ram_ptr(MemoryRegion *mr, struct Object *owner, @@ -522,6 +555,10 @@ void memory_region_init_ram_ptr(MemoryRegion *mr, * @name: the name of the region. * @size: size of the region. * @ptr: memory to be mapped; must contain at least @size bytes. + * + * 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. + * (For RAM device memory regions, migrating the contents rarely makes sense.) */ void memory_region_init_ram_device_ptr(MemoryRegion *mr, struct Object *owner, @@ -549,12 +586,16 @@ void memory_region_init_alias(MemoryRegion *mr, uint64_t size); /** - * memory_region_init_rom: Initialize a ROM memory region. + * memory_region_init_rom_nomigrate: Initialize a ROM memory region. * - * This has the same effect as calling memory_region_init_ram() + * This has the same effect as calling memory_region_init_ram_nomigrate() * and then marking the resulting region read-only with * memory_region_set_readonly(). * + * Note that this function does not do anything to cause the data in the + * RAM side of the memory region to be migrated; that is the responsibility + * of the caller. + * * @mr: the #MemoryRegion to be initialized. * @owner: the object that tracks the region's reference count * @name: Region name, becomes part of RAMBlock name used in migration stream @@ -562,15 +603,19 @@ void memory_region_init_alias(MemoryRegion *mr, * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. */ -void memory_region_init_rom(MemoryRegion *mr, - struct Object *owner, - const char *name, - uint64_t size, - Error **errp); +void memory_region_init_rom_nomigrate(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp); /** - * memory_region_init_rom_device: Initialize a ROM memory region. Writes are - * handled via callbacks. + * memory_region_init_rom_device_nomigrate: Initialize a ROM memory region. + * Writes are handled via callbacks. + * + * Note that this function does not do anything to cause the data in the + * RAM side of the memory region to be migrated; that is the responsibility + * of the caller. * * @mr: the #MemoryRegion to be initialized. * @owner: the object that tracks the region's reference count @@ -580,13 +625,13 @@ void memory_region_init_rom(MemoryRegion *mr, * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. */ -void memory_region_init_rom_device(MemoryRegion *mr, - struct Object *owner, - const MemoryRegionOps *ops, - void *opaque, - const char *name, - uint64_t size, - Error **errp); +void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, + struct Object *owner, + const MemoryRegionOps *ops, + void *opaque, + const char *name, + uint64_t size, + Error **errp); /** * memory_region_init_reservation: Initialize a memory region that reserves @@ -612,25 +657,116 @@ static inline void memory_region_init_reservation(MemoryRegion *mr, } /** - * memory_region_init_iommu: Initialize a memory region that translates - * addresses + * memory_region_init_iommu: Initialize a memory region of a custom type + * that translates addresses * * An IOMMU region translates addresses and forwards accesses to a target * memory region. * - * @mr: the #MemoryRegion to be initialized + * @typename: QOM class name + * @_iommu_mr: the #IOMMUMemoryRegion to be initialized + * @instance_size: the IOMMUMemoryRegion subclass instance size * @owner: the object that tracks the region's reference count * @ops: a function that translates addresses into the @target region * @name: used for debugging; not visible to the user or ABI * @size: size of the region. */ -void memory_region_init_iommu(MemoryRegion *mr, - struct Object *owner, - const MemoryRegionIOMMUOps *ops, +void memory_region_init_iommu(void *_iommu_mr, + size_t instance_size, + const char *mrtypename, + Object *owner, const char *name, uint64_t size); /** + * memory_region_init_ram - Initialize RAM memory region. Accesses into the + * region will modify memory directly. + * + * @mr: the #MemoryRegion to be initialized + * @owner: the object that tracks the region's reference count (must be + * TYPE_DEVICE or a subclass of TYPE_DEVICE, or NULL) + * @name: name of the memory region + * @size: size of the region in bytes + * @errp: pointer to Error*, to store an error if it happens. + * + * This function allocates RAM for a board model or device, and + * arranges for it to be migrated (by calling vmstate_register_ram() + * if @owner is a DeviceState, or vmstate_register_ram_global() if + * @owner is NULL). + * + * TODO: Currently we restrict @owner to being either NULL (for + * global RAM regions with no owner) or devices, so that we can + * 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. + */ +void memory_region_init_ram(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp); + +/** + * memory_region_init_rom: Initialize a ROM memory region. + * + * This has the same effect as calling memory_region_init_ram() + * and then marking the resulting region read-only with + * memory_region_set_readonly(). This includes arranging for the + * contents to be migrated. + * + * TODO: Currently we restrict @owner to being either NULL (for + * global RAM regions with no owner) or devices, so that we can + * 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. + * + * @mr: the #MemoryRegion to be initialized. + * @owner: the object that tracks the region's reference count + * @name: Region name, becomes part of RAMBlock name used in migration stream + * must be unique within any device + * @size: size of the region. + * @errp: pointer to Error*, to store an error if it happens. + */ +void memory_region_init_rom(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp); + +/** + * memory_region_init_rom_device: Initialize a ROM memory region. + * Writes are handled via callbacks. + * + * This function initializes a memory region backed by RAM for reads + * and callbacks for writes, and arranges for the RAM backing to + * be migrated (by calling vmstate_register_ram() + * if @owner is a DeviceState, or vmstate_register_ram_global() if + * @owner is NULL). + * + * TODO: Currently we restrict @owner to being either NULL (for + * global RAM regions with no owner) or devices, so that we can + * 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. + * + * @mr: the #MemoryRegion to be initialized. + * @owner: the object that tracks the region's reference count + * @ops: callbacks for write access handling (must not be NULL). + * @name: Region name, becomes part of RAMBlock name used in migration stream + * must be unique within any device + * @size: size of the region. + * @errp: pointer to Error*, to store an error if it happens. + */ +void memory_region_init_rom_device(MemoryRegion *mr, + struct Object *owner, + const MemoryRegionOps *ops, + void *opaque, + const char *name, + uint64_t size, + Error **errp); + + +/** * memory_region_owner: get a memory region's owner. * * @mr: the memory region being queried. @@ -679,20 +815,40 @@ static inline bool memory_region_is_romd(MemoryRegion *mr) } /** - * memory_region_is_iommu: check whether a memory region is an iommu + * memory_region_get_iommu: check whether a memory region is an iommu * - * Returns %true is a memory region is an iommu. + * Returns pointer to IOMMUMemoryRegion if a memory region is an iommu, + * otherwise NULL. * * @mr: the memory region being queried */ -static inline bool memory_region_is_iommu(MemoryRegion *mr) +static inline IOMMUMemoryRegion *memory_region_get_iommu(MemoryRegion *mr) { if (mr->alias) { - return memory_region_is_iommu(mr->alias); + return memory_region_get_iommu(mr->alias); + } + if (mr->is_iommu) { + return (IOMMUMemoryRegion *) mr; } - return mr->iommu_ops; + return NULL; } +/** + * memory_region_get_iommu_class_nocheck: returns iommu memory region class + * if an iommu or NULL if not + * + * Returns pointer to IOMMUMemoryRegioniClass if a memory region is an iommu, + * otherwise NULL. This is fast path avoinding QOM checking, use with caution. + * + * @mr: the memory region being queried + */ +static inline IOMMUMemoryRegionClass *memory_region_get_iommu_class_nocheck( + IOMMUMemoryRegion *iommu_mr) +{ + return (IOMMUMemoryRegionClass *) (((Object *)iommu_mr)->class); +} + +#define memory_region_is_iommu(mr) (memory_region_get_iommu(mr) != NULL) /** * memory_region_iommu_get_min_page_size: get minimum supported page size @@ -700,9 +856,9 @@ static inline bool memory_region_is_iommu(MemoryRegion *mr) * * Returns minimum supported page size for an iommu. * - * @mr: the memory region being queried + * @iommu_mr: the memory region being queried */ -uint64_t memory_region_iommu_get_min_page_size(MemoryRegion *mr); +uint64_t memory_region_iommu_get_min_page_size(IOMMUMemoryRegion *iommu_mr); /** * memory_region_notify_iommu: notify a change in an IOMMU translation entry. @@ -716,12 +872,12 @@ uint64_t memory_region_iommu_get_min_page_size(MemoryRegion *mr); * Note: for any IOMMU implementation, an in-place mapping change * should be notified with an UNMAP followed by a MAP. * - * @mr: the memory region that was changed + * @iommu_mr: the memory region that was changed * @entry: the new entry in the IOMMU translation table. The entry * replaces all old entries for the same virtual I/O address range. * Deleted entries have .@perm == 0. */ -void memory_region_notify_iommu(MemoryRegion *mr, +void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr, IOMMUTLBEntry entry); /** @@ -756,18 +912,18 @@ void memory_region_register_iommu_notifier(MemoryRegion *mr, * a notifier with the minimum page granularity returned by * mr->iommu_ops->get_page_size(). * - * @mr: the memory region to observe + * @iommu_mr: the memory region to observe * @n: the notifier to which to replay iommu mappings */ -void memory_region_iommu_replay(MemoryRegion *mr, IOMMUNotifier *n); +void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n); /** * memory_region_iommu_replay_all: replay existing IOMMU translations * to all the notifiers registered. * - * @mr: the memory region to observe + * @iommu_mr: the memory region to observe */ -void memory_region_iommu_replay_all(MemoryRegion *mr); +void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr); /** * memory_region_unregister_iommu_notifier: unregister a notifier for diff --git a/include/hw/boards.h b/include/hw/boards.h index 76ce0219ff..3363dd19fd 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -9,6 +9,35 @@ #include "qom/object.h" #include "qom/cpu.h" +/** + * memory_region_allocate_system_memory - Allocate a board's main memory + * @mr: the #MemoryRegion to be initialized + * @owner: the object that tracks the region's reference count + * @name: name of the memory region + * @ram_size: size of the region in bytes + * + * This function allocates the main memory for a board model, and + * initializes @mr appropriately. It also arranges for the memory + * to be migrated (by calling vmstate_register_ram_global()). + * + * Memory allocated via this function will be backed with the memory + * backend the user provided using "-mem-path" or "-numa node,memdev=..." + * if appropriate; this is typically used to cause host huge pages to be + * used. This function should therefore be called by a board exactly once, + * for the primary or largest RAM area it implements. + * + * For boards where the major RAM is split into two parts in the memory + * map, you can deal with this by calling memory_region_allocate_system_memory() + * once to get a MemoryRegion with enough RAM for both parts, and then + * creating alias MemoryRegions via memory_region_init_alias() which + * alias into different parts of the RAM MemoryRegion and can be mapped + * into the memory map in the appropriate places. + * + * Smaller pieces of memory (display RAM, static RAMs, etc) don't need + * to be backed via the -mem-path memory backend and can simply + * be created via memory_region_allocate_aux_memory() or + * memory_region_init_ram(). + */ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, const char *name, uint64_t ram_size); diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 3e51876b75..08d8a26d13 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -32,6 +32,8 @@ #define INTEL_IOMMU_DEVICE(obj) \ OBJECT_CHECK(IntelIOMMUState, (obj), TYPE_INTEL_IOMMU_DEVICE) +#define TYPE_INTEL_IOMMU_MEMORY_REGION "intel-iommu-iommu-memory-region" + /* DMAR Hardware Unit Definition address (IOMMU unit) */ #define Q35_HOST_BRIDGE_IOMMU_ADDR 0xfed90000ULL @@ -83,7 +85,7 @@ struct VTDAddressSpace { PCIBus *bus; uint8_t devfn; AddressSpace as; - MemoryRegion iommu; + IOMMUMemoryRegion iommu; MemoryRegion root; MemoryRegion sys_alias; MemoryRegion iommu_ir; /* Interrupt region: 0xfeeXXXXX */ @@ -289,7 +291,6 @@ struct IntelIOMMUState { uint32_t context_cache_gen; /* Should be in [1,MAX] */ GHashTable *iotlb; /* IOTLB */ - MemoryRegionIOMMUOps iommu_ops; GHashTable *vtd_as_by_busptr; /* VTDBus objects indexed by PCIBus* reference */ VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by bus number */ /* list of registered notifiers */ diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h index 16412dc150..2f6774d540 100644 --- a/include/hw/mips/mips.h +++ b/include/hw/mips/mips.h @@ -19,6 +19,6 @@ typedef struct rc4030DMAState *rc4030_dma; void rc4030_dma_read(void *dma, uint8_t *buf, int len); void rc4030_dma_write(void *dma, uint8_t *buf, int len); -DeviceState *rc4030_init(rc4030_dma **dmas, MemoryRegion **dma_mr); +DeviceState *rc4030_init(rc4030_dma **dmas, IOMMUMemoryRegion **dma_mr); #endif diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h index 3462d85836..52e068ec3e 100644 --- a/include/hw/misc/unimp.h +++ b/include/hw/misc/unimp.h @@ -8,6 +8,8 @@ #ifndef HW_MISC_UNIMP_H #define HW_MISC_UNIMP_H +#include "hw/sysbus.h" + #define TYPE_UNIMPLEMENTED_DEVICE "unimplemented-device" /** diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h index 11d83e43f8..f6af5eae1f 100644 --- a/include/hw/ppc/pnv_psi.h +++ b/include/hw/ppc/pnv_psi.h @@ -28,8 +28,6 @@ #define PSIHB_XSCOM_MAX 0x20 -typedef struct XICSState XICSState; - typedef struct PnvPsi { SysBusDevice parent; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a184ffab0e..2a303a705c 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -13,6 +13,7 @@ struct sPAPRPHBState; struct sPAPRNVRAM; typedef struct sPAPREventLogEntry sPAPREventLogEntry; typedef struct sPAPREventSource sPAPREventSource; +typedef struct sPAPRPendingHPT sPAPRPendingHPT; #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL #define SPAPR_ENTRY_POINT 0x100 @@ -42,6 +43,13 @@ typedef struct sPAPRMachineClass sPAPRMachineClass; #define SPAPR_MACHINE_CLASS(klass) \ OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE) +typedef enum { + SPAPR_RESIZE_HPT_DEFAULT = 0, + SPAPR_RESIZE_HPT_DISABLED, + SPAPR_RESIZE_HPT_ENABLED, + SPAPR_RESIZE_HPT_REQUIRED, +} sPAPRResizeHPT; + /** * sPAPRMachineClass: */ @@ -58,6 +66,7 @@ struct sPAPRMachineClass { uint64_t *buid, hwaddr *pio, hwaddr *mmio32, hwaddr *mmio64, unsigned n_dma, uint32_t *liobns, Error **errp); + sPAPRResizeHPT resize_hpt_default; }; /** @@ -73,9 +82,12 @@ struct sPAPRMachineState { ICSState *ics; sPAPRRTCState rtc; + sPAPRResizeHPT resize_hpt; void *htab; uint32_t htab_shift; uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROCESS_TABLE */ + sPAPRPendingHPT *pending_hpt; /* in-progress resize */ + hwaddr rma_size; int vrma_adjust; ssize_t rtas_size; @@ -367,6 +379,8 @@ struct sPAPRMachineState { #define H_XIRR_X 0x2FC #define H_RANDOM 0x300 #define H_SET_MODE 0x31C +#define H_RESIZE_HPT_PREPARE 0x36C +#define H_RESIZE_HPT_COMMIT 0x370 #define H_CLEAN_SLB 0x374 #define H_INVALIDATE_PID 0x378 #define H_REGISTER_PROC_TBL 0x37C @@ -582,6 +596,10 @@ typedef struct sPAPRTCETable sPAPRTCETable; #define SPAPR_TCE_TABLE(obj) \ OBJECT_CHECK(sPAPRTCETable, (obj), TYPE_SPAPR_TCE_TABLE) +#define TYPE_SPAPR_IOMMU_MEMORY_REGION "spapr-iommu-memory-region" +#define SPAPR_IOMMU_MEMORY_REGION(obj) \ + OBJECT_CHECK(IOMMUMemoryRegion, (obj), TYPE_SPAPR_IOMMU_MEMORY_REGION) + struct sPAPRTCETable { DeviceState parent; uint32_t liobn; @@ -594,7 +612,8 @@ struct sPAPRTCETable { bool bypass; bool need_vfio; int fd; - MemoryRegion root, iommu; + MemoryRegion root; + IOMMUMemoryRegion iommu; struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */ QLIST_ENTRY(sPAPRTCETable) list; }; @@ -602,8 +621,9 @@ struct sPAPRTCETable { sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn); struct sPAPREventLogEntry { - int log_type; - void *data; + uint32_t summary; + uint32_t extended_length; + void *extended_log; QTAILQ_ENTRY(sPAPREventLogEntry) next; }; @@ -639,6 +659,9 @@ void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type, void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type, uint32_t count, uint32_t index); void spapr_cpu_parse_features(sPAPRMachineState *spapr); +int spapr_hpt_shift_for_ramsize(uint64_t ramsize); +void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift, + Error **errp); /* CPU and LMB DRC release callbacks. */ void spapr_core_release(DeviceState *dev); @@ -679,4 +702,6 @@ int spapr_rng_populate_dt(void *fdt); void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg); +#define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift)) + #endif /* HW_SPAPR_H */ diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index d15e9eb3b4..a7958d0a8d 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -15,6 +15,7 @@ #include <libfdt.h> #include "qom/object.h" +#include "sysemu/sysemu.h" #include "hw/qdev.h" #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector" @@ -32,7 +33,7 @@ #define SPAPR_DRC_PHYSICAL_CLASS(klass) \ OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \ TYPE_SPAPR_DRC_PHYSICAL) -#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ +#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRCPhysical, (obj), \ TYPE_SPAPR_DRC_PHYSICAL) #define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical" @@ -172,11 +173,23 @@ typedef enum { SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003, } sPAPRDRCCResponse; -/* rtas-configure-connector state */ -typedef struct sPAPRConfigureConnectorState { - int fdt_offset; - int fdt_depth; -} sPAPRConfigureConnectorState; +typedef enum { + /* + * Values come from Fig. 12 in LoPAPR section 13.4 + * + * These are exposed in the migration stream, so don't change + * them. + */ + SPAPR_DRC_STATE_INVALID = 0, + SPAPR_DRC_STATE_LOGICAL_UNUSABLE = 1, + SPAPR_DRC_STATE_LOGICAL_AVAILABLE = 2, + SPAPR_DRC_STATE_LOGICAL_UNISOLATE = 3, + SPAPR_DRC_STATE_LOGICAL_CONFIGURED = 4, + SPAPR_DRC_STATE_PHYSICAL_AVAILABLE = 5, + SPAPR_DRC_STATE_PHYSICAL_POWERON = 6, + SPAPR_DRC_STATE_PHYSICAL_UNISOLATE = 7, + SPAPR_DRC_STATE_PHYSICAL_CONFIGURED = 8, +} sPAPRDRCState; typedef struct sPAPRDRConnector { /*< private >*/ @@ -185,29 +198,25 @@ typedef struct sPAPRDRConnector { uint32_t id; Object *owner; - /* DR-indicator */ - uint32_t dr_indicator; + uint32_t state; - /* sensor/indicator states */ - uint32_t isolation_state; - uint32_t allocation_state; - - /* configure-connector state */ - void *fdt; - int fdt_start_offset; - bool configured; - sPAPRConfigureConnectorState *ccs; - - bool awaiting_release; - bool awaiting_allocation; + /* RTAS ibm,configure-connector state */ + /* (only valid in UNISOLATE state) */ + int ccs_offset; + int ccs_depth; /* device pointer, via link property */ DeviceState *dev; + bool unplug_requested; + void *fdt; + int fdt_start_offset; } sPAPRDRConnector; typedef struct sPAPRDRConnectorClass { /*< private >*/ DeviceClass parent; + sPAPRDRCState empty_state; + sPAPRDRCState ready_state; /*< public >*/ sPAPRDRConnectorTypeShift typeshift; @@ -218,11 +227,23 @@ typedef struct sPAPRDRConnectorClass { uint32_t (*isolate)(sPAPRDRConnector *drc); uint32_t (*unisolate)(sPAPRDRConnector *drc); void (*release)(DeviceState *dev); - - /* QEMU interfaces for managing hotplug operations */ - bool (*release_pending)(sPAPRDRConnector *drc); } sPAPRDRConnectorClass; +typedef struct sPAPRDRCPhysical { + /*< private >*/ + sPAPRDRConnector parent; + + /* DR-indicator */ + uint32_t dr_indicator; +} sPAPRDRCPhysical; + +static inline bool spapr_drc_hotplugged(DeviceState *dev) +{ + return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE); +} + +void spapr_drc_reset(sPAPRDRConnector *drc); + uint32_t spapr_drc_index(sPAPRDRConnector *drc); sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc); @@ -235,6 +256,11 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt, int fdt_start_offset, Error **errp); -void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp); +void spapr_drc_detach(sPAPRDRConnector *drc); + +static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc) +{ + return drc->unplug_requested; +} #endif /* HW_SPAPR_DRC_H */ diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h index 0b464e22e7..9edfa5ff75 100644 --- a/include/hw/ppc/spapr_ovec.h +++ b/include/hw/ppc/spapr_ovec.h @@ -50,6 +50,7 @@ typedef struct sPAPROptionVector sPAPROptionVector; #define OV5_DRCONF_MEMORY OV_BIT(2, 2) #define OV5_FORM1_AFFINITY OV_BIT(5, 0) #define OV5_HP_EVT OV_BIT(6, 5) +#define OV5_HPT_RESIZE OV_BIT(6, 7) #define OV5_XIVE_EXPLOIT OV_BIT(23, 7) /* ISA 3.00 MMU features: */ diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h index eafc3f0a86..fc4ef5cc1d 100644 --- a/include/hw/ptimer.h +++ b/include/hw/ptimer.h @@ -12,6 +12,20 @@ #include "qemu/timer.h" #include "migration/vmstate.h" +/* The ptimer API implements a simple periodic countdown timer. + * The countdown timer has a value (which can be read and written via + * ptimer_get_count() and ptimer_set_count()). When it is enabled + * using ptimer_run(), the value will count downwards at the frequency + * which has been configured using ptimer_set_period() or ptimer_set_freq(). + * When it reaches zero it will trigger a QEMU bottom half handler, and + * can be set to either reload itself from a specified limit value + * and keep counting down, or to stop (as a one-shot timer). + * + * Forgetting to set the period/frequency (or setting it to zero) is a + * bug in the QEMU device and will cause warning messages to be printed + * to stderr when the guest attempts to enable the timer. + */ + /* The default ptimer policy retains backward compatibility with the legacy * timers. Custom policies are adjusting the default one. Consider providing * a correct policy for your timer. @@ -59,15 +73,121 @@ typedef struct ptimer_state ptimer_state; typedef void (*ptimer_cb)(void *opaque); +/** + * ptimer_init - Allocate and return a new ptimer + * @bh: QEMU bottom half which is run on timer expiry + * @policy: PTIMER_POLICY_* bits specifying behaviour + * + * The ptimer returned must be freed using ptimer_free(). + * The ptimer takes ownership of @bh and will delete it + * when the ptimer is eventually freed. + */ ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_mask); + +/** + * ptimer_free - Free a ptimer + * @s: timer to free + * + * Free a ptimer created using ptimer_init() (including + * deleting the bottom half which it is using). + */ void ptimer_free(ptimer_state *s); + +/** + * ptimer_set_period - Set counter increment interval in nanoseconds + * @s: ptimer to configure + * @period: period of the counter in nanoseconds + * + * Note that if your counter behaviour is specified as having a + * particular frequency rather than a period then ptimer_set_freq() + * may be more appropriate. + */ void ptimer_set_period(ptimer_state *s, int64_t period); + +/** + * ptimer_set_freq - Set counter frequency in Hz + * @s: ptimer to configure + * @freq: counter frequency in Hz + * + * This does the same thing as ptimer_set_period(), so you only + * need to call one of them. If the counter behaviour is specified + * as setting the frequency then this function is more appropriate, + * because it allows specifying an effective period which is + * precise to fractions of a nanosecond, avoiding rounding errors. + */ void ptimer_set_freq(ptimer_state *s, uint32_t freq); + +/** + * ptimer_get_limit - Get the configured limit of the ptimer + * @s: ptimer to query + * + * This function returns the current limit (reload) value + * of the down-counter; that is, the value which it will be + * reset to when it hits zero. + * + * Generally timer devices using ptimers should be able to keep + * their reload register state inside the ptimer using the get + * and set limit functions rather than needing to also track it + * in their own state structure. + */ uint64_t ptimer_get_limit(ptimer_state *s); + +/** + * ptimer_set_limit - Set the limit of the ptimer + * @s: ptimer + * @limit: initial countdown value + * @reload: if nonzero, then reset the counter to the new limit + * + * Set the limit value of the down-counter. The @reload flag can + * be used to emulate the behaviour of timers which immediately + * reload the counter when their reload register is written to. + */ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload); + +/** + * ptimer_get_count - Get the current value of the ptimer + * @s: ptimer + * + * Return the current value of the down-counter. This will + * return the correct value whether the counter is enabled or + * disabled. + */ uint64_t ptimer_get_count(ptimer_state *s); + +/** + * ptimer_set_count - Set the current value of the ptimer + * @s: ptimer + * @count: count value to set + * + * Set the value of the down-counter. If the counter is currently + * enabled this will arrange for a timer callback at the appropriate + * point in the future. + */ void ptimer_set_count(ptimer_state *s, uint64_t count); + +/** + * ptimer_run - Start a ptimer counting + * @s: ptimer + * @oneshot: non-zero if this timer should only count down once + * + * Start a ptimer counting down; when it reaches zero the bottom half + * passed to ptimer_init() will be invoked. If the @oneshot argument is zero, + * the counter value will then be reloaded from the limit and it will + * start counting down again. If @oneshot is non-zero, then the counter + * will disable itself when it reaches zero. + */ void ptimer_run(ptimer_state *s, int oneshot); + +/** + * ptimer_stop - Stop a ptimer counting + * @s: ptimer + * + * Pause a timer (the count stays at its current value until ptimer_run() + * is called to start it counting again). + * + * Note that this can cause it to "lose" time, even if it is immediately + * restarted. + */ void ptimer_stop(ptimer_state *s); extern const VMStateDescription vmstate_ptimer; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 9d7c1c0e9b..53488153fd 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -223,7 +223,7 @@ struct BusState { struct Property { const char *name; - PropertyInfo *info; + const PropertyInfo *info; ptrdiff_t offset; uint8_t bitnr; union { @@ -231,8 +231,9 @@ struct Property { uint64_t u; } defval; int arrayoffset; - PropertyInfo *arrayinfo; + const PropertyInfo *arrayinfo; int arrayfieldsize; + const char *link_type; }; struct PropertyInfo { @@ -241,6 +242,7 @@ struct PropertyInfo { const char * const *enum_table; int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); void (*set_default_value)(Object *obj, const Property *prop); + void (*create)(Object *obj, Property *prop, Error **errp); ObjectPropertyAccessor *get; ObjectPropertyAccessor *set; ObjectPropertyRelease *release; diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 0604c337e0..f6692d5dc3 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -5,31 +5,32 @@ /*** qdev-properties.c ***/ -extern PropertyInfo qdev_prop_bit; -extern PropertyInfo qdev_prop_bit64; -extern PropertyInfo qdev_prop_bool; -extern PropertyInfo qdev_prop_uint8; -extern PropertyInfo qdev_prop_uint16; -extern PropertyInfo qdev_prop_uint32; -extern PropertyInfo qdev_prop_int32; -extern PropertyInfo qdev_prop_uint64; -extern PropertyInfo qdev_prop_size; -extern PropertyInfo qdev_prop_string; -extern PropertyInfo qdev_prop_chr; -extern PropertyInfo qdev_prop_ptr; -extern PropertyInfo qdev_prop_macaddr; -extern PropertyInfo qdev_prop_on_off_auto; -extern PropertyInfo qdev_prop_losttickpolicy; -extern PropertyInfo qdev_prop_blockdev_on_error; -extern PropertyInfo qdev_prop_bios_chs_trans; -extern PropertyInfo qdev_prop_fdc_drive_type; -extern PropertyInfo qdev_prop_drive; -extern PropertyInfo qdev_prop_netdev; -extern PropertyInfo qdev_prop_vlan; -extern PropertyInfo qdev_prop_pci_devfn; -extern PropertyInfo qdev_prop_blocksize; -extern PropertyInfo qdev_prop_pci_host_devaddr; -extern PropertyInfo qdev_prop_arraylen; +extern const PropertyInfo qdev_prop_bit; +extern const PropertyInfo qdev_prop_bit64; +extern const PropertyInfo qdev_prop_bool; +extern const PropertyInfo qdev_prop_uint8; +extern const PropertyInfo qdev_prop_uint16; +extern const PropertyInfo qdev_prop_uint32; +extern const PropertyInfo qdev_prop_int32; +extern const PropertyInfo qdev_prop_uint64; +extern const PropertyInfo qdev_prop_size; +extern const PropertyInfo qdev_prop_string; +extern const PropertyInfo qdev_prop_chr; +extern const PropertyInfo qdev_prop_ptr; +extern const PropertyInfo qdev_prop_macaddr; +extern const PropertyInfo qdev_prop_on_off_auto; +extern const PropertyInfo qdev_prop_losttickpolicy; +extern const PropertyInfo qdev_prop_blockdev_on_error; +extern const PropertyInfo qdev_prop_bios_chs_trans; +extern const PropertyInfo qdev_prop_fdc_drive_type; +extern const PropertyInfo qdev_prop_drive; +extern const PropertyInfo qdev_prop_netdev; +extern const PropertyInfo qdev_prop_vlan; +extern const PropertyInfo qdev_prop_pci_devfn; +extern const PropertyInfo qdev_prop_blocksize; +extern const PropertyInfo qdev_prop_pci_host_devaddr; +extern const PropertyInfo qdev_prop_arraylen; +extern const PropertyInfo qdev_prop_link; #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ .name = (_name), \ @@ -117,6 +118,14 @@ extern PropertyInfo qdev_prop_arraylen; .arrayoffset = offsetof(_state, _arrayfield), \ } +#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type) { \ + .name = (_name), \ + .info = &(qdev_prop_link), \ + .offset = offsetof(_state, _field) \ + + type_check(_ptr_type, typeof_field(_state, _field)), \ + .link_type = _type, \ + } + #define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t) #define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ @@ -272,7 +281,8 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name, * This function should be used as the check() argument to * object_property_add_link(). */ -void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name, +void qdev_prop_allow_set_link_before_realize(const Object *obj, + const char *name, Object *val, Error **errp); #endif diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h index eb0e26f258..5c5fe6b202 100644 --- a/include/hw/s390x/css.h +++ b/include/hw/s390x/css.h @@ -12,6 +12,7 @@ #ifndef CSS_H #define CSS_H +#include "cpu.h" #include "hw/s390x/adapter.h" #include "hw/s390x/s390_flic.h" #include "hw/s390x/ioinst.h" @@ -89,10 +90,11 @@ struct SubchDev { bool thinint_active; uint8_t ccw_no_data_cnt; uint16_t migrated_schid; /* used for missmatch detection */ + ORB orb; /* transport-provided data: */ int (*ccw_cb) (SubchDev *, CCW1); void (*disable_cb)(SubchDev *); - int (*do_subchannel_work) (SubchDev *, ORB *); + int (*do_subchannel_work) (SubchDev *); SenseId id; void *driver_data; }; @@ -112,7 +114,7 @@ typedef struct CssDevId { bool valid; } CssDevId; -extern PropertyInfo css_devid_propinfo; +extern const PropertyInfo css_devid_propinfo; #define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId) @@ -154,10 +156,9 @@ void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid, void css_generate_chp_crws(uint8_t cssid, uint8_t chpid); void css_generate_css_crws(uint8_t cssid); void css_clear_sei_pending(void); -void css_adapter_interrupt(uint8_t isc); int s390_ccw_cmd_request(ORB *orb, SCSW *scsw, void *data); -int do_subchannel_work_virtual(SubchDev *sub, ORB *orb); -int do_subchannel_work_passthrough(SubchDev *sub, ORB *orb); +int do_subchannel_work_virtual(SubchDev *sub); +int do_subchannel_work_passthrough(SubchDev *sub); typedef enum { CSS_IO_ADAPTER_VIRTIO = 0, @@ -165,9 +166,17 @@ typedef enum { CSS_IO_ADAPTER_TYPE_NUMS, } CssIoAdapterType; +void css_adapter_interrupt(CssIoAdapterType type, uint8_t isc); +int css_do_sic(CPUS390XState *env, uint8_t isc, uint16_t mode); uint32_t css_get_adapter_id(CssIoAdapterType type, uint8_t isc); void css_register_io_adapters(CssIoAdapterType type, bool swap, bool maskable, - Error **errp); + uint8_t flags, Error **errp); + +#ifndef CONFIG_KVM +#define S390_ADAPTER_SUPPRESSIBLE 0x01 +#else +#define S390_ADAPTER_SUPPRESSIBLE KVM_S390_ADAPTER_SUPPRESSIBLE +#endif #ifndef CONFIG_USER_ONLY SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, @@ -196,7 +205,7 @@ int css_do_rchp(uint8_t cssid, uint8_t chpid); bool css_present(uint8_t cssid); #endif -extern PropertyInfo css_devid_ro_propinfo; +extern const PropertyInfo css_devid_ro_propinfo; #define DEFINE_PROP_CSS_DEV_ID_RO(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, css_devid_ro_propinfo, CssDevId) @@ -225,4 +234,8 @@ extern PropertyInfo css_devid_ro_propinfo; */ SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss, Error **errp); + +/** Turn on css migration */ +void css_register_vmstate(void); + #endif diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h index 3027555f6d..41a9d2862b 100644 --- a/include/hw/s390x/s390-virtio-ccw.h +++ b/include/hw/s390x/s390-virtio-ccw.h @@ -39,11 +39,21 @@ typedef struct S390CcwMachineClass { /*< public >*/ bool ri_allowed; bool cpu_model_allowed; + bool css_migration_enabled; + bool gs_allowed; } S390CcwMachineClass; /* runtime-instrumentation allowed by the machine */ bool ri_allowed(void); /* cpu model allowed by the machine */ bool cpu_model_allowed(void); +/* guarded-storage allowed by the machine */ +bool gs_allowed(void); + +/** + * Returns true if (vmstate based) migration of the channel subsystem + * is enabled, false if it is disabled. + */ +bool css_migration_enabled(void); #endif diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h index caa6fc608d..7aab6ef7f0 100644 --- a/include/hw/s390x/s390_flic.h +++ b/include/hw/s390x/s390_flic.h @@ -44,7 +44,7 @@ typedef struct S390FLICState { SysBusDevice parent_obj; /* to limit AdapterRoutes.num_routes for compat */ uint32_t adapter_routes_max_batch; - + bool ais_supported; } S390FLICState; #define S390_FLIC_COMMON_CLASS(klass) \ @@ -56,13 +56,16 @@ typedef struct S390FLICStateClass { DeviceClass parent_class; int (*register_io_adapter)(S390FLICState *fs, uint32_t id, uint8_t isc, - bool swap, bool maskable); + bool swap, bool maskable, uint8_t flags); int (*io_adapter_map)(S390FLICState *fs, uint32_t id, uint64_t map_addr, bool do_map); int (*add_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes); void (*release_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes); int (*clear_io_irq)(S390FLICState *fs, uint16_t subchannel_id, uint16_t subchannel_nr); + int (*modify_ais_mode)(S390FLICState *fs, uint8_t isc, uint16_t mode); + int (*inject_airq)(S390FLICState *fs, uint8_t type, uint8_t isc, + uint8_t flags); } S390FLICStateClass; #define TYPE_KVM_S390_FLIC "s390-flic-kvm" @@ -73,13 +76,20 @@ typedef struct S390FLICStateClass { #define QEMU_S390_FLIC(obj) \ OBJECT_CHECK(QEMUS390FLICState, (obj), TYPE_QEMU_S390_FLIC) +#define SIC_IRQ_MODE_ALL 0 +#define SIC_IRQ_MODE_SINGLE 1 +#define AIS_MODE_MASK(isc) (0x80 >> isc) + typedef struct QEMUS390FLICState { S390FLICState parent_obj; + uint8_t simm; + uint8_t nimm; } QEMUS390FLICState; void s390_flic_init(void); S390FLICState *s390_get_flic(void); +bool ais_needed(void *opaque); #ifdef CONFIG_KVM DeviceState *s390_flic_kvm_create(void); diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h index 3008a5148a..e71d526605 100644 --- a/include/hw/s390x/sclp.h +++ b/include/hw/s390x/sclp.h @@ -123,8 +123,7 @@ typedef struct ReadInfo { uint64_t facilities; /* 48-55 */ uint8_t _reserved0[76 - 56]; /* 56-75 */ uint32_t ibc_val; - uint8_t conf_char[96 - 80]; /* 80-95 */ - uint8_t _reserved4[99 - 96]; /* 96-98 */ + uint8_t conf_char[99 - 80]; /* 80-98 */ uint8_t mha_pow; uint32_t rnsize2; uint64_t rnmax2; diff --git a/include/hw/s390x/storage-attributes.h b/include/hw/s390x/storage-attributes.h new file mode 100644 index 0000000000..9be954d163 --- /dev/null +++ b/include/hw/s390x/storage-attributes.h @@ -0,0 +1,81 @@ +/* + * s390 storage attributes device + * + * Copyright 2016 IBM Corp. + * Author(s): Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#ifndef S390_STORAGE_ATTRIBUTES_H +#define S390_STORAGE_ATTRIBUTES_H + +#include <hw/qdev.h> +#include "monitor/monitor.h" + +#define TYPE_S390_STATTRIB "s390-storage_attributes" +#define TYPE_QEMU_S390_STATTRIB "s390-storage_attributes-qemu" +#define TYPE_KVM_S390_STATTRIB "s390-storage_attributes-kvm" + +#define S390_STATTRIB(obj) \ + OBJECT_CHECK(S390StAttribState, (obj), TYPE_S390_STATTRIB) + +typedef struct S390StAttribState { + DeviceState parent_obj; + uint64_t migration_cur_gfn; + bool migration_enabled; +} S390StAttribState; + +#define S390_STATTRIB_CLASS(klass) \ + OBJECT_CLASS_CHECK(S390StAttribClass, (klass), TYPE_S390_STATTRIB) +#define S390_STATTRIB_GET_CLASS(obj) \ + OBJECT_GET_CLASS(S390StAttribClass, (obj), TYPE_S390_STATTRIB) + +typedef struct S390StAttribClass { + DeviceClass parent_class; + /* Return value: < 0 on error, or new count */ + int (*get_stattr)(S390StAttribState *sa, uint64_t *start_gfn, + uint32_t count, uint8_t *values); + int (*peek_stattr)(S390StAttribState *sa, uint64_t start_gfn, + uint32_t count, uint8_t *values); + int (*set_stattr)(S390StAttribState *sa, uint64_t start_gfn, + uint32_t count, uint8_t *values); + void (*synchronize)(S390StAttribState *sa); + int (*set_migrationmode)(S390StAttribState *sa, bool value); + int (*get_active)(S390StAttribState *sa); + long long (*get_dirtycount)(S390StAttribState *sa); +} S390StAttribClass; + +#define QEMU_S390_STATTRIB(obj) \ + OBJECT_CHECK(QEMUS390StAttribState, (obj), TYPE_QEMU_S390_STATTRIB) + +typedef struct QEMUS390StAttribState { + S390StAttribState parent_obj; +} QEMUS390StAttribState; + +#define KVM_S390_STATTRIB(obj) \ + OBJECT_CHECK(KVMS390StAttribState, (obj), TYPE_KVM_S390_STATTRIB) + +typedef struct KVMS390StAttribState { + S390StAttribState parent_obj; + uint64_t still_dirty; + uint8_t *incoming_buffer; +} KVMS390StAttribState; + +void s390_stattrib_init(void); + +#ifdef CONFIG_KVM +Object *kvm_s390_stattrib_create(void); +#else +static inline Object *kvm_s390_stattrib_create(void) +{ + return NULL; +} +#endif + +void hmp_info_cmma(Monitor *mon, const QDict *qdict); +void hmp_migrationmode(Monitor *mon, const QDict *qdict); + +#endif /* S390_STORAGE_ATTRIBUTES_H */ diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 0b475a3596..f3a2ac9fee 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -95,7 +95,7 @@ typedef struct VFIOContainer { typedef struct VFIOGuestIOMMU { VFIOContainer *container; - MemoryRegion *iommu; + IOMMUMemoryRegion *iommu; hwaddr iommu_offset; IOMMUNotifier n; QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index d2b3aafdb4..83ea4a1aaf 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -23,13 +23,6 @@ void monitor_cleanup(void); int monitor_suspend(Monitor *mon); void monitor_resume(Monitor *mon); -int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, - BlockCompletionFunc *completion_cb, - void *opaque); -int monitor_read_block_device_key(Monitor *mon, const char *device, - BlockCompletionFunc *completion_cb, - void *opaque); - int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp); int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp); diff --git a/include/qapi/error.h b/include/qapi/error.h index 7e532d00e9..341b229066 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -125,7 +125,6 @@ typedef enum ErrorClass { ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERICERROR, ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMANDNOTFOUND, - ERROR_CLASS_DEVICE_ENCRYPTED = QAPI_ERROR_CLASS_DEVICEENCRYPTED, ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE, ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND, ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP, @@ -267,11 +266,22 @@ void error_free(Error *err); void error_free_or_abort(Error **errp); /* + * Convenience function to warn_report() and free @err. + */ +void warn_report_err(Error *err); + +/* * Convenience function to error_report() and free @err. */ void error_report_err(Error *err); /* + * Convenience function to error_prepend(), warn_report() and free @err. + */ +void warn_reportf_err(Error *err, const char *fmt, ...) + GCC_FMT_ATTR(2, 3); + +/* * Convenience function to error_prepend(), error_report() and free @err. */ void error_reportf_err(Error *err, const char *fmt, ...) diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index a4509bd977..9aff9a735e 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -229,6 +229,24 @@ void qemu_co_rwlock_init(CoRwlock *lock); void qemu_co_rwlock_rdlock(CoRwlock *lock); /** + * Write Locks the CoRwlock from a reader. This is a bit more efficient than + * @qemu_co_rwlock_unlock followed by a separate @qemu_co_rwlock_wrlock. + * However, if the lock cannot be upgraded immediately, control is transferred + * to the caller of the current coroutine. Also, @qemu_co_rwlock_upgrade + * only overrides CoRwlock fairness if there are no concurrent readers, so + * another writer might run while @qemu_co_rwlock_upgrade blocks. + */ +void qemu_co_rwlock_upgrade(CoRwlock *lock); + +/** + * Downgrades a write-side critical section to a reader. Downgrading with + * @qemu_co_rwlock_downgrade never blocks, unlike @qemu_co_rwlock_unlock + * followed by @qemu_co_rwlock_rdlock. This makes it more efficient, but + * may also sometimes be necessary for correctness. + */ +void qemu_co_rwlock_downgrade(CoRwlock *lock); + +/** * Write Locks the mutex. If the lock cannot be taken immediately because * of a parallel reader, control is transferred to the caller of the current * coroutine. diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h index 3001865896..e1c8ae1a52 100644 --- a/include/qemu/error-report.h +++ b/include/qemu/error-report.h @@ -35,8 +35,15 @@ void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2); void error_vprintf_unless_qmp(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2); void error_set_progname(const char *argv0); + void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void warn_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void info_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); + void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +void warn_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +void info_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); + const char *error_get_progname(void); extern bool enable_timestamp_msg; diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h index 9239fe515e..d3a74a21fc 100644 --- a/include/qemu/hbitmap.h +++ b/include/qemu/hbitmap.h @@ -229,6 +229,21 @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count, bool finish); /** + * hbitmap_deserialize_ones + * @hb: HBitmap to operate on. + * @start: First bit to restore. + * @count: Number of bits to restore. + * @finish: Whether to call hbitmap_deserialize_finish automatically. + * + * Fills the bitmap with ones. + * + * If @finish is false, caller must call hbitmap_serialize_finish before using + * the bitmap. + */ +void hbitmap_deserialize_ones(HBitmap *hb, uint64_t start, uint64_t count, + bool finish); + +/** * hbitmap_deserialize_finish * @hb: HBitmap to operate on. * @@ -238,6 +253,14 @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count, void hbitmap_deserialize_finish(HBitmap *hb); /** + * hbitmap_sha256: + * @bitmap: HBitmap to operate on. + * + * Returns SHA256 hash of the last level. + */ +char *hbitmap_sha256(const HBitmap *bitmap, Error **errp); + +/** * hbitmap_free: * @hb: HBitmap to operate on. * @@ -256,10 +279,9 @@ void hbitmap_free(HBitmap *hb); * the lowest-numbered bit that is set in @hb, starting at @first. * * Concurrent setting of bits is acceptable, and will at worst cause the - * iteration to miss some of those bits. Resetting bits before the current - * position of the iterator is also okay. However, concurrent resetting of - * bits can lead to unexpected behavior if the iterator has not yet reached - * those bits. + * iteration to miss some of those bits. + * + * The concurrent resetting of bits is OK. */ void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first); @@ -298,24 +320,7 @@ void hbitmap_free_meta(HBitmap *hb); * Return the next bit that is set in @hbi's associated HBitmap, * or -1 if all remaining bits are zero. */ -static inline int64_t hbitmap_iter_next(HBitmapIter *hbi) -{ - unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1]; - int64_t item; - - if (cur == 0) { - cur = hbitmap_iter_skip_words(hbi); - if (cur == 0) { - return -1; - } - } - - /* The next call will resume work from the next bit. */ - hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1); - item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur); - - return item << hbi->granularity; -} +int64_t hbitmap_iter_next(HBitmapIter *hbi); /** * hbitmap_iter_next_word: diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 85596341fa..3b74f6fcb2 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -457,8 +457,6 @@ void qemu_set_tty_echo(int fd, bool echo); void os_mem_prealloc(int fd, char *area, size_t sz, int smp_cpus, Error **errp); -int qemu_read_password(char *buf, int buf_size); - /** * qemu_get_pid_name: * @pid: pid of a process diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 5c326db232..ef6b5591f7 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -106,21 +106,6 @@ SocketAddress *socket_local_address(int fd, Error **errp); SocketAddress *socket_remote_address(int fd, Error **errp); /** - * socket_address_to_string: - * @addr: the socket address struct - * @errp: pointer to uninitialized error object - * - * Get the string representation of the socket - * address. A pointer to the char array containing - * string format will be returned, the caller is - * required to release the returned value when no - * longer required with g_free. - * - * Returns: the socket address in string format, or NULL on error - */ -char *socket_address_to_string(struct SocketAddress *addr, Error **errp); - -/** * socket_address_flatten: * @addr: the socket address to flatten * diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 2706aabedf..b19159104c 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -45,6 +45,7 @@ typedef struct MachineState MachineState; typedef struct MemoryListener MemoryListener; typedef struct MemoryMappingList MemoryMappingList; typedef struct MemoryRegion MemoryRegion; +typedef struct IOMMUMemoryRegion IOMMUMemoryRegion; typedef struct MemoryRegionCache MemoryRegionCache; typedef struct MemoryRegionSection MemoryRegionSection; typedef struct MigrationIncomingState MigrationIncomingState; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 7bfd50cc32..04c31e63eb 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -265,7 +265,6 @@ struct qemu_work_item; * @cpu_index: CPU index (informative). * @nr_cores: Number of cores within this CPU package. * @nr_threads: Number of threads within this CPU. - * @host_tid: Host thread ID. * @running: #true if CPU is currently running (lockless). * @has_waiter: #true if a CPU is currently waiting for the cpu_exec_end; * valid under cpu_list_lock. @@ -319,7 +318,6 @@ struct CPUState { HANDLE hThread; #endif int thread_id; - uint32_t host_tid; bool running, has_waiter; struct QemuCond *halt_cond; bool thread_kicked; @@ -1015,6 +1013,7 @@ AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx); void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...) GCC_FMT_ATTR(2, 3); +extern Property cpu_common_props[]; void cpu_exec_initfn(CPUState *cpu); void cpu_exec_realizefn(CPUState *cpu, Error **errp); void cpu_exec_unrealizefn(CPUState *cpu); diff --git a/include/qom/object.h b/include/qom/object.h index abaeb8cf4e..1b828994fa 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -764,7 +764,7 @@ ObjectClass *object_get_class(Object *obj); * * Returns: The QOM typename of @obj. */ -const char *object_get_typename(Object *obj); +const char *object_get_typename(const Object *obj); /** * type_register_static: @@ -1319,7 +1319,7 @@ typedef enum { * callback function. It allows the link property to be set and never returns * an error. */ -void object_property_allow_set_link(Object *, const char *, +void object_property_allow_set_link(const Object *, const char *, Object *, Error **); /** @@ -1352,7 +1352,7 @@ void object_property_allow_set_link(Object *, const char *, */ void object_property_add_link(Object *obj, const char *name, const char *type, Object **child, - void (*check)(Object *obj, const char *name, + void (*check)(const Object *obj, const char *name, Object *val, Error **errp), ObjectPropertyLinkFlags flags, Error **errp); diff --git a/include/standard-headers/asm-x86/hyperv.h b/include/standard-headers/asm-x86/hyperv.h index d0c6e0a079..fac7651740 100644 --- a/include/standard-headers/asm-x86/hyperv.h +++ b/include/standard-headers/asm-x86/hyperv.h @@ -34,16 +34,10 @@ #define HV_X64_MSR_REFERENCE_TSC 0x40000021 /* - * There is a single feature flag that signifies the presence of the MSR - * that can be used to retrieve both the local APIC Timer frequency as - * well as the TSC frequency. + * There is a single feature flag that signifies if the partition has access + * to MSRs with local APIC and TSC frequencies. */ - -/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */ -#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11) - -/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */ -#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11) +#define HV_X64_ACCESS_FREQUENCY_MSRS (1 << 11) /* * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM @@ -73,6 +67,9 @@ */ #define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) +/* Frequency MSRs available */ +#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE (1 << 8) + /* Crash MSR available */ #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10) @@ -153,6 +150,12 @@ #define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9) /* + * HV_VP_SET available + */ +#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11) + + +/* * Crash notification flag. */ #define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63) diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h index 29d463af37..2fa0f4ea6b 100644 --- a/include/standard-headers/linux/input-event-codes.h +++ b/include/standard-headers/linux/input-event-codes.h @@ -600,6 +600,7 @@ #define KEY_APPSELECT 0x244 /* AL Select Task/Application */ #define KEY_SCREENSAVER 0x245 /* AL Screen Saver */ #define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ +#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index d56bb00510..c22d3ebaca 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -517,6 +517,7 @@ #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ #define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1 */ +#define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003 /* LNKCAP2 SLS Vector bit 2 */ #define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 1e05281fff..d9ea0cdb0f 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -223,7 +223,8 @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, int bytes, BdrvRequestFlags flags); int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, int bytes); -int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp); +int blk_truncate(BlockBackend *blk, int64_t offset, PreallocMode prealloc, + Error **errp); int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes); int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, int64_t pos, int size); |