diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/block/replication.h | 175 | ||||
| -rw-r--r-- | include/exec/exec-all.h | 1 | ||||
| -rw-r--r-- | include/exec/memory.h | 14 | ||||
| -rw-r--r-- | include/exec/memory_ldst.h.inc | 16 | ||||
| -rw-r--r-- | include/exec/memory_ldst_cached.h.inc | 42 | ||||
| -rw-r--r-- | include/exec/memory_ldst_phys.h.inc | 72 | ||||
| -rw-r--r-- | include/exec/tb-context.h | 41 | ||||
| -rw-r--r-- | include/exec/tb-hash.h | 69 | ||||
| -rw-r--r-- | include/exec/tb-lookup.h | 49 | ||||
| -rw-r--r-- | include/hw/core/cpu.h | 101 | ||||
| -rw-r--r-- | include/hw/core/sysemu-cpu-ops.h | 92 | ||||
| -rw-r--r-- | include/migration/vmstate.h | 2 | ||||
| -rw-r--r-- | include/qemu/config-file.h | 2 | ||||
| -rw-r--r-- | include/qemu/qemu-options.h | 41 | ||||
| -rw-r--r-- | include/sysemu/kvm_int.h | 7 | ||||
| -rw-r--r-- | include/tcg/tcg.h | 1 |
16 files changed, 420 insertions, 305 deletions
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/hw/core/cpu.h b/include/hw/core/cpu.h index d45f78290e..044f668a6e 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,10 @@ 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 +102,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 +131,15 @@ 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 +152,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 @@ -329,6 +294,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 +369,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); @@ -586,18 +558,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 +571,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 +580,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 +1030,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 +1040,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/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/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/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" |