diff options
Diffstat (limited to 'include')
36 files changed, 645 insertions, 354 deletions
diff --git a/include/block/block.h b/include/block/block.h index 82185965ff..8e707a83b7 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -701,6 +701,7 @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, GSList **ignore, Error **errp); AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c); +AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c); int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz); int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo); diff --git a/include/block/block_int.h b/include/block/block_int.h index b2c8b09d0f..057d88b1fc 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -843,7 +843,6 @@ struct BlockDriverState { * locking needed during I/O... */ 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 sg; /* if true, the device is a /dev/sg* */ bool probed; /* if true, format was probed rather than specified */ @@ -1008,7 +1007,6 @@ struct BlockDriverState { struct BlockBackendRootState { int open_flags; - bool read_only; BlockdevDetectZeroesOptions detect_zeroes; }; diff --git a/include/block/replication.h b/include/block/replication.h new file mode 100644 index 0000000000..21931b4f0c --- /dev/null +++ b/include/block/replication.h @@ -0,0 +1,175 @@ +/* + * Replication filter + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2016 FUJITSU LIMITED + * + * Author: + * Changlong Xie <xiecl.fnst@cn.fujitsu.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef REPLICATION_H +#define REPLICATION_H + +#include "qapi/qapi-types-block-core.h" +#include "qemu/module.h" +#include "qemu/queue.h" + +typedef struct ReplicationOps ReplicationOps; +typedef struct ReplicationState ReplicationState; + +/** + * SECTION:block/replication.h + * @title:Base Replication System + * @short_description: interfaces for handling replication + * + * The Replication Model provides a framework for handling Replication + * + * <example> + * <title>How to use replication interfaces</title> + * <programlisting> + * #include "block/replication.h" + * + * typedef struct BDRVReplicationState { + * ReplicationState *rs; + * } BDRVReplicationState; + * + * static void replication_start(ReplicationState *rs, ReplicationMode mode, + * Error **errp); + * static void replication_do_checkpoint(ReplicationState *rs, Error **errp); + * static void replication_get_error(ReplicationState *rs, Error **errp); + * static void replication_stop(ReplicationState *rs, bool failover, + * Error **errp); + * + * static ReplicationOps replication_ops = { + * .start = replication_start, + * .checkpoint = replication_do_checkpoint, + * .get_error = replication_get_error, + * .stop = replication_stop, + * } + * + * static int replication_open(BlockDriverState *bs, QDict *options, + * int flags, Error **errp) + * { + * BDRVReplicationState *s = bs->opaque; + * s->rs = replication_new(bs, &replication_ops); + * return 0; + * } + * + * static void replication_close(BlockDriverState *bs) + * { + * BDRVReplicationState *s = bs->opaque; + * replication_remove(s->rs); + * } + * + * BlockDriver bdrv_replication = { + * .format_name = "replication", + * .instance_size = sizeof(BDRVReplicationState), + * + * .bdrv_open = replication_open, + * .bdrv_close = replication_close, + * }; + * + * static void bdrv_replication_init(void) + * { + * bdrv_register(&bdrv_replication); + * } + * + * block_init(bdrv_replication_init); + * </programlisting> + * </example> + * + * We create an example about how to use replication interfaces in above. + * Then in migration, we can use replication_(start/stop/do_checkpoint/ + * get_error)_all to handle all replication operations. + */ + +/** + * ReplicationState: + * @opaque: opaque pointer value passed to this ReplicationState + * @ops: replication operation of this ReplicationState + * @node: node that we will insert into @replication_states QLIST + */ +struct ReplicationState { + void *opaque; + ReplicationOps *ops; + QLIST_ENTRY(ReplicationState) node; +}; + +/** + * ReplicationOps: + * @start: callback to start replication + * @stop: callback to stop replication + * @checkpoint: callback to do checkpoint + * @get_error: callback to check if error occurred during replication + */ +struct ReplicationOps { + void (*start)(ReplicationState *rs, ReplicationMode mode, Error **errp); + void (*stop)(ReplicationState *rs, bool failover, Error **errp); + void (*checkpoint)(ReplicationState *rs, Error **errp); + void (*get_error)(ReplicationState *rs, Error **errp); +}; + +/** + * replication_new: + * @opaque: opaque pointer value passed to ReplicationState + * @ops: replication operation of the new relevant ReplicationState + * + * Called to create a new ReplicationState instance, and then insert it + * into @replication_states QLIST + * + * Returns: the new ReplicationState instance + */ +ReplicationState *replication_new(void *opaque, ReplicationOps *ops); + +/** + * replication_remove: + * @rs: the ReplicationState instance to remove + * + * Called to remove a ReplicationState instance, and then delete it from + * @replication_states QLIST + */ +void replication_remove(ReplicationState *rs); + +/** + * replication_start_all: + * @mode: replication mode that could be "primary" or "secondary" + * @errp: returns an error if this function fails + * + * Start replication, called in migration/checkpoint thread + * + * Note: the caller of the function MUST make sure vm stopped + */ +void replication_start_all(ReplicationMode mode, Error **errp); + +/** + * replication_do_checkpoint_all: + * @errp: returns an error if this function fails + * + * This interface is called after all VM state is transferred to Secondary QEMU + */ +void replication_do_checkpoint_all(Error **errp); + +/** + * replication_get_error_all: + * @errp: returns an error if this function fails + * + * This interface is called to check if error occurred during replication + */ +void replication_get_error_all(Error **errp); + +/** + * replication_stop_all: + * @failover: boolean value that indicates if we need do failover or not + * @errp: returns an error if this function fails + * + * It is called on failover. The vm should be stopped before calling it, if you + * use this API to shutdown the guest, or other things except failover + */ +void replication_stop_all(bool failover, Error **errp); + +#endif /* REPLICATION_H */ diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 8021adf38f..754f4130c9 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -21,7 +21,6 @@ #define EXEC_ALL_H #include "cpu.h" -#include "exec/tb-context.h" #ifdef CONFIG_TCG #include "exec/cpu_ldst.h" #endif diff --git a/include/exec/memory.h b/include/exec/memory.h index c8b9088924..c158fd7084 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -617,6 +617,18 @@ struct MemoryListener { void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section); /** + * @log_sync_global: + * + * This is the global version of @log_sync when the listener does + * not have a way to synchronize the log with finer granularity. + * When the listener registers with @log_sync_global defined, then + * its @log_sync must be NULL. Vice versa. + * + * @listener: The #MemoryListener. + */ + void (*log_sync_global)(MemoryListener *listener); + + /** * @log_clear: * * Called before reading the dirty memory bitmap for a @@ -2305,7 +2317,7 @@ static inline uint8_t address_space_ldub_cached(MemoryRegionCache *cache, } static inline void address_space_stb_cached(MemoryRegionCache *cache, - hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) + hwaddr addr, uint8_t val, MemTxAttrs attrs, MemTxResult *result) { assert(addr < cache->len); if (likely(cache->ptr)) { diff --git a/include/exec/memory_ldst.h.inc b/include/exec/memory_ldst.h.inc index 46e6c220d3..7c3a641f7e 100644 --- a/include/exec/memory_ldst.h.inc +++ b/include/exec/memory_ldst.h.inc @@ -20,7 +20,7 @@ */ #ifdef TARGET_ENDIANNESS -extern uint32_t glue(address_space_lduw, SUFFIX)(ARG1_DECL, +extern uint16_t glue(address_space_lduw, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result); extern uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result); @@ -29,17 +29,17 @@ extern uint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL, extern void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stw, SUFFIX)(ARG1_DECL, - hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); + hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stl, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stq, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result); #else -extern uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, +extern uint8_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result); -extern uint32_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL, +extern uint16_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result); -extern uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL, +extern uint16_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result); extern uint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result); @@ -50,11 +50,11 @@ extern uint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL, extern uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stb, SUFFIX)(ARG1_DECL, - hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); + hwaddr addr, uint8_t val, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stw_le, SUFFIX)(ARG1_DECL, - hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); + hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stw_be, SUFFIX)(ARG1_DECL, - hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); + hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stl_le, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); extern void glue(address_space_stl_be, SUFFIX)(ARG1_DECL, diff --git a/include/exec/memory_ldst_cached.h.inc b/include/exec/memory_ldst_cached.h.inc index 7bc8790d34..d7834f852c 100644 --- a/include/exec/memory_ldst_cached.h.inc +++ b/include/exec/memory_ldst_cached.h.inc @@ -24,6 +24,18 @@ #define LD_P(size) \ glue(glue(ld, size), glue(ENDIANNESS, _p)) +static inline uint16_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + assert(addr < cache->len && 2 <= cache->len - addr); + fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr); + if (likely(cache->ptr)) { + return LD_P(uw)(cache->ptr + addr); + } else { + return ADDRESS_SPACE_LD_CACHED_SLOW(uw)(cache, addr, attrs, result); + } +} + static inline uint32_t ADDRESS_SPACE_LD_CACHED(l)(MemoryRegionCache *cache, hwaddr addr, MemTxAttrs attrs, MemTxResult *result) { @@ -48,18 +60,6 @@ static inline uint64_t ADDRESS_SPACE_LD_CACHED(q)(MemoryRegionCache *cache, } } -static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache, - hwaddr addr, MemTxAttrs attrs, MemTxResult *result) -{ - assert(addr < cache->len && 2 <= cache->len - addr); - fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr); - if (likely(cache->ptr)) { - return LD_P(uw)(cache->ptr + addr); - } else { - return ADDRESS_SPACE_LD_CACHED_SLOW(uw)(cache, addr, attrs, result); - } -} - #undef ADDRESS_SPACE_LD_CACHED #undef ADDRESS_SPACE_LD_CACHED_SLOW #undef LD_P @@ -71,25 +71,25 @@ static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache, #define ST_P(size) \ glue(glue(st, size), glue(ENDIANNESS, _p)) -static inline void ADDRESS_SPACE_ST_CACHED(l)(MemoryRegionCache *cache, - hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +static inline void ADDRESS_SPACE_ST_CACHED(w)(MemoryRegionCache *cache, + hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result) { - assert(addr < cache->len && 4 <= cache->len - addr); + assert(addr < cache->len && 2 <= cache->len - addr); if (likely(cache->ptr)) { - ST_P(l)(cache->ptr + addr, val); + ST_P(w)(cache->ptr + addr, val); } else { - ADDRESS_SPACE_ST_CACHED_SLOW(l)(cache, addr, val, attrs, result); + ADDRESS_SPACE_ST_CACHED_SLOW(w)(cache, addr, val, attrs, result); } } -static inline void ADDRESS_SPACE_ST_CACHED(w)(MemoryRegionCache *cache, +static inline void ADDRESS_SPACE_ST_CACHED(l)(MemoryRegionCache *cache, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) { - assert(addr < cache->len && 2 <= cache->len - addr); + assert(addr < cache->len && 4 <= cache->len - addr); if (likely(cache->ptr)) { - ST_P(w)(cache->ptr + addr, val); + ST_P(l)(cache->ptr + addr, val); } else { - ADDRESS_SPACE_ST_CACHED_SLOW(w)(cache, addr, val, attrs, result); + ADDRESS_SPACE_ST_CACHED_SLOW(l)(cache, addr, val, attrs, result); } } diff --git a/include/exec/memory_ldst_phys.h.inc b/include/exec/memory_ldst_phys.h.inc index b9dd53c389..ecd678610d 100644 --- a/include/exec/memory_ldst_phys.h.inc +++ b/include/exec/memory_ldst_phys.h.inc @@ -20,6 +20,12 @@ */ #ifdef TARGET_ENDIANNESS +static inline uint16_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + static inline uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr) { return glue(address_space_ldl, SUFFIX)(ARG1, addr, @@ -32,10 +38,10 @@ static inline uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr) MEMTXATTRS_UNSPECIFIED, NULL); } -static inline uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +static inline void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint16_t val) { - return glue(address_space_lduw, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); + glue(address_space_stw, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); } static inline void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) @@ -44,18 +50,30 @@ static inline void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) MEMTXATTRS_UNSPECIFIED, NULL); } -static inline void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stw, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - static inline void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) { glue(address_space_stq, SUFFIX)(ARG1, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); } #else +static inline uint8_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldub, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint16_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw_le, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint16_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw_be, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + static inline uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) { return glue(address_space_ldl_le, SUFFIX)(ARG1, addr, @@ -80,22 +98,22 @@ static inline uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) MEMTXATTRS_UNSPECIFIED, NULL); } -static inline uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +static inline void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint8_t val) { - return glue(address_space_ldub, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); + glue(address_space_stb, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); } -static inline uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +static inline void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint16_t val) { - return glue(address_space_lduw_le, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); + glue(address_space_stw_le, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); } -static inline uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +static inline void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint16_t val) { - return glue(address_space_lduw_be, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); + glue(address_space_stw_be, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); } static inline void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) @@ -110,24 +128,6 @@ static inline void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t va MEMTXATTRS_UNSPECIFIED, NULL); } -static inline void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stb, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -static inline void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stw_le, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -static inline void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stw_be, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - static inline void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) { glue(address_space_stq_le, SUFFIX)(ARG1, addr, val, diff --git a/include/exec/tb-context.h b/include/exec/tb-context.h deleted file mode 100644 index cc33979113..0000000000 --- a/include/exec/tb-context.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Internal structs that QEMU exports to TCG - * - * Copyright (c) 2003 Fabrice Bellard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef QEMU_TB_CONTEXT_H -#define QEMU_TB_CONTEXT_H - -#include "qemu/thread.h" -#include "qemu/qht.h" - -#define CODE_GEN_HTABLE_BITS 15 -#define CODE_GEN_HTABLE_SIZE (1 << CODE_GEN_HTABLE_BITS) - -typedef struct TBContext TBContext; - -struct TBContext { - - struct qht htable; - - /* statistics */ - unsigned tb_flush_count; -}; - -extern TBContext tb_ctx; - -#endif diff --git a/include/exec/tb-hash.h b/include/exec/tb-hash.h deleted file mode 100644 index 0a273d9605..0000000000 --- a/include/exec/tb-hash.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * internal execution defines for qemu - * - * Copyright (c) 2003 Fabrice Bellard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef EXEC_TB_HASH_H -#define EXEC_TB_HASH_H - -#include "exec/cpu-defs.h" -#include "exec/exec-all.h" -#include "qemu/xxhash.h" - -#ifdef CONFIG_SOFTMMU - -/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for - addresses on the same page. The top bits are the same. This allows - TLB invalidation to quickly clear a subset of the hash table. */ -#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2) -#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS) -#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1) -#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE) - -static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) -{ - target_ulong tmp; - tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); - return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK; -} - -static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) -{ - target_ulong tmp; - tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); - return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK) - | (tmp & TB_JMP_ADDR_MASK)); -} - -#else - -/* In user-mode we can get better hashing because we do not have a TLB */ -static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) -{ - return (pc ^ (pc >> TB_JMP_CACHE_BITS)) & (TB_JMP_CACHE_SIZE - 1); -} - -#endif /* CONFIG_SOFTMMU */ - -static inline -uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc, uint32_t flags, - uint32_t cf_mask, uint32_t trace_vcpu_dstate) -{ - return qemu_xxhash7(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate); -} - -#endif diff --git a/include/exec/tb-lookup.h b/include/exec/tb-lookup.h deleted file mode 100644 index 29d61ceb34..0000000000 --- a/include/exec/tb-lookup.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2017, Emilio G. Cota <cota@braap.org> - * - * License: GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ -#ifndef EXEC_TB_LOOKUP_H -#define EXEC_TB_LOOKUP_H - -#ifdef NEED_CPU_H -#include "cpu.h" -#else -#include "exec/poison.h" -#endif - -#include "exec/exec-all.h" -#include "exec/tb-hash.h" - -/* Might cause an exception, so have a longjmp destination ready */ -static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc, - target_ulong cs_base, - uint32_t flags, uint32_t cflags) -{ - TranslationBlock *tb; - uint32_t hash; - - /* we should never be trying to look up an INVALID tb */ - tcg_debug_assert(!(cflags & CF_INVALID)); - - hash = tb_jmp_cache_hash_func(pc); - tb = qatomic_rcu_read(&cpu->tb_jmp_cache[hash]); - - if (likely(tb && - tb->pc == pc && - tb->cs_base == cs_base && - tb->flags == flags && - tb->trace_vcpu_dstate == *cpu->trace_dstate && - tb_cflags(tb) == cflags)) { - return tb; - } - tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags); - if (tb == NULL) { - return NULL; - } - qatomic_set(&cpu->tb_jmp_cache[hash], tb); - return tb; -} - -#endif /* EXEC_TB_LOOKUP_H */ diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h index 2f0674fbdd..34f4cf92ae 100644 --- a/include/fpu/softfloat-helpers.h +++ b/include/fpu/softfloat-helpers.h @@ -69,7 +69,7 @@ static inline void set_float_exception_flags(int val, float_status *status) status->float_exception_flags = val; } -static inline void set_floatx80_rounding_precision(int val, +static inline void set_floatx80_rounding_precision(FloatX80RoundPrec val, float_status *status) { status->floatx80_rounding_precision = val; @@ -120,7 +120,8 @@ static inline int get_float_exception_flags(float_status *status) return status->float_exception_flags; } -static inline int get_floatx80_rounding_precision(float_status *status) +static inline FloatX80RoundPrec +get_floatx80_rounding_precision(float_status *status) { return status->floatx80_rounding_precision; } diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index ec4e27a595..81c3fe8256 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -745,4 +745,38 @@ static inline bool ne128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1) return a0 != b0 || a1 != b1; } +/* + * Similarly, comparisons of 192-bit values. + */ + +static inline bool eq192(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t b0, uint64_t b1, uint64_t b2) +{ + return ((a0 ^ b0) | (a1 ^ b1) | (a2 ^ b2)) == 0; +} + +static inline bool le192(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t b0, uint64_t b1, uint64_t b2) +{ + if (a0 != b0) { + return a0 < b0; + } + if (a1 != b1) { + return a1 < b1; + } + return a2 <= b2; +} + +static inline bool lt192(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t b0, uint64_t b1, uint64_t b2) +{ + if (a0 != b0) { + return a0 < b0; + } + if (a1 != b1) { + return a1 < b1; + } + return a2 < b2; +} + #endif diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h index 8a3f20fae9..5bcbd041f7 100644 --- a/include/fpu/softfloat-types.h +++ b/include/fpu/softfloat-types.h @@ -134,8 +134,10 @@ typedef enum __attribute__((__packed__)) { float_round_up = 2, float_round_to_zero = 3, float_round_ties_away = 4, - /* Not an IEEE rounding mode: round to the closest odd mantissa value */ + /* Not an IEEE rounding mode: round to closest odd, overflow to max */ float_round_to_odd = 5, + /* Not an IEEE rounding mode: round to closest odd, overflow to inf */ + float_round_to_odd_inf = 6, } FloatRoundMode; /* @@ -152,6 +154,14 @@ enum { float_flag_output_denormal = 128 }; +/* + * Rounding precision for floatx80. + */ +typedef enum __attribute__((__packed__)) { + floatx80_precision_x, + floatx80_precision_d, + floatx80_precision_s, +} FloatX80RoundPrec; /* * Floating Point Status. Individual architectures may maintain @@ -163,7 +173,7 @@ enum { typedef struct float_status { FloatRoundMode float_rounding_mode; uint8_t float_exception_flags; - signed char floatx80_rounding_precision; + FloatX80RoundPrec floatx80_rounding_precision; bool tininess_before_rounding; /* should denormalised results go to zero and set the inexact flag? */ bool flush_to_zero; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 53f2c2ea3c..ec7dca0960 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -1152,7 +1152,7 @@ floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status); | Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, +floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status); @@ -1165,7 +1165,7 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, | normalized. *----------------------------------------------------------------------------*/ -floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision, +floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status); @@ -1204,6 +1204,12 @@ float128 float128_rem(float128, float128, float_status *status); float128 float128_sqrt(float128, float_status *status); FloatRelation float128_compare(float128, float128, float_status *status); FloatRelation float128_compare_quiet(float128, float128, float_status *status); +float128 float128_min(float128, float128, float_status *status); +float128 float128_max(float128, float128, float_status *status); +float128 float128_minnum(float128, float128, float_status *status); +float128 float128_maxnum(float128, float128, float_status *status); +float128 float128_minnummag(float128, float128, float_status *status); +float128 float128_maxnummag(float128, float128, float_status *status); bool float128_is_quiet_nan(float128, float_status *status); bool float128_is_signaling_nan(float128, float_status *status); float128 float128_silence_nan(float128, float_status *status); diff --git a/include/glib-compat.h b/include/glib-compat.h index 4542e920d5..9e95c888f5 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -19,12 +19,12 @@ /* Ask for warnings for anything that was marked deprecated in * the defined version, or before. It is a candidate for rewrite. */ -#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_48 +#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56 /* Ask for warnings if code tries to use function that did not * exist in the defined version. These risk breaking builds */ -#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_48 +#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_56 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -68,15 +68,6 @@ * without generating warnings. */ -#if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0) -/* - * g_poll has a problem on Windows when using - * timeouts < 10ms, so use wrapper. - */ -#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, timeout) -gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); -#endif - #if defined(G_OS_UNIX) /* * Note: The fallback implementation is not MT-safe, and it returns a copy of diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h index cc308a5d2c..63025fb27c 100644 --- a/include/hw/arm/allwinner-h3.h +++ b/include/hw/arm/allwinner-h3.h @@ -18,7 +18,7 @@ */ /* - * The Allwinner H3 is a System on Chip containing four ARM Cortex A7 + * The Allwinner H3 is a System on Chip containing four ARM Cortex-A7 * processor cores. Features and specifications include DDR2/DDR3 memory, * SD/MMC storage cards, 10/100/1000Mbit Ethernet, USB 2.0, HDMI and * various I/O modules. diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index 189b23a8ce..bc6733c518 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -46,6 +46,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M) * devices will be automatically layered on top of this view.) * + Property "idau": IDAU interface (forwarded to CPU object) * + Property "init-svtor": secure VTOR reset value (forwarded to CPU object) + * + Property "init-nsvtor": non-secure VTOR reset value (forwarded to CPU object) * + Property "vfp": enable VFP (forwarded to CPU object) * + Property "dsp": enable DSP (forwarded to CPU object) * + Property "enable-bitband": expose bitbanded IO @@ -69,6 +70,7 @@ struct ARMv7MState { MemoryRegion *board_memory; Object *idau; uint32_t init_svtor; + uint32_t init_nsvtor; bool enable_bitband; bool start_powered_off; bool vfp; diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index d45f78290e..4e0ea68efc 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -80,6 +80,9 @@ struct TCGCPUOps; /* see accel-cpu.h */ struct AccelCPUClass; +/* see sysemu-cpu-ops.h */ +struct SysemuCPUOps; + /** * CPUClass: * @class_by_name: Callback to map -cpu command line model name to an @@ -87,16 +90,9 @@ struct AccelCPUClass; * @parse_features: Callback to parse command line arguments. * @reset_dump_flags: #CPUDumpFlags to use for reset logging. * @has_work: Callback for checking if there is work to do. - * @virtio_is_big_endian: Callback to return %true if a CPU which supports - * runtime configurable endianness is currently big-endian. Non-configurable - * CPUs can use the default implementation of this method. This method should - * not be used by any callers other than the pre-1.0 virtio devices. * @memory_rw_debug: Callback for GDB memory access. * @dump_state: Callback for dumping state. - * @dump_statistics: Callback for dumping statistics. * @get_arch_id: Callback for getting architecture-dependent CPU ID. - * @get_paging_enabled: Callback for inquiring whether paging is enabled. - * @get_memory_mapping: Callback for obtaining the memory mappings. * @set_pc: Callback for setting the Program Counter register. This * should have the semantics used by the target architecture when * setting the PC from a source such as an ELF file entry point; @@ -105,24 +101,8 @@ struct AccelCPUClass; * If the target behaviour here is anything other than "set * the PC register to the value passed in" then the target must * also implement the synchronize_from_tb hook. - * @get_phys_page_debug: Callback for obtaining a physical address. - * @get_phys_page_attrs_debug: Callback for obtaining a physical address and the - * associated memory transaction attributes to use for the access. - * CPUs which use memory transaction attributes should implement this - * instead of get_phys_page_debug. - * @asidx_from_attrs: Callback to return the CPU AddressSpace to use for - * a memory access with the specified memory transaction attributes. * @gdb_read_register: Callback for letting GDB read a register. * @gdb_write_register: Callback for letting GDB write a register. - * @write_elf64_note: Callback for writing a CPU-specific ELF note to a - * 64-bit VM coredump. - * @write_elf32_qemunote: Callback for writing a CPU- and QEMU-specific ELF - * note to a 32-bit VM coredump. - * @write_elf32_note: Callback for writing a CPU-specific ELF note to a - * 32-bit VM coredump. - * @write_elf32_qemunote: Callback for writing a CPU- and QEMU-specific ELF - * note to a 32-bit VM coredump. - * @vmsd: State description for migration. * @gdb_num_core_regs: Number of core registers accessible to GDB. * @gdb_core_xml_file: File name for core registers GDB XML description. * @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop @@ -150,34 +130,14 @@ struct CPUClass { int reset_dump_flags; bool (*has_work)(CPUState *cpu); - bool (*virtio_is_big_endian)(CPUState *cpu); int (*memory_rw_debug)(CPUState *cpu, vaddr addr, uint8_t *buf, int len, bool is_write); void (*dump_state)(CPUState *cpu, FILE *, int flags); - GuestPanicInformation* (*get_crash_info)(CPUState *cpu); - void (*dump_statistics)(CPUState *cpu, int flags); int64_t (*get_arch_id)(CPUState *cpu); - bool (*get_paging_enabled)(const CPUState *cpu); - void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, - Error **errp); void (*set_pc)(CPUState *cpu, vaddr value); - hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); - hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr, - MemTxAttrs *attrs); - int (*asidx_from_attrs)(CPUState *cpu, MemTxAttrs attrs); int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg); int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg); - int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, - int cpuid, void *opaque); - int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, - void *opaque); - int (*write_elf32_note)(WriteCoreDumpFunction f, CPUState *cpu, - int cpuid, void *opaque); - int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, - void *opaque); - - const VMStateDescription *vmsd; const char *gdb_core_xml_file; gchar * (*gdb_arch_name)(CPUState *cpu); const char * (*gdb_get_dynamic_xml)(CPUState *cpu, const char *xmlname); @@ -190,8 +150,11 @@ struct CPUClass { bool gdb_stop_before_watchpoint; struct AccelCPUClass *accel_cpu; + /* when system emulation is not available, this pointer is NULL */ + const struct SysemuCPUOps *sysemu_ops; + /* when TCG is not available, this pointer is NULL */ - struct TCGCPUOps *tcg_ops; + const struct TCGCPUOps *tcg_ops; /* * if not NULL, this is called in order for the CPUClass to initialize @@ -251,6 +214,7 @@ struct KVMState; struct kvm_run; struct hax_vcpu_state; +struct hvf_vcpu_state; #define TB_JMP_CACHE_BITS 12 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) @@ -329,6 +293,10 @@ struct qemu_work_item; * @ignore_memory_transaction_failures: Cached copy of the MachineState * flag of the same name: allows the board to suppress calling of the * CPU do_transaction_failed hook function. + * @kvm_dirty_gfns: Points to the KVM dirty ring for this CPU when KVM dirty + * ring is enabled. + * @kvm_fetch_index: Keeps the index that we last fetched from the per-vCPU + * dirty ring structure. * * State of one CPU core or thread. */ @@ -400,9 +368,12 @@ struct CPUState { */ uintptr_t mem_io_pc; + /* Only used in KVM */ int kvm_fd; struct KVMState *kvm_state; struct kvm_run *kvm_run; + struct kvm_dirty_gfn *kvm_dirty_gfns; + uint32_t kvm_fetch_index; /* Used for events with 'vcpu' and *without* the 'disabled' properties */ DECLARE_BITMAP(trace_dstate_delayed, CPU_TRACE_DSTATE_MAX_EVENTS); @@ -436,7 +407,7 @@ struct CPUState { struct hax_vcpu_state *hax_vcpu; - int hvf_fd; + struct hvf_vcpu_state *hvf; /* track IOMMUs whose translations we've cached in the TCG TLB */ GArray *iommu_notifiers; @@ -562,16 +533,6 @@ enum CPUDumpFlags { */ void cpu_dump_state(CPUState *cpu, FILE *f, int flags); -/** - * cpu_dump_statistics: - * @cpu: The CPU whose state is to be dumped. - * @flags: Flags what to dump. - * - * Dump CPU statistics to the current monitor if we have one, else to - * stdout. - */ -void cpu_dump_statistics(CPUState *cpu, int flags); - #ifndef CONFIG_USER_ONLY /** * cpu_get_phys_page_attrs_debug: @@ -586,18 +547,8 @@ void cpu_dump_statistics(CPUState *cpu, int flags); * * Returns: Corresponding physical page address or -1 if no page found. */ -static inline hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, - MemTxAttrs *attrs) -{ - CPUClass *cc = CPU_GET_CLASS(cpu); - - if (cc->get_phys_page_attrs_debug) { - return cc->get_phys_page_attrs_debug(cpu, addr, attrs); - } - /* Fallback for CPUs which don't implement the _attrs_ hook */ - *attrs = MEMTXATTRS_UNSPECIFIED; - return cc->get_phys_page_debug(cpu, addr); -} +hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, + MemTxAttrs *attrs); /** * cpu_get_phys_page_debug: @@ -609,12 +560,7 @@ static inline hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, * * Returns: Corresponding physical page address or -1 if no page found. */ -static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) -{ - MemTxAttrs attrs = {}; - - return cpu_get_phys_page_attrs_debug(cpu, addr, &attrs); -} +hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); /** cpu_asidx_from_attrs: * @cpu: CPU @@ -623,17 +569,16 @@ static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) * Returns the address space index specifying the CPU AddressSpace * to use for a memory access with the given transaction attributes. */ -static inline int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs) -{ - CPUClass *cc = CPU_GET_CLASS(cpu); - int ret = 0; +int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs); - if (cc->asidx_from_attrs) { - ret = cc->asidx_from_attrs(cpu, attrs); - assert(ret < cpu->num_ases && ret >= 0); - } - return ret; -} +/** + * cpu_virtio_is_big_endian: + * @cpu: CPU + + * Returns %true if a CPU which supports runtime configurable endianness + * is currently big-endian. + */ +bool cpu_virtio_is_big_endian(CPUState *cpu); #endif /* CONFIG_USER_ONLY */ @@ -1074,10 +1019,8 @@ bool target_words_bigendian(void); #ifdef NEED_CPU_H #ifdef CONFIG_SOFTMMU + extern const VMStateDescription vmstate_cpu_common; -#else -#define vmstate_cpu_common vmstate_dummy -#endif #define VMSTATE_CPU() { \ .name = "parent_obj", \ @@ -1086,6 +1029,7 @@ extern const VMStateDescription vmstate_cpu_common; .flags = VMS_STRUCT, \ .offset = 0, \ } +#endif /* CONFIG_SOFTMMU */ #endif /* NEED_CPU_H */ diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h new file mode 100644 index 0000000000..a9ba39e5f2 --- /dev/null +++ b/include/hw/core/sysemu-cpu-ops.h @@ -0,0 +1,92 @@ +/* + * CPU operations specific to system emulation + * + * Copyright (c) 2012 SUSE LINUX Products GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef SYSEMU_CPU_OPS_H +#define SYSEMU_CPU_OPS_H + +#include "hw/core/cpu.h" + +/* + * struct SysemuCPUOps: System operations specific to a CPU class + */ +typedef struct SysemuCPUOps { + /** + * @get_memory_mapping: Callback for obtaining the memory mappings. + */ + void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, + Error **errp); + /** + * @get_paging_enabled: Callback for inquiring whether paging is enabled. + */ + bool (*get_paging_enabled)(const CPUState *cpu); + /** + * @get_phys_page_debug: Callback for obtaining a physical address. + */ + hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); + /** + * @get_phys_page_attrs_debug: Callback for obtaining a physical address + * and the associated memory transaction attributes to use for the + * access. + * CPUs which use memory transaction attributes should implement this + * instead of get_phys_page_debug. + */ + hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr, + MemTxAttrs *attrs); + /** + * @asidx_from_attrs: Callback to return the CPU AddressSpace to use for + * a memory access with the specified memory transaction attributes. + */ + int (*asidx_from_attrs)(CPUState *cpu, MemTxAttrs attrs); + /** + * @get_crash_info: Callback for reporting guest crash information in + * GUEST_PANICKED events. + */ + GuestPanicInformation* (*get_crash_info)(CPUState *cpu); + /** + * @write_elf32_note: Callback for writing a CPU-specific ELF note to a + * 32-bit VM coredump. + */ + int (*write_elf32_note)(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque); + /** + * @write_elf64_note: Callback for writing a CPU-specific ELF note to a + * 64-bit VM coredump. + */ + int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque); + /** + * @write_elf32_qemunote: Callback for writing a CPU- and QEMU-specific ELF + * note to a 32-bit VM coredump. + */ + int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque); + /** + * @write_elf64_qemunote: Callback for writing a CPU- and QEMU-specific ELF + * note to a 64-bit VM coredump. + */ + int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque); + /** + * @virtio_is_big_endian: Callback to return %true if a CPU which supports + * runtime configurable endianness is currently big-endian. + * Non-configurable CPUs can use the default implementation of this method. + * This method should not be used by any callers other than the pre-1.0 + * virtio devices. + */ + bool (*virtio_is_big_endian)(CPUState *cpu); + + /** + * @legacy_vmsd: Legacy state for migration. + * Do not use in new targets, use #DeviceClass::vmsd instead. + */ + const VMStateDescription *legacy_vmsd; + +} SysemuCPUOps; + +#endif /* SYSEMU_CPU_OPS_H */ diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index bbf817af46..f05219f75e 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -223,6 +223,9 @@ struct SpaprMachineState { int fwnmi_machine_check_interlock; QemuCond fwnmi_machine_check_interlock_cond; + /* Set by -boot */ + char *boot_device; + /*< public >*/ char *kvm_type; char *host_model; diff --git a/include/hw/ppc/spapr_nvdimm.h b/include/hw/ppc/spapr_nvdimm.h index 73be250e2a..764f999f54 100644 --- a/include/hw/ppc/spapr_nvdimm.h +++ b/include/hw/ppc/spapr_nvdimm.h @@ -11,19 +11,9 @@ #define HW_SPAPR_NVDIMM_H #include "hw/mem/nvdimm.h" -#include "hw/ppc/spapr.h" -/* - * The nvdimm size should be aligned to SCM block size. - * The SCM block size should be aligned to SPAPR_MEMORY_BLOCK_SIZE - * inorder to have SCM regions not to overlap with dimm memory regions. - * The SCM devices can have variable block sizes. For now, fixing the - * block size to the minimum value. - */ -#define SPAPR_MINIMUM_SCM_BLOCK_SIZE SPAPR_MEMORY_BLOCK_SIZE - -/* Have an explicit check for alignment */ -QEMU_BUILD_BUG_ON(SPAPR_MINIMUM_SCM_BLOCK_SIZE % SPAPR_MEMORY_BLOCK_SIZE); +typedef struct SpaprDrc SpaprDrc; +typedef struct SpaprMachineState SpaprMachineState; int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, void *fdt, int *fdt_start_offset, Error **errp); diff --git a/include/hw/virtio/virtio-gpu-bswap.h b/include/hw/virtio/virtio-gpu-bswap.h index 203f9e1718..e2bee8f595 100644 --- a/include/hw/virtio/virtio-gpu-bswap.h +++ b/include/hw/virtio/virtio-gpu-bswap.h @@ -59,4 +59,20 @@ virtio_gpu_t2d_bswap(struct virtio_gpu_transfer_to_host_2d *t2d) le32_to_cpus(&t2d->padding); } +static inline void +virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob) +{ + virtio_gpu_ctrl_hdr_bswap(&cblob->hdr); + le32_to_cpus(&cblob->resource_id); + le32_to_cpus(&cblob->blob_flags); + le64_to_cpus(&cblob->size); +} + +static inline void +virtio_gpu_scanout_blob_bswap(struct virtio_gpu_set_scanout_blob *ssb) +{ + virtio_gpu_bswap_32(ssb, sizeof(*ssb) - sizeof(ssb->offsets[3])); + le32_to_cpus(&ssb->offsets[3]); +} + #endif diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 8ca2c55d9a..bcf54d970f 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -50,9 +50,23 @@ struct virtio_gpu_simple_resource { uint32_t scanout_bitmask; pixman_image_t *image; uint64_t hostmem; + + uint64_t blob_size; + void *blob; + int dmabuf_fd; + uint8_t *remapped; + QTAILQ_ENTRY(virtio_gpu_simple_resource) next; }; +struct virtio_gpu_framebuffer { + pixman_format_code_t format; + uint32_t bytes_pp; + uint32_t width, height; + uint32_t stride; + uint32_t offset; +}; + struct virtio_gpu_scanout { QemuConsole *con; DisplaySurface *ds; @@ -75,6 +89,7 @@ enum virtio_gpu_base_conf_flags { VIRTIO_GPU_FLAG_STATS_ENABLED, VIRTIO_GPU_FLAG_EDID_ENABLED, VIRTIO_GPU_FLAG_DMABUF_ENABLED, + VIRTIO_GPU_FLAG_BLOB_ENABLED, }; #define virtio_gpu_virgl_enabled(_cfg) \ @@ -85,6 +100,8 @@ enum virtio_gpu_base_conf_flags { (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED)) #define virtio_gpu_dmabuf_enabled(_cfg) \ (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED)) +#define virtio_gpu_blob_enabled(_cfg) \ + (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED)) struct virtio_gpu_base_conf { uint32_t max_outputs; @@ -133,6 +150,12 @@ struct VirtIOGPUBaseClass { DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \ DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768) +typedef struct VGPUDMABuf { + QemuDmaBuf buf; + uint32_t scanout_id; + QTAILQ_ENTRY(VGPUDMABuf) next; +} VGPUDMABuf; + struct VirtIOGPU { VirtIOGPUBase parent_obj; @@ -161,6 +184,11 @@ struct VirtIOGPU { uint32_t req_3d; uint32_t bytes_3d; } stats; + + struct { + QTAILQ_HEAD(, VGPUDMABuf) bufs; + VGPUDMABuf *primary; + } dmabuf; }; struct VirtIOGPUClass { @@ -224,7 +252,7 @@ void virtio_gpu_get_display_info(VirtIOGPU *g, void virtio_gpu_get_edid(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); int virtio_gpu_create_mapping_iov(VirtIOGPU *g, - struct virtio_gpu_resource_attach_backing *ab, + uint32_t nr_entries, uint32_t offset, struct virtio_gpu_ctrl_command *cmd, uint64_t **addr, struct iovec **iov, uint32_t *niov); @@ -238,6 +266,15 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g, struct virtio_gpu_scanout *s, uint32_t resource_id); +/* virtio-gpu-udmabuf.c */ +bool virtio_gpu_have_udmabuf(void); +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res); +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res); +int virtio_gpu_update_dmabuf(VirtIOGPU *g, + uint32_t scanout_id, + struct virtio_gpu_simple_resource *res, + struct virtio_gpu_framebuffer *fb); + /* virtio-gpu-3d.c */ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 075ee80096..8df7b69f38 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -194,8 +194,6 @@ struct VMStateDescription { const VMStateDescription **subsections; }; -extern const VMStateDescription vmstate_dummy; - extern const VMStateInfo vmstate_info_bool; extern const VMStateInfo vmstate_info_int8; diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h index 8f4b3a80fb..3ccf84fd46 100644 --- a/include/qemu/atomic.h +++ b/include/qemu/atomic.h @@ -8,7 +8,7 @@ * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. * - * See docs/devel/atomics.txt for discussion about the guarantees each + * See docs/devel/atomics.rst for discussion about the guarantees each * atomic primitive is meant to provide. */ @@ -432,7 +432,7 @@ * sequentially consistent operations. * * As long as they are used as paired operations they are safe to - * use. See docs/devel/atomics.txt for more discussion. + * use. See docs/devel/atomics.rst for more discussion. */ #ifndef qatomic_mb_read diff --git a/include/qemu/atomic128.h b/include/qemu/atomic128.h index ad2bcf45b4..adb9a1a260 100644 --- a/include/qemu/atomic128.h +++ b/include/qemu/atomic128.h @@ -6,7 +6,7 @@ * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. * - * See docs/devel/atomics.txt for discussion about the guarantees each + * See docs/devel/atomics.rst for discussion about the guarantees each * atomic primitive is meant to provide. */ diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h index 8d3e53ae4d..0500b3668d 100644 --- a/include/qemu/config-file.h +++ b/include/qemu/config-file.h @@ -1,7 +1,7 @@ #ifndef QEMU_CONFIG_FILE_H #define QEMU_CONFIG_FILE_H - +void qemu_load_module_for_opts(const char *group); QemuOptsList *qemu_find_opts(const char *group); QemuOptsList *qemu_find_opts_err(const char *group, Error **errp); QemuOpts *qemu_find_opts_singleton(const char *group); diff --git a/include/qemu/qemu-options.h b/include/qemu/qemu-options.h new file mode 100644 index 0000000000..4a62c83c45 --- /dev/null +++ b/include/qemu/qemu-options.h @@ -0,0 +1,41 @@ +/* + * qemu-options.h + * + * Defines needed for command line argument processing. + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef QEMU_OPTIONS_H +#define QEMU_OPTIONS_H + +enum { + +#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \ + opt_enum, +#define DEFHEADING(text) +#define ARCHHEADING(text, arch_mask) + +#include "qemu-options.def" +}; + +#endif diff --git a/include/standard-headers/linux/udmabuf.h b/include/standard-headers/linux/udmabuf.h new file mode 100644 index 0000000000..e19eb5b5ce --- /dev/null +++ b/include/standard-headers/linux/udmabuf.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _LINUX_UDMABUF_H +#define _LINUX_UDMABUF_H + +#include "standard-headers/linux/types.h" + +#define UDMABUF_FLAGS_CLOEXEC 0x01 + +struct udmabuf_create { + uint32_t memfd; + uint32_t flags; + uint64_t offset; + uint64_t size; +}; + +struct udmabuf_create_item { + uint32_t memfd; + uint32_t __pad; + uint64_t offset; + uint64_t size; +}; + +struct udmabuf_create_list { + uint32_t flags; + uint32_t count; + struct udmabuf_create_item list[]; +}; + +#define UDMABUF_CREATE _IOW('u', 0x42, struct udmabuf_create) +#define UDMABUF_CREATE_LIST _IOW('u', 0x43, struct udmabuf_create_list) + +#endif /* _LINUX_UDMABUF_H */ diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 880e903293..5423e3d9c6 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -66,6 +66,10 @@ typedef struct BlockDevOps { * Runs when the backend's last drain request ends. */ void (*drained_end)(void *opaque); + /* + * Is the device still busy? + */ + bool (*drained_poll)(void *opaque); } BlockDevOps; /* This struct is embedded in (the private) BlockBackend struct and contains diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h new file mode 100644 index 0000000000..8b66a4e7d0 --- /dev/null +++ b/include/sysemu/hvf_int.h @@ -0,0 +1,58 @@ +/* + * QEMU Hypervisor.framework (HVF) support + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +/* header to be included in HVF-specific code */ + +#ifndef HVF_INT_H +#define HVF_INT_H + +#include <Hypervisor/hv.h> + +/* hvf_slot flags */ +#define HVF_SLOT_LOG (1 << 0) + +typedef struct hvf_slot { + uint64_t start; + uint64_t size; + uint8_t *mem; + int slot_id; + uint32_t flags; + MemoryRegion *region; +} hvf_slot; + +typedef struct hvf_vcpu_caps { + uint64_t vmx_cap_pinbased; + uint64_t vmx_cap_procbased; + uint64_t vmx_cap_procbased2; + uint64_t vmx_cap_entry; + uint64_t vmx_cap_exit; + uint64_t vmx_cap_preemption_timer; +} hvf_vcpu_caps; + +struct HVFState { + AccelState parent; + hvf_slot slots[32]; + int num_slots; + + hvf_vcpu_caps *hvf_caps; +}; +extern HVFState *hvf_state; + +struct hvf_vcpu_state { + int fd; +}; + +void assert_hvf_ok(hv_return_t ret); +int hvf_arch_init_vcpu(CPUState *cpu); +void hvf_arch_vcpu_destroy(CPUState *cpu); +int hvf_vcpu_exec(CPUState *); +hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t); +int hvf_put_registers(CPUState *); +int hvf_get_registers(CPUState *); + +#endif diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index ccb8869f01..c788452cd9 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -23,12 +23,15 @@ typedef struct KVMSlot int old_flags; /* Dirty bitmap cache for the slot */ unsigned long *dirty_bmap; + unsigned long dirty_bmap_size; + /* Cache of the address space ID */ + int as_id; + /* Cache of the offset in ram address space */ + ram_addr_t ram_start_offset; } KVMSlot; typedef struct KVMMemoryListener { MemoryListener listener; - /* Protects the slots and all inside them */ - QemuMutex slots_lock; KVMSlot *slots; int as_id; } KVMMemoryListener; diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 0f0695e90d..74cb345308 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -27,7 +27,6 @@ #include "cpu.h" #include "exec/memop.h" -#include "exec/tb-context.h" #include "qemu/bitops.h" #include "qemu/plugin.h" #include "qemu/queue.h" diff --git a/include/ui/console.h b/include/ui/console.h index ca3c7af6a6..b30b63976a 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -471,4 +471,7 @@ bool vnc_display_reload_certs(const char *id, Error **errp); /* input.c */ int index_from_key(const char *key, size_t key_length); +/* udmabuf.c */ +int udmabuf_fd(void); + #endif diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index 87737a6f16..806ddcd7cd 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -62,6 +62,7 @@ typedef struct PixelFormat { PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format); pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian); pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format); +uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman); int qemu_pixman_get_type(int rshift, int gshift, int bshift); pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf); bool qemu_pixman_check_format(DisplayChangeListener *dcl, |