diff options
Diffstat (limited to 'include')
47 files changed, 748 insertions, 170 deletions
diff --git a/include/block/aio.h b/include/block/aio.h index 7df271d2b9..677b6ffc25 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -47,6 +47,7 @@ typedef void QEMUBHFunc(void *opaque); typedef bool AioPollFn(void *opaque); typedef void IOHandler(void *opaque); +struct Coroutine; struct ThreadPool; struct LinuxAioState; @@ -108,6 +109,9 @@ struct AioContext { bool notified; EventNotifier notifier; + QSLIST_HEAD(, Coroutine) scheduled_coroutines; + QEMUBH *co_schedule_bh; + /* Thread pool for performing work and receiving completion callbacks. * Has its own locking. */ @@ -306,12 +310,8 @@ bool aio_pending(AioContext *ctx); /* Dispatch any pending callbacks from the GSource attached to the AioContext. * * This is used internally in the implementation of the GSource. - * - * @dispatch_fds: true to process fds, false to skip them - * (can be used as an optimization by callers that know there - * are no fds ready) */ -bool aio_dispatch(AioContext *ctx, bool dispatch_fds); +void aio_dispatch(AioContext *ctx); /* Progress in completing AIO work to occur. This can issue new pending * aio as a result of executing I/O completion or bh callbacks. @@ -483,6 +483,34 @@ static inline bool aio_node_check(AioContext *ctx, bool is_external) } /** + * aio_co_schedule: + * @ctx: the aio context + * @co: the coroutine + * + * Start a coroutine on a remote AioContext. + * + * The coroutine must not be entered by anyone else while aio_co_schedule() + * is active. In addition the coroutine must have yielded unless ctx + * is the context in which the coroutine is running (i.e. the value of + * qemu_get_current_aio_context() from the coroutine itself). + */ +void aio_co_schedule(AioContext *ctx, struct Coroutine *co); + +/** + * aio_co_wake: + * @co: the coroutine + * + * Restart a coroutine on the AioContext where it was running last, thus + * preventing coroutines from jumping from one context to another when they + * go to sleep. + * + * aio_co_wake may be executed either in coroutine or non-coroutine + * context. The coroutine must not be entered by anyone else while + * aio_co_wake() is active. + */ +void aio_co_wake(struct Coroutine *co); + +/** * Return the AioContext whose event loop runs in the current thread. * * If called from an IOThread this will be the IOThread's AioContext. If diff --git a/include/block/block.h b/include/block/block.h index 4e81f2069b..bde5ebda18 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -215,6 +215,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, const char *bdref_key, Error **errp); BlockDriverState *bdrv_open(const char *filename, const char *reference, QDict *options, int flags, Error **errp); +BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name, + int flags, Error **errp); BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, BlockDriverState *bs, QDict *options, int flags); @@ -253,7 +255,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_get_backing_file_depth(BlockDriverState *bs); void bdrv_refresh_filename(BlockDriverState *bs); -int bdrv_truncate(BlockDriverState *bs, int64_t offset); +int bdrv_truncate(BdrvChild *child, int64_t offset); int64_t bdrv_nb_sectors(BlockDriverState *bs); int64_t bdrv_getlength(BlockDriverState *bs); int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index 2d92d7edfe..1670941da9 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -430,8 +430,9 @@ struct BdrvChild { * copied as well. */ struct BlockDriverState { - int64_t total_sectors; /* if we are reading a disk image, give its - size in sectors */ + /* Protected by big QEMU lock or read-only after opening. No special + * 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 */ @@ -439,14 +440,6 @@ struct BlockDriverState { bool sg; /* if true, the device is a /dev/sg* */ bool probed; /* if true, format was probed rather than specified */ - int copy_on_read; /* if nonzero, copy read backing sectors into image. - note this is a reference count */ - - CoQueue flush_queue; /* Serializing flush queue */ - bool active_flush_req; /* Flush request in flight? */ - unsigned int write_gen; /* Current data generation */ - unsigned int flushed_gen; /* Flushed write generation */ - BlockDriver *drv; /* NULL means no media */ void *opaque; @@ -468,18 +461,6 @@ struct BlockDriverState { BdrvChild *backing; BdrvChild *file; - /* Callback before write request is processed */ - NotifierWithReturnList before_write_notifiers; - - /* number of in-flight requests; overall and serialising */ - unsigned int in_flight; - unsigned int serialising_in_flight; - - bool wakeup; - - /* Offset after the highest byte written to */ - uint64_t wr_highest_offset; - /* I/O Limits */ BlockLimits bl; @@ -497,11 +478,8 @@ struct BlockDriverState { QTAILQ_ENTRY(BlockDriverState) bs_list; /* element of the list of monitor-owned BDS */ QTAILQ_ENTRY(BlockDriverState) monitor_list; - QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps; int refcnt; - QLIST_HEAD(, BdrvTrackedRequest) tracked_requests; - /* operation blockers */ QLIST_HEAD(, BdrvOpBlocker) op_blockers[BLOCK_OP_TYPE_MAX]; @@ -522,6 +500,31 @@ struct BlockDriverState { /* The error object in use for blocking operations on backing_hd */ Error *backing_blocker; + /* Protected by AioContext lock */ + + /* If true, copy read backing sectors into image. Can be >1 if more + * than one client has requested copy-on-read. + */ + int copy_on_read; + + /* If we are reading a disk image, give its size in sectors. + * Generally read-only; it is written to by load_vmstate and save_vmstate, + * but the block layer is quiescent during those. + */ + int64_t total_sectors; + + /* Callback before write request is processed */ + NotifierWithReturnList before_write_notifiers; + + /* number of in-flight requests; overall and serialising */ + unsigned int in_flight; + unsigned int serialising_in_flight; + + bool wakeup; + + /* Offset after the highest byte written to */ + uint64_t wr_highest_offset; + /* threshold limit for writes, in bytes. "High water mark". */ uint64_t write_threshold_offset; NotifierWithReturn write_threshold_notifier; @@ -529,6 +532,17 @@ struct BlockDriverState { /* counter for nested bdrv_io_plug */ unsigned io_plugged; + QLIST_HEAD(, BdrvTrackedRequest) tracked_requests; + CoQueue flush_queue; /* Serializing flush queue */ + bool active_flush_req; /* Flush request in flight? */ + unsigned int write_gen; /* Current data generation */ + unsigned int flushed_gen; /* Flushed write generation */ + + QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps; + + /* do we need to tell the quest if we have a volatile write cache? */ + int enable_write_cache; + int quiesce_counter; }; diff --git a/include/disas/bfd.h b/include/disas/bfd.h index 0435b8c9f9..b01e002b4c 100644 --- a/include/disas/bfd.h +++ b/include/disas/bfd.h @@ -295,6 +295,7 @@ typedef struct disassemble_info { The bottom 16 bits are for the internal use of the disassembler. */ unsigned long flags; #define INSN_HAS_RELOC 0x80000000 +#define INSN_ARM_BE32 0x00010000 PTR private_data; /* Function used to get bytes to disassemble. MEMADDR is the @@ -306,6 +307,12 @@ typedef struct disassemble_info { (bfd_vma memaddr, bfd_byte *myaddr, int length, struct disassemble_info *info); + /* A place to stash the real read_memory_func if read_memory_func wants to + do some funky address arithmetic or similar (e.g. for ARM BE32 mode). */ + int (*read_memory_inner_func) + (bfd_vma memaddr, bfd_byte *myaddr, int length, + struct disassemble_info *info); + /* Function which should be called if we get an error that we can't recover from. STATUS is the errno value from read_memory_func and MEMADDR is the address that we were trying to read. INFO is a diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index d454c005b7..3f941783c5 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -23,8 +23,6 @@ /* cputlb.c */ void tlb_protect_code(ram_addr_t ram_addr); void tlb_unprotect_code(ram_addr_t ram_addr); -void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start, - uintptr_t length); extern int tlb_flush_count; #endif diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index bbc9478a50..bcde1e6a14 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -93,6 +93,27 @@ void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx); */ void tlb_flush_page(CPUState *cpu, target_ulong addr); /** + * tlb_flush_page_all_cpus: + * @cpu: src CPU of the flush + * @addr: virtual address of page to be flushed + * + * Flush one page from the TLB of the specified CPU, for all + * MMU indexes. + */ +void tlb_flush_page_all_cpus(CPUState *src, target_ulong addr); +/** + * tlb_flush_page_all_cpus_synced: + * @cpu: src CPU of the flush + * @addr: virtual address of page to be flushed + * + * Flush one page from the TLB of the specified CPU, for all MMU + * indexes like tlb_flush_page_all_cpus except the source vCPUs work + * is scheduled as safe work meaning all flushes will be complete once + * the source vCPUs safe work is complete. This will depend on when + * the guests translation ends the TB. + */ +void tlb_flush_page_all_cpus_synced(CPUState *src, target_ulong addr); +/** * tlb_flush: * @cpu: CPU whose TLB should be flushed * @@ -103,24 +124,87 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr); */ void tlb_flush(CPUState *cpu); /** + * tlb_flush_all_cpus: + * @cpu: src CPU of the flush + */ +void tlb_flush_all_cpus(CPUState *src_cpu); +/** + * tlb_flush_all_cpus_synced: + * @cpu: src CPU of the flush + * + * Like tlb_flush_all_cpus except this except the source vCPUs work is + * scheduled as safe work meaning all flushes will be complete once + * the source vCPUs safe work is complete. This will depend on when + * the guests translation ends the TB. + */ +void tlb_flush_all_cpus_synced(CPUState *src_cpu); +/** * tlb_flush_page_by_mmuidx: * @cpu: CPU whose TLB should be flushed * @addr: virtual address of page to be flushed - * @...: list of MMU indexes to flush, terminated by a negative value + * @idxmap: bitmap of MMU indexes to flush * * Flush one page from the TLB of the specified CPU, for the specified * MMU indexes. */ -void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...); +void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, + uint16_t idxmap); +/** + * tlb_flush_page_by_mmuidx_all_cpus: + * @cpu: Originating CPU of the flush + * @addr: virtual address of page to be flushed + * @idxmap: bitmap of MMU indexes to flush + * + * Flush one page from the TLB of all CPUs, for the specified + * MMU indexes. + */ +void tlb_flush_page_by_mmuidx_all_cpus(CPUState *cpu, target_ulong addr, + uint16_t idxmap); +/** + * tlb_flush_page_by_mmuidx_all_cpus_synced: + * @cpu: Originating CPU of the flush + * @addr: virtual address of page to be flushed + * @idxmap: bitmap of MMU indexes to flush + * + * Flush one page from the TLB of all CPUs, for the specified MMU + * indexes like tlb_flush_page_by_mmuidx_all_cpus except the source + * vCPUs work is scheduled as safe work meaning all flushes will be + * complete once the source vCPUs safe work is complete. This will + * depend on when the guests translation ends the TB. + */ +void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *cpu, target_ulong addr, + uint16_t idxmap); /** * tlb_flush_by_mmuidx: * @cpu: CPU whose TLB should be flushed - * @...: list of MMU indexes to flush, terminated by a negative value + * @wait: If true ensure synchronisation by exiting the cpu_loop + * @idxmap: bitmap of MMU indexes to flush * * Flush all entries from the TLB of the specified CPU, for the specified * MMU indexes. */ -void tlb_flush_by_mmuidx(CPUState *cpu, ...); +void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap); +/** + * tlb_flush_by_mmuidx_all_cpus: + * @cpu: Originating CPU of the flush + * @idxmap: bitmap of MMU indexes to flush + * + * Flush all entries from all TLBs of all CPUs, for the specified + * MMU indexes. + */ +void tlb_flush_by_mmuidx_all_cpus(CPUState *cpu, uint16_t idxmap); +/** + * tlb_flush_by_mmuidx_all_cpus_synced: + * @cpu: Originating CPU of the flush + * @idxmap: bitmap of MMU indexes to flush + * + * Flush all entries from all TLBs of all CPUs, for the specified + * MMU indexes like tlb_flush_by_mmuidx_all_cpus except except the source + * vCPUs work is scheduled as safe work meaning all flushes will be + * complete once the source vCPUs safe work is complete. This will + * depend on when the guests translation ends the TB. + */ +void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, uint16_t idxmap); /** * tlb_set_page_with_attrs: * @cpu: CPU to add this TLB entry for @@ -162,17 +246,45 @@ void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx, static inline void tlb_flush_page(CPUState *cpu, target_ulong addr) { } - +static inline void tlb_flush_page_all_cpus(CPUState *src, target_ulong addr) +{ +} +static inline void tlb_flush_page_all_cpus_synced(CPUState *src, + target_ulong addr) +{ +} static inline void tlb_flush(CPUState *cpu) { } - +static inline void tlb_flush_all_cpus(CPUState *src_cpu) +{ +} +static inline void tlb_flush_all_cpus_synced(CPUState *src_cpu) +{ +} static inline void tlb_flush_page_by_mmuidx(CPUState *cpu, - target_ulong addr, ...) + target_ulong addr, uint16_t idxmap) { } -static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...) +static inline void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap) +{ +} +static inline void tlb_flush_page_by_mmuidx_all_cpus(CPUState *cpu, + target_ulong addr, + uint16_t idxmap) +{ +} +static inline void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *cpu, + target_ulong addr, + uint16_t idxmap) +{ +} +static inline void tlb_flush_by_mmuidx_all_cpus(CPUState *cpu, uint16_t idxmap) +{ +} +static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, + uint16_t idxmap) { } #endif @@ -318,6 +430,7 @@ static inline void tb_set_jmp_target(TranslationBlock *tb, static inline void tb_add_jump(TranslationBlock *tb, int n, TranslationBlock *tb_next) { + assert(n < ARRAY_SIZE(tb->jmp_list_next)); if (tb->jmp_list_next[n]) { /* Another thread has already done this while we were * outside of the lock; nothing to do in this case */ @@ -403,8 +516,4 @@ bool memory_region_is_unassigned(MemoryRegion *mr); /* vl.c */ extern int singlestep; -/* cpu-exec.c, accessed with atomic_mb_read/atomic_mb_set */ -extern CPUState *tcg_current_cpu; -extern bool exit_request; - #endif diff --git a/include/exec/memory.h b/include/exec/memory.h index 987f9251c6..691102317c 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1426,6 +1426,8 @@ struct MemoryRegionCache { bool is_write; }; +#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .mr = NULL }) + /* address_space_cache_init: prepare for repeated access to a physical * memory region * diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 842ec6b22a..f1288efa87 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -180,6 +180,8 @@ enum { 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 */ + float_round_to_odd = 5, }; /*---------------------------------------------------------------------------- @@ -712,6 +714,9 @@ int32_t float128_to_int32(float128, float_status *status); int32_t float128_to_int32_round_to_zero(float128, float_status *status); int64_t float128_to_int64(float128, float_status *status); int64_t float128_to_int64_round_to_zero(float128, float_status *status); +uint64_t float128_to_uint64(float128, float_status *status); +uint64_t float128_to_uint64_round_to_zero(float128, float_status *status); +uint32_t float128_to_uint32_round_to_zero(float128, float_status *status); float32 float128_to_float32(float128, float_status *status); float64 float128_to_float64(float128, float_status *status); floatx80 float128_to_floatx80(float128, float_status *status); diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 1ab5deaa08..dbec0c1598 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -19,6 +19,7 @@ #include "hw/timer/aspeed_timer.h" #include "hw/i2c/aspeed_i2c.h" #include "hw/ssi/aspeed_smc.h" +#include "hw/watchdog/wdt_aspeed.h" #define ASPEED_SPIS_NUM 2 @@ -37,6 +38,7 @@ typedef struct AspeedSoCState { AspeedSMCState fmc; AspeedSMCState spi[ASPEED_SPIS_NUM]; AspeedSDMCState sdmc; + AspeedWDTState wdt; } AspeedSoCState; #define TYPE_ASPEED_SOC "aspeed-soc" diff --git a/include/hw/boards.h b/include/hw/boards.h index ac891a828b..269d0ba399 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -41,15 +41,20 @@ int machine_phandle_start(MachineState *machine); bool machine_dump_guest_core(MachineState *machine); bool machine_mem_merge(MachineState *machine); void machine_register_compat_props(MachineState *machine); +HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine); /** * CPUArchId: * @arch_id - architecture-dependent CPU ID of present or possible CPU * @cpu - pointer to corresponding CPU object if it's present on NULL otherwise + * @props - CPU object properties, initialized by board + * #vcpus_count - number of threads provided by @cpu object */ typedef struct { uint64_t arch_id; - struct CPUState *cpu; + int64_t vcpus_count; + CpuInstanceProperties props; + Object *cpu; } CPUArchId; /** @@ -82,10 +87,8 @@ typedef struct { * Returns an array of @CPUArchId architecture-dependent CPU IDs * which includes CPU IDs for present and possible to hotplug CPUs. * Caller is responsible for freeing returned list. - * @query_hotpluggable_cpus: - * Returns a @HotpluggableCPUList, which describes CPUs objects which - * could be added with -device/device_add. - * Caller is responsible for freeing returned list. + * @has_hotpluggable_cpus: + * If true, board supports CPUs creation with -device/device_add. * @minimum_page_bits: * If non-zero, the board promises never to create a CPU with a page size * smaller than this, so QEMU can use a more efficient larger page @@ -131,12 +134,12 @@ struct MachineClass { bool option_rom_has_mr; bool rom_file_has_mr; int minimum_page_bits; + bool has_hotpluggable_cpus; HotplugHandler *(*get_hotplug_handler)(MachineState *machine, DeviceState *dev); unsigned (*cpu_index_to_socket_id)(unsigned cpu_index); const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine); - HotpluggableCPUList *(*query_hotpluggable_cpus)(MachineState *machine); }; /** @@ -178,6 +181,7 @@ struct MachineState { char *initrd_filename; const char *cpu_model; AccelState *accelerator; + CPUArchIdList *possible_cpus; }; #define DEFINE_MACHINE(namestr, machine_initfn) \ diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 405c9d122e..fe645aa93a 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -257,6 +257,8 @@ struct IntelIOMMUState { uint8_t womask[DMAR_REG_SIZE]; /* WO (write only - read returns 0) */ uint32_t version; + bool caching_mode; /* RO - is cap CM enabled? */ + dma_addr_t root; /* Current root table pointer */ bool root_extended; /* Type of root table (extended or not) */ bool dmar_enabled; /* Set if DMA remapping is enabled */ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 079e8d9393..d1f45540a1 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -73,7 +73,6 @@ struct PCMachineState { /* CPU and apic information: */ bool apic_xrupt_override; unsigned apic_id_limit; - CPUArchIdList *possible_cpus; uint16_t boot_cpus; /* NUMA information: */ diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index 0fec91cdb0..7f0a80af9d 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -26,8 +26,8 @@ #define HW_PS2_H #define PS2_MOUSE_BUTTON_LEFT 0x01 -#define PS2_MOUSE_BUTTON_MIDDLE 0x02 -#define PS2_MOUSE_BUTTON_RIGHT 0x04 +#define PS2_MOUSE_BUTTON_RIGHT 0x02 +#define PS2_MOUSE_BUTTON_MIDDLE 0x04 #define PS2_MOUSE_BUTTON_SIDE 0x08 #define PS2_MOUSE_BUTTON_EXTRA 0x10 diff --git a/include/hw/loader-fit.h b/include/hw/loader-fit.h new file mode 100644 index 0000000000..9e2a068a20 --- /dev/null +++ b/include/hw/loader-fit.h @@ -0,0 +1,41 @@ +/* + * Flattened Image Tree loader. + * + * Copyright (c) 2016 Imagination Technologies + * + * 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 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 HW_LOADER_FIT_H +#define HW_LOADER_FIT_H + +#include <exec/hwaddr.h> + +struct fit_loader_match { + const char *compatible; + const void *data; +}; + +struct fit_loader { + const struct fit_loader_match *matches; + hwaddr (*addr_to_phys)(void *opaque, uint64_t addr); + const void *(*fdt_filter)(void *opaque, const void *fdt, + const void *match_data, hwaddr *load_addr); + const void *(*kernel_filter)(void *opaque, const void *kernel, + hwaddr *load_addr, hwaddr *entry_addr); +}; + +int load_fit(const struct fit_loader *ldr, const char *filename, void *opaque); + +#endif /* HW_LOADER_FIT_H */ diff --git a/include/hw/loader.h b/include/hw/loader.h index 0dbd8d6bf3..40c4153e58 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -164,6 +164,8 @@ int load_uimage(const char *filename, hwaddr *ep, */ int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz); +ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, size_t srclen); + ssize_t read_targphys(const char *name, int fd, hwaddr dst_addr, size_t nbytes); void pstrcpy_targphys(const char *name, @@ -214,4 +216,8 @@ void hmp_info_roms(Monitor *mon, const QDict *qdict); int rom_add_vga(const char *file); int rom_add_option(const char *file, int32_t bootindex); +/* This is the usual maximum in uboot, so if a uImage overflows this, it would + * overflow on real hardware too. */ +#define UBOOT_MAX_GUNZIP_BYTES (64 << 20) + #endif diff --git a/include/hw/m68k/mcf.h b/include/hw/m68k/mcf.h index 9a0bcfa0f4..0db49c5e60 100644 --- a/include/hw/m68k/mcf.h +++ b/include/hw/m68k/mcf.h @@ -4,17 +4,13 @@ #include "target/m68k/cpu-qom.h" -struct MemoryRegion; - /* mcf_uart.c */ uint64_t mcf_uart_read(void *opaque, hwaddr addr, unsigned size); void mcf_uart_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); void *mcf_uart_init(qemu_irq irq, Chardev *chr); -void mcf_uart_mm_init(struct MemoryRegion *sysmem, - hwaddr base, - qemu_irq irq, Chardev *chr); +void mcf_uart_mm_init(hwaddr base, qemu_irq irq, Chardev *chr); /* mcf_intc.c */ qemu_irq *mcf_intc_init(struct MemoryRegion *sysmem, diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h index a209d91ded..c9dfcb4b84 100644 --- a/include/hw/misc/mips_cmgcr.h +++ b/include/hw/misc/mips_cmgcr.h @@ -41,6 +41,9 @@ #define GCR_L2_CONFIG_BYPASS_SHF 20 #define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF) +/* GCR_BASE register fields */ +#define GCR_BASE_GCRBASE_MSK 0xffffffff8000ULL + /* GCR_GIC_BASE register fields */ #define GCR_GIC_BASE_GICEN_MSK 1 #define GCR_GIC_BASE_GICBASE_MSK 0xFFFFFFFE0000ULL diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h new file mode 100644 index 0000000000..3462d85836 --- /dev/null +++ b/include/hw/misc/unimp.h @@ -0,0 +1,39 @@ +/* + * "Unimplemented" device + * + * Copyright Linaro Limited, 2017 + * Written by Peter Maydell + */ + +#ifndef HW_MISC_UNIMP_H +#define HW_MISC_UNIMP_H + +#define TYPE_UNIMPLEMENTED_DEVICE "unimplemented-device" + +/** + * create_unimplemented_device: create and map a dummy device + * @name: name of the device for debug logging + * @base: base address of the device's MMIO region + * @size: size of the device's MMIO region + * + * This utility function creates and maps an instance of unimplemented-device, + * which is a dummy device which simply logs all guest accesses to + * it via the qemu_log LOG_UNIMP debug log. + * The device is mapped at priority -1000, which means that you can + * use it to cover a large region and then map other devices on top of it + * if necessary. + */ +static inline void create_unimplemented_device(const char *name, + hwaddr base, + hwaddr size) +{ + DeviceState *dev = qdev_create(NULL, TYPE_UNIMPLEMENTED_DEVICE); + + qdev_prop_set_string(dev, "name", name); + qdev_prop_set_uint64(dev, "size", size); + qdev_init_nofail(dev); + + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(dev), 0, base, -1000); +} + +#endif diff --git a/include/hw/pci-host/xilinx-pcie.h b/include/hw/pci-host/xilinx-pcie.h new file mode 100644 index 0000000000..bec66b27c5 --- /dev/null +++ b/include/hw/pci-host/xilinx-pcie.h @@ -0,0 +1,68 @@ +/* + * Xilinx PCIe host controller emulation. + * + * Copyright (c) 2016 Imagination Technologies + * + * 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 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 HW_XILINX_PCIE_H +#define HW_XILINX_PCIE_H + +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pcie_host.h" + +#define TYPE_XILINX_PCIE_HOST "xilinx-pcie-host" +#define XILINX_PCIE_HOST(obj) \ + OBJECT_CHECK(XilinxPCIEHost, (obj), TYPE_XILINX_PCIE_HOST) + +#define TYPE_XILINX_PCIE_ROOT "xilinx-pcie-root" +#define XILINX_PCIE_ROOT(obj) \ + OBJECT_CHECK(XilinxPCIERoot, (obj), TYPE_XILINX_PCIE_ROOT) + +typedef struct XilinxPCIERoot { + PCIBridge parent_obj; +} XilinxPCIERoot; + +typedef struct XilinxPCIEInt { + uint32_t fifo_reg1; + uint32_t fifo_reg2; +} XilinxPCIEInt; + +typedef struct XilinxPCIEHost { + PCIExpressHost parent_obj; + + char name[16]; + + uint32_t bus_nr; + uint64_t cfg_base, cfg_size; + uint64_t mmio_base, mmio_size; + bool link_up; + qemu_irq irq; + + MemoryRegion mmio, io; + + XilinxPCIERoot root; + + uint32_t intr; + uint32_t intr_mask; + XilinxPCIEInt intr_fifo[16]; + unsigned int intr_fifo_r, intr_fifo_w; + uint32_t rpscr; +} XilinxPCIEHost; + +#endif /* HW_XILINX_PCIE_H */ diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index cbc1fdfb5b..6983f13745 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -97,6 +97,7 @@ #define PCI_DEVICE_ID_REDHAT_BRIDGE_SEAT 0x000a #define PCI_DEVICE_ID_REDHAT_PXB_PCIE 0x000b #define PCI_DEVICE_ID_REDHAT_PCIE_RP 0x000c +#define PCI_DEVICE_ID_REDHAT_XHCI 0x000d #define PCI_DEVICE_ID_REDHAT_QXL 0x0100 #define FMT_PCIBUS PRIx64 @@ -687,6 +688,8 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); +void lsi53c895a_create(PCIBus *bus); + qemu_irq pci_allocate_irq(PCIDevice *pci_dev); void pci_set_irq(PCIDevice *pci_dev, int level); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a2d8964f7e..f9b17d860a 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -94,7 +94,6 @@ struct sPAPRMachineState { /*< public >*/ char *kvm_type; MemoryHotplugState hotplug_memory; - Object **cores; }; #define H_SUCCESS 0 diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 50292f48b1..3c35665221 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -34,12 +34,6 @@ typedef struct sPAPRCPUCoreClass { ObjectClass *cpu_class; } sPAPRCPUCoreClass; -void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, - Error **errp); char *spapr_get_cpu_core_type(const char *model); -void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, - Error **errp); -void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, - Error **errp); void spapr_cpu_core_class_init(ObjectClass *oc, void *data); #endif diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h index 9094edadf5..f9e6890c90 100644 --- a/include/hw/s390x/s390_flic.h +++ b/include/hw/s390x/s390_flic.h @@ -17,8 +17,13 @@ #include "hw/s390x/adapter.h" #include "hw/virtio/virtio.h" -#define ADAPTER_ROUTES_MAX_GSI 64 -#define VIRTIO_CCW_QUEUE_MAX ADAPTER_ROUTES_MAX_GSI +/* + * Reserve enough gsis to accommodate all virtio devices. + * If any other user of adapter routes needs more of these, + * we need to bump the value; but virtio looks like the + * maximum right now. + */ +#define ADAPTER_ROUTES_MAX_GSI VIRTIO_QUEUE_MAX typedef struct AdapterRoutes { AdapterInfo adapter; @@ -32,6 +37,8 @@ typedef struct AdapterRoutes { typedef struct S390FLICState { SysBusDevice parent_obj; + /* to limit AdapterRoutes.num_routes for compat */ + uint32_t adapter_routes_max_batch; } S390FLICState; diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 9bad49e917..6b85786dbf 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -177,7 +177,8 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, int unit, bool removable, int bootindex, const char *serial, Error **errp); -void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp); +void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated); +void scsi_legacy_handle_cmdline(void); /* * Predefined sense codes diff --git a/include/hw/timer/mips_gictimer.h b/include/hw/timer/mips_gictimer.h index c8bc5d2541..c7ca6c821d 100644 --- a/include/hw/timer/mips_gictimer.h +++ b/include/hw/timer/mips_gictimer.h @@ -31,6 +31,7 @@ struct MIPSGICTimerState { MIPSGICTimerCB *cb; }; +uint32_t mips_gictimer_get_freq(MIPSGICTimerState *gic); uint32_t mips_gictimer_get_sh_count(MIPSGICTimerState *gic); void mips_gictimer_store_sh_count(MIPSGICTimerState *gic, uint64_t count); uint32_t mips_gictimer_get_vp_compare(MIPSGICTimerState *gictimer, diff --git a/include/hw/usb.h b/include/hw/usb.h index 43838c9f5d..eb28655270 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -135,6 +135,8 @@ #define USB_REQ_GET_INTERFACE 0x0A #define USB_REQ_SET_INTERFACE 0x0B #define USB_REQ_SYNCH_FRAME 0x0C +#define USB_REQ_SET_SEL 0x30 +#define USB_REQ_SET_ISOCH_DELAY 0x31 #define USB_DEVICE_SELF_POWERED 0 #define USB_DEVICE_REMOTE_WAKEUP 1 @@ -289,11 +291,6 @@ typedef struct USBDeviceClass { void (*cancel_packet)(USBDevice *dev, USBPacket *p); /* - * Called when device is destroyed. - */ - void (*handle_destroy)(USBDevice *dev); - - /* * Attach the device */ void (*handle_attach)(USBDevice *dev); diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h index 91ae14d254..2e92074bd1 100644 --- a/include/hw/virtio/virtio-access.h +++ b/include/hw/virtio/virtio-access.h @@ -156,6 +156,58 @@ static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s) #endif } +static inline uint16_t virtio_lduw_phys_cached(VirtIODevice *vdev, + MemoryRegionCache *cache, + hwaddr pa) +{ + if (virtio_access_is_big_endian(vdev)) { + return lduw_be_phys_cached(cache, pa); + } + return lduw_le_phys_cached(cache, pa); +} + +static inline uint32_t virtio_ldl_phys_cached(VirtIODevice *vdev, + MemoryRegionCache *cache, + hwaddr pa) +{ + if (virtio_access_is_big_endian(vdev)) { + return ldl_be_phys_cached(cache, pa); + } + return ldl_le_phys_cached(cache, pa); +} + +static inline uint64_t virtio_ldq_phys_cached(VirtIODevice *vdev, + MemoryRegionCache *cache, + hwaddr pa) +{ + if (virtio_access_is_big_endian(vdev)) { + return ldq_be_phys_cached(cache, pa); + } + return ldq_le_phys_cached(cache, pa); +} + +static inline void virtio_stw_phys_cached(VirtIODevice *vdev, + MemoryRegionCache *cache, + hwaddr pa, uint16_t value) +{ + if (virtio_access_is_big_endian(vdev)) { + stw_be_phys_cached(cache, pa, value); + } else { + stw_le_phys_cached(cache, pa, value); + } +} + +static inline void virtio_stl_phys_cached(VirtIODevice *vdev, + MemoryRegionCache *cache, + hwaddr pa, uint32_t value) +{ + if (virtio_access_is_big_endian(vdev)) { + stl_be_phys_cached(cache, pa, value); + } else { + stl_le_phys_cached(cache, pa, value); + } +} + static inline void virtio_tswap16s(VirtIODevice *vdev, uint16_t *s) { *s = virtio_tswap16(vdev, *s); diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 9734b4c446..d3c8a6fa8c 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -80,6 +80,6 @@ typedef struct MultiReqBuffer { bool is_write; } MultiReqBuffer; -void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq); +bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq); #endif diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 8ea56a8f60..1eec9a2da3 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -47,7 +47,7 @@ typedef struct VirtIONetQueue { VirtQueue *tx_vq; QEMUTimer *tx_timer; QEMUBH *tx_bh; - int tx_waiting; + uint32_t tx_waiting; struct { VirtQueueElement *elem; } async_tx; @@ -68,7 +68,7 @@ typedef struct VirtIONet { size_t guest_hdr_len; uint32_t host_features; uint8_t has_ufo; - int mergeable_rx_bufs; + uint32_t mergeable_rx_bufs; uint8_t promisc; uint8_t allmulti; uint8_t alluni; diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 73751969ba..f536f77e68 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -126,9 +126,9 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp, VirtIOHandleOutput cmd); void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp); -void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq); -void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq); -void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq); +bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq); +bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq); +bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq); void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req); void virtio_scsi_free_req(VirtIOSCSIReq *req); void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 525da24222..15efcf2057 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -85,6 +85,7 @@ struct VirtIODevice uint32_t generation; int nvectors; VirtQueue *vq; + MemoryListener listener; uint16_t device_id; bool vm_running; bool broken; /* device in invalid state, needs reset */ @@ -154,6 +155,7 @@ void virtio_error(VirtIODevice *vdev, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name); typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *); +typedef bool (*VirtIOHandleAIOOutput)(VirtIODevice *, VirtQueue *); VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, VirtIOHandleOutput handle_output); @@ -284,8 +286,7 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev); EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq); void virtio_queue_host_notifier_read(EventNotifier *n); void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx, - void (*fn)(VirtIODevice *, - VirtQueue *)); + VirtIOHandleAIOOutput handle_output); VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector); VirtQueue *virtio_vector_next_queue(VirtQueue *vq); diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h new file mode 100644 index 0000000000..080c223122 --- /dev/null +++ b/include/hw/watchdog/wdt_aspeed.h @@ -0,0 +1,32 @@ +/* + * ASPEED Watchdog Controller + * + * Copyright (C) 2016-2017 IBM Corp. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ +#ifndef ASPEED_WDT_H +#define ASPEED_WDT_H + +#include "hw/sysbus.h" + +#define TYPE_ASPEED_WDT "aspeed.wdt" +#define ASPEED_WDT(obj) \ + OBJECT_CHECK(AspeedWDTState, (obj), TYPE_ASPEED_WDT) + +#define ASPEED_WDT_REGS_MAX (0x20 / 4) + +typedef struct AspeedWDTState { + /*< private >*/ + SysBusDevice parent_obj; + QEMUTimer *timer; + + /*< public >*/ + MemoryRegion iomem; + uint32_t regs[ASPEED_WDT_REGS_MAX]; + + uint32_t pclk_freq; +} AspeedWDTState; + +#endif /* ASPEED_WDT_H */ diff --git a/include/io/channel.h b/include/io/channel.h index 32a9470794..5d48906998 100644 --- a/include/io/channel.h +++ b/include/io/channel.h @@ -23,6 +23,8 @@ #include "qemu-common.h" #include "qom/object.h" +#include "qemu/coroutine.h" +#include "block/aio.h" #define TYPE_QIO_CHANNEL "qio-channel" #define QIO_CHANNEL(obj) \ @@ -80,6 +82,9 @@ struct QIOChannel { Object parent; unsigned int features; /* bitmask of QIOChannelFeatures */ char *name; + AioContext *ctx; + Coroutine *read_coroutine; + Coroutine *write_coroutine; #ifdef _WIN32 HANDLE event; /* For use with GSource on Win32 */ #endif @@ -132,6 +137,11 @@ struct QIOChannelClass { off_t offset, int whence, Error **errp); + void (*io_set_aio_fd_handler)(QIOChannel *ioc, + AioContext *ctx, + IOHandler *io_read, + IOHandler *io_write, + void *opaque); }; /* General I/O handling functions */ @@ -497,13 +507,50 @@ guint qio_channel_add_watch(QIOChannel *ioc, /** + * qio_channel_attach_aio_context: + * @ioc: the channel object + * @ctx: the #AioContext to set the handlers on + * + * Request that qio_channel_yield() sets I/O handlers on + * the given #AioContext. If @ctx is %NULL, qio_channel_yield() + * uses QEMU's main thread event loop. + * + * You can move a #QIOChannel from one #AioContext to another even if + * I/O handlers are set for a coroutine. However, #QIOChannel provides + * no synchronization between the calls to qio_channel_yield() and + * qio_channel_attach_aio_context(). + * + * Therefore you should first call qio_channel_detach_aio_context() + * to ensure that the coroutine is not entered concurrently. Then, + * while the coroutine has yielded, call qio_channel_attach_aio_context(), + * and then aio_co_schedule() to place the coroutine on the new + * #AioContext. The calls to qio_channel_detach_aio_context() + * and qio_channel_attach_aio_context() should be protected with + * aio_context_acquire() and aio_context_release(). + */ +void qio_channel_attach_aio_context(QIOChannel *ioc, + AioContext *ctx); + +/** + * qio_channel_detach_aio_context: + * @ioc: the channel object + * + * Disable any I/O handlers set by qio_channel_yield(). With the + * help of aio_co_schedule(), this allows moving a coroutine that was + * paused by qio_channel_yield() to another context. + */ +void qio_channel_detach_aio_context(QIOChannel *ioc); + +/** * qio_channel_yield: * @ioc: the channel object * @condition: the I/O condition to wait for * - * Yields execution from the current coroutine until - * the condition indicated by @condition becomes - * available. + * Yields execution from the current coroutine until the condition + * indicated by @condition becomes available. @condition must + * be either %G_IO_IN or %G_IO_OUT; it cannot contain both. In + * addition, no two coroutine can be waiting on the same condition + * and channel at the same time. * * This must only be called from coroutine context */ @@ -525,4 +572,23 @@ void qio_channel_yield(QIOChannel *ioc, void qio_channel_wait(QIOChannel *ioc, GIOCondition condition); +/** + * qio_channel_set_aio_fd_handler: + * @ioc: the channel object + * @ctx: the AioContext to set the handlers on + * @io_read: the read handler + * @io_write: the write handler + * @opaque: the opaque value passed to the handler + * + * This is used internally by qio_channel_yield(). It can + * be used by channel implementations to forward the handlers + * to another channel (e.g. from #QIOChannelTLS to the + * underlying socket). + */ +void qio_channel_set_aio_fd_handler(QIOChannel *ioc, + AioContext *ctx, + IOHandler *io_read, + IOHandler *io_write, + void *opaque); + #endif /* QIO_CHANNEL_H */ diff --git a/include/migration/colo.h b/include/migration/colo.h index e32eef4763..2bbff9e6c2 100644 --- a/include/migration/colo.h +++ b/include/migration/colo.h @@ -35,4 +35,6 @@ COLOMode get_colo_mode(void); /* failover */ void colo_do_failover(MigrationState *s); + +void colo_checkpoint_notify(void *opaque); #endif diff --git a/include/migration/migration.h b/include/migration/migration.h index af9135f0a7..1735d66512 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -116,13 +116,13 @@ struct MigrationIncomingState { QemuThread colo_incoming_thread; /* The coroutine we should enter (back) after failover */ Coroutine *migration_incoming_co; + QemuSemaphore colo_incoming_sem; /* See savevm.c */ LoadStateEntry_Head loadvm_handlers; }; MigrationIncomingState *migration_incoming_get_current(void); -MigrationIncomingState *migration_incoming_state_new(QEMUFile *f); void migration_incoming_state_destroy(void); /* @@ -188,6 +188,13 @@ struct MigrationState QSIMPLEQ_HEAD(src_page_requests, MigrationSrcPageRequest) src_page_requests; /* The RAMBlock used in the last src_page_request */ RAMBlock *last_req_rb; + /* The semaphore is used to notify COLO thread that failover is finished */ + QemuSemaphore colo_exit_sem; + + /* The semaphore is used to notify COLO thread to do checkpoint */ + QemuSemaphore colo_checkpoint_sem; + int64_t colo_checkpoint_time; + QEMUTimer *colo_delay_timer; /* The last error that occurred */ Error *error; @@ -286,6 +293,7 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms); int ram_discard_range(MigrationIncomingState *mis, const char *block_name, uint64_t start, size_t length); int ram_postcopy_incoming_init(MigrationIncomingState *mis); +void ram_postcopy_migrated_memory_release(MigrationState *ms); /** * @migrate_add_blocker - prevent migration from proceeding @@ -305,6 +313,7 @@ int migrate_add_blocker(Error *reason, Error **errp); */ void migrate_del_blocker(Error *reason); +bool migrate_release_ram(void); bool migrate_postcopy_ram(void); bool migrate_zero_blocks(void); diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index abedd466c9..0cd648a733 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -132,7 +132,8 @@ void qemu_put_byte(QEMUFile *f, int v); * put_buffer without copying the buffer. * The buffer should be available till it is sent asynchronously. */ -void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size); +void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size, + bool may_free); bool qemu_file_mode_is_not_valid(const char *mode); bool qemu_file_is_writable(QEMUFile *f); diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 3bbe3ed984..63e7b02e05 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -259,6 +259,7 @@ extern const VMStateInfo vmstate_info_cpudouble; extern const VMStateInfo vmstate_info_timer; extern const VMStateInfo vmstate_info_buffer; extern const VMStateInfo vmstate_info_unused_buffer; +extern const VMStateInfo vmstate_info_tmp; extern const VMStateInfo vmstate_info_bitmap; extern const VMStateInfo vmstate_info_qtailq; @@ -587,7 +588,8 @@ extern const VMStateInfo vmstate_info_qtailq; .offset = vmstate_offset_buffer(_state, _field) + _start, \ } -#define VMSTATE_VBUFFER_MULTIPLY(_field, _state, _version, _test, _start, _field_size, _multiply) { \ +#define VMSTATE_VBUFFER_MULTIPLY(_field, _state, _version, _test, \ + _field_size, _multiply) { \ .name = (stringify(_field)), \ .version_id = (_version), \ .field_exists = (_test), \ @@ -596,10 +598,9 @@ extern const VMStateInfo vmstate_info_qtailq; .info = &vmstate_info_buffer, \ .flags = VMS_VBUFFER|VMS_POINTER|VMS_MULTIPLY, \ .offset = offsetof(_state, _field), \ - .start = (_start), \ } -#define VMSTATE_VBUFFER(_field, _state, _version, _test, _start, _field_size) { \ +#define VMSTATE_VBUFFER(_field, _state, _version, _test, _field_size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ .field_exists = (_test), \ @@ -607,10 +608,9 @@ extern const VMStateInfo vmstate_info_qtailq; .info = &vmstate_info_buffer, \ .flags = VMS_VBUFFER|VMS_POINTER, \ .offset = offsetof(_state, _field), \ - .start = (_start), \ } -#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _start, _field_size) { \ +#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _field_size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ .field_exists = (_test), \ @@ -618,10 +618,10 @@ extern const VMStateInfo vmstate_info_qtailq; .info = &vmstate_info_buffer, \ .flags = VMS_VBUFFER|VMS_POINTER, \ .offset = offsetof(_state, _field), \ - .start = (_start), \ } -#define VMSTATE_VBUFFER_ALLOC_UINT32(_field, _state, _version, _test, _start, _field_size) { \ +#define VMSTATE_VBUFFER_ALLOC_UINT32(_field, _state, _version, \ + _test, _field_size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ .field_exists = (_test), \ @@ -629,7 +629,6 @@ extern const VMStateInfo vmstate_info_qtailq; .info = &vmstate_info_buffer, \ .flags = VMS_VBUFFER|VMS_POINTER|VMS_ALLOC, \ .offset = offsetof(_state, _field), \ - .start = (_start), \ } #define VMSTATE_BUFFER_UNSAFE_INFO_TEST(_field, _state, _test, _version, _info, _size) { \ @@ -651,6 +650,24 @@ extern const VMStateInfo vmstate_info_qtailq; .offset = offsetof(_state, _field), \ } +/* Allocate a temporary of type 'tmp_type', set tmp->parent to _state + * and execute the vmsd on the temporary. Note that we're working with + * the whole of _state here, not a field within it. + * We compile time check that: + * That _tmp_type contains a 'parent' member that's a pointer to the + * '_state' type + * That the pointer is right at the start of _tmp_type. + */ +#define VMSTATE_WITH_TMP(_state, _tmp_type, _vmsd) { \ + .name = "tmp", \ + .size = sizeof(_tmp_type) + \ + QEMU_BUILD_BUG_ON_ZERO(offsetof(_tmp_type, parent) != 0) + \ + type_check_pointer(_state, \ + typeof_field(_tmp_type, parent)), \ + .vmsd = &(_vmsd), \ + .info = &vmstate_info_tmp, \ +} + #define VMSTATE_UNUSED_BUFFER(_test, _version, _size) { \ .name = "unused", \ .field_exists = (_test), \ @@ -660,6 +677,17 @@ extern const VMStateInfo vmstate_info_qtailq; .flags = VMS_BUFFER, \ } +/* Discard size * field_num bytes, where field_num is a uint32 member */ +#define VMSTATE_UNUSED_VARRAY_UINT32(_state, _test, _version, _field_num, _size) {\ + .name = "unused", \ + .field_exists = (_test), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ + .version_id = (_version), \ + .size = (_size), \ + .info = &vmstate_info_unused_buffer, \ + .flags = VMS_VARRAY_UINT32 | VMS_BUFFER, \ +} + /* _field_size should be a int32_t field in the _state struct giving the * size of the bitmap _field in bits. */ @@ -948,13 +976,10 @@ extern const VMStateInfo vmstate_info_qtailq; VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, 0) #define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size) \ - VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size) + VMSTATE_VBUFFER(_f, _s, 0, NULL, _size) #define VMSTATE_PARTIAL_VBUFFER_UINT32(_f, _s, _size) \ - VMSTATE_VBUFFER_UINT32(_f, _s, 0, NULL, 0, _size) - -#define VMSTATE_SUB_VBUFFER(_f, _s, _start, _size) \ - VMSTATE_VBUFFER(_f, _s, 0, NULL, _start, _size) + VMSTATE_VBUFFER_UINT32(_f, _s, 0, NULL, _size) #define VMSTATE_BUFFER_TEST(_f, _s, _test) \ VMSTATE_STATIC_BUFFER(_f, _s, 0, _test, 0, sizeof(typeof_field(_s, _f))) @@ -985,17 +1010,20 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque); +/* Returns: 0 on success, -1 on failure */ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, const VMStateDescription *vmsd, void *base, int alias_id, - int required_for_version); + int required_for_version, + Error **errp); +/* Returns: 0 on success, -1 on failure */ static inline int vmstate_register(DeviceState *dev, int instance_id, const VMStateDescription *vmsd, void *opaque) { return vmstate_register_with_alias_id(dev, instance_id, vmsd, - opaque, -1, 0); + opaque, -1, 0, NULL); } void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index 12584ed1b7..e60beaff81 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -112,11 +112,56 @@ bool qemu_in_coroutine(void); */ bool qemu_coroutine_entered(Coroutine *co); +/** + * Provides a mutex that can be used to synchronise coroutines + */ +struct CoWaitRecord; +typedef struct CoMutex { + /* Count of pending lockers; 0 for a free mutex, 1 for an + * uncontended mutex. + */ + unsigned locked; + + /* Context that is holding the lock. Useful to avoid spinning + * when two coroutines on the same AioContext try to get the lock. :) + */ + AioContext *ctx; + + /* A queue of waiters. Elements are added atomically in front of + * from_push. to_pop is only populated, and popped from, by whoever + * is in charge of the next wakeup. This can be an unlocker or, + * through the handoff protocol, a locker that is about to go to sleep. + */ + QSLIST_HEAD(, CoWaitRecord) from_push, to_pop; + + unsigned handoff, sequence; + + Coroutine *holder; +} CoMutex; + +/** + * Initialises a CoMutex. This must be called before any other operation is used + * on the CoMutex. + */ +void qemu_co_mutex_init(CoMutex *mutex); + +/** + * Locks the mutex. If the lock cannot be taken immediately, control is + * transferred to the caller of the current coroutine. + */ +void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex); + +/** + * Unlocks the mutex and schedules the next coroutine that was waiting for this + * lock to be run. + */ +void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex); + /** * CoQueues are a mechanism to queue coroutines in order to continue executing - * them later. They provide the fundamental primitives on which coroutine locks - * are built. + * them later. They are similar to condition variables, but they need help + * from an external mutex in order to maintain thread-safety. */ typedef struct CoQueue { QSIMPLEQ_HEAD(, Coroutine) entries; @@ -130,9 +175,10 @@ void qemu_co_queue_init(CoQueue *queue); /** * Adds the current coroutine to the CoQueue and transfers control to the - * caller of the coroutine. + * caller of the coroutine. The mutex is unlocked during the wait and + * locked again afterwards. */ -void coroutine_fn qemu_co_queue_wait(CoQueue *queue); +void coroutine_fn qemu_co_queue_wait(CoQueue *queue, CoMutex *mutex); /** * Restarts the next coroutine in the CoQueue and removes it from the queue. @@ -157,36 +203,10 @@ bool qemu_co_enter_next(CoQueue *queue); bool qemu_co_queue_empty(CoQueue *queue); -/** - * Provides a mutex that can be used to synchronise coroutines - */ -typedef struct CoMutex { - bool locked; - Coroutine *holder; - CoQueue queue; -} CoMutex; - -/** - * Initialises a CoMutex. This must be called before any other operation is used - * on the CoMutex. - */ -void qemu_co_mutex_init(CoMutex *mutex); - -/** - * Locks the mutex. If the lock cannot be taken immediately, control is - * transferred to the caller of the current coroutine. - */ -void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex); - -/** - * Unlocks the mutex and schedules the next coroutine that was waiting for this - * lock to be run. - */ -void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex); - typedef struct CoRwlock { - bool writer; + int pending_writer; int reader; + CoMutex mutex; CoQueue queue; } CoRwlock; diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h index 14d4f1d1f2..cb98892bba 100644 --- a/include/qemu/coroutine_int.h +++ b/include/qemu/coroutine_int.h @@ -40,12 +40,21 @@ struct Coroutine { CoroutineEntry *entry; void *entry_arg; Coroutine *caller; + + /* Only used when the coroutine has terminated. */ QSLIST_ENTRY(Coroutine) pool_next; + size_t locks_held; - /* Coroutines that should be woken up when we yield or terminate */ + /* Coroutines that should be woken up when we yield or terminate. + * Only used when the coroutine is running. + */ QSIMPLEQ_HEAD(, Coroutine) co_queue_wakeup; + + /* Only used when the coroutine has yielded. */ + AioContext *ctx; QSIMPLEQ_ENTRY(Coroutine) co_queue_next; + QSLIST_ENTRY(Coroutine) co_scheduled_next; }; Coroutine *qemu_coroutine_new(void); diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h index 8033929139..f0878eaafa 100644 --- a/include/qemu/cutils.h +++ b/include/qemu/cutils.h @@ -130,34 +130,19 @@ int qemu_strtol(const char *nptr, const char **endptr, int base, long *result); int qemu_strtoul(const char *nptr, const char **endptr, int base, unsigned long *result); -int qemu_strtoll(const char *nptr, const char **endptr, int base, - int64_t *result); -int qemu_strtoull(const char *nptr, const char **endptr, int base, +int qemu_strtoi64(const char *nptr, const char **endptr, int base, + int64_t *result); +int qemu_strtou64(const char *nptr, const char **endptr, int base, uint64_t *result); int parse_uint(const char *s, unsigned long long *value, char **endptr, int base); int parse_uint_full(const char *s, unsigned long long *value, int base); -/* - * qemu_strtosz() suffixes used to specify the default treatment of an - * argument passed to qemu_strtosz() without an explicit suffix. - * These should be defined using upper case characters in the range - * A-Z, as qemu_strtosz() will use qemu_toupper() on the given argument - * prior to comparison. - */ -#define QEMU_STRTOSZ_DEFSUFFIX_EB 'E' -#define QEMU_STRTOSZ_DEFSUFFIX_PB 'P' -#define QEMU_STRTOSZ_DEFSUFFIX_TB 'T' -#define QEMU_STRTOSZ_DEFSUFFIX_GB 'G' -#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M' -#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K' -#define QEMU_STRTOSZ_DEFSUFFIX_B 'B' -int64_t qemu_strtosz(const char *nptr, char **end); -int64_t qemu_strtosz_suffix(const char *nptr, char **end, - const char default_suffix); -int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end, - const char default_suffix, int64_t unit); +int qemu_strtosz(const char *nptr, char **end, uint64_t *result); +int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result); +int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result); + #define K_BYTE (1ULL << 10) #define M_BYTE (1ULL << 20) #define G_BYTE (1ULL << 30) diff --git a/include/qemu/option.h b/include/qemu/option.h index 1f9e3f939d..e786df0cfa 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -100,6 +100,15 @@ typedef int (*qemu_opt_loopfunc)(void *opaque, int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, Error **errp); +typedef struct { + QemuOpts *opts; + QemuOpt *opt; + const char *name; +} QemuOptsIter; + +void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *name); +const char *qemu_opt_iter_next(QemuOptsIter *iter); + QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id); QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists, Error **errp); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index ca4d0fb1b4..3e61c880da 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -132,6 +132,8 @@ struct TranslationBlock; * @cpu_exec_exit: Callback for cpu_exec cleanup. * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec. * @disas_set_info: Setup architecture specific components of disassembly info + * @adjust_watchpoint_address: Perform a target-specific adjustment to an + * address before attempting to match it against watchpoints. * * Represents a CPU family or model. */ @@ -156,6 +158,7 @@ typedef struct CPUClass { uint8_t *buf, int len, bool is_write); void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); + GuestPanicInformation* (*get_crash_info)(CPUState *cpu); void (*dump_statistics)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); int64_t (*get_arch_id)(CPUState *cpu); @@ -195,6 +198,7 @@ typedef struct CPUClass { bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request); void (*disas_set_info)(CPUState *cpu, disassemble_info *info); + vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len); } CPUClass; #ifdef HOST_WORDS_BIGENDIAN @@ -325,6 +329,7 @@ struct CPUState { bool unplug; bool crash_occurred; bool exit_request; + /* updates protected by BQL */ uint32_t interrupt_request; int singlestep_enabled; int64_t icount_extra; @@ -397,6 +402,12 @@ struct CPUState { bool hax_vcpu_dirty; struct hax_vcpu_state *hax_vcpu; + + /* The pending_tlb_flush flag is set and cleared atomically to + * avoid potential races. The aim of the flag is to avoid + * unnecessary flushes. + */ + uint16_t pending_tlb_flush; }; QTAILQ_HEAD(CPUTailQ, CPUState); @@ -412,6 +423,15 @@ extern struct CPUTailQ cpus; extern __thread CPUState *current_cpu; /** + * qemu_tcg_mttcg_enabled: + * Check whether we are running MultiThread TCG or not. + * + * Returns: %true if we are in MTTCG mode %false otherwise. + */ +extern bool mttcg_enabled; +#define qemu_tcg_mttcg_enabled() (mttcg_enabled) + +/** * cpu_paging_enabled: * @cpu: The CPU whose state is to be inspected. * @@ -469,6 +489,15 @@ int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, void *opaque); /** + * cpu_get_crash_info: + * @cpu: The CPU to get crash information for + * + * Gets the previously saved crash information. + * Caller is responsible for freeing the data. + */ +GuestPanicInformation *cpu_get_crash_info(CPUState *cpu); + +/** * CPUDumpFlags: * @CPU_DUMP_CODE: * @CPU_DUMP_FPU: dump FPU register state, not just integer diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 6444e41d39..f365a51acf 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -64,14 +64,20 @@ typedef struct BlockDevOps { * fields that must be public. This is in particular for QLIST_ENTRY() and * friends so that BlockBackends can be kept in lists outside block-backend.c */ typedef struct BlockBackendPublic { - /* I/O throttling. - * throttle_state tells us if this BlockBackend has I/O limits configured. - * io_limits_disabled tells us if they are currently being enforced */ + /* I/O throttling has its own locking, but also some fields are + * protected by the AioContext lock. + */ + + /* Protected by AioContext lock. */ CoQueue throttled_reqs[2]; + + /* Nonzero if the I/O limits are currently being ignored; generally + * it is zero. */ unsigned int io_limits_disabled; /* The following fields are protected by the ThrottleGroup lock. - * See the ThrottleGroup documentation for details. */ + * See the ThrottleGroup documentation for details. + * throttle_state tells us if I/O limits are configured. */ ThrottleState *throttle_state; ThrottleTimers throttle_timers; unsigned pending_reqs[2]; diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index 16432f3508..ac22f2ae1f 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -19,12 +19,11 @@ void blockdev_auto_del(BlockBackend *blk); typedef enum { IF_DEFAULT = -1, /* for use with drive_add() only */ /* - * IF_IDE must be zero, because we want MachineClass member - * block_default_type to default-initialize to IF_IDE + * IF_NONE must be zero, because we want MachineClass member + * block_default_type to default-initialize to IF_NONE */ - IF_IDE = 0, - IF_NONE, - IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN, + IF_NONE = 0, + IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN, IF_COUNT } BlockInterfaceType; @@ -49,7 +48,7 @@ BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo); void override_max_devs(BlockInterfaceType type, int max_devs); DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); -bool drive_check_orphaned(void); +void drive_check_orphaned(void); DriveInfo *drive_get_by_index(BlockInterfaceType type, int index); int drive_get_max_bus(BlockInterfaceType type); int drive_get_max_devs(BlockInterfaceType type); diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3728a1ea7e..a73b5d4bce 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -36,4 +36,6 @@ extern int smp_threads; void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg); +void qemu_tcg_configure(QemuOpts *opts, Error **errp); + #endif diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 4d50694930..576c7ce640 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -37,6 +37,7 @@ void vm_state_notify(int running, RunState state); #define VMRESET_REPORT true void vm_start(void); +int vm_prepare_start(void); int vm_stop(RunState state); int vm_stop_force_state(RunState state); @@ -60,11 +61,12 @@ void qemu_register_powerdown_notifier(Notifier *notifier); void qemu_system_debug_request(void); void qemu_system_vmstop_request(RunState reason); void qemu_system_vmstop_request_prepare(void); +bool qemu_vmstop_requested(RunState *r); int qemu_shutdown_requested_get(void); int qemu_reset_requested_get(void); void qemu_system_killed(int signal, pid_t pid); void qemu_system_reset(bool report); -void qemu_system_guest_panicked(void); +void qemu_system_guest_panicked(GuestPanicInformation *info); size_t qemu_target_page_bits(void); void qemu_add_exit_notifier(Notifier *notify); diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h index 03fcf4bba2..88a13e827b 100644 --- a/include/ui/egl-helpers.h +++ b/include/ui/egl-helpers.h @@ -14,8 +14,7 @@ extern int qemu_egl_rn_fd; extern struct gbm_device *qemu_egl_rn_gbm_dev; extern EGLContext qemu_egl_rn_ctx; -int qemu_egl_rendernode_open(void); -int egl_rendernode_init(void); +int egl_rendernode_init(const char *rendernode); int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc); #endif |