diff options
Diffstat (limited to 'include')
29 files changed, 777 insertions, 203 deletions
diff --git a/include/block/aio.h b/include/block/aio.h index b9fe2cb37e..c7ae27c91c 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -18,7 +18,6 @@ #include "qemu/queue.h" #include "qemu/event_notifier.h" #include "qemu/thread.h" -#include "qemu/rfifolock.h" #include "qemu/timer.h" typedef struct BlockAIOCB BlockAIOCB; @@ -54,7 +53,7 @@ struct AioContext { GSource source; /* Protects all fields from multi-threaded access */ - RFifoLock lock; + QemuRecMutex lock; /* The list of registered AIO handlers */ QLIST_HEAD(, AioHandler) aio_handlers; @@ -116,9 +115,6 @@ struct AioContext { bool notified; EventNotifier notifier; - /* Scheduling this BH forces the event loop it iterate */ - QEMUBH *notify_dummy_bh; - /* Thread pool for performing work and receiving completion callbacks */ struct ThreadPool *thread_pool; @@ -453,6 +449,24 @@ static inline bool aio_node_check(AioContext *ctx, bool is_external) } /** + * Return the AioContext whose event loop runs in the current thread. + * + * If called from an IOThread this will be the IOThread's AioContext. If + * called from another thread it will be the main loop AioContext. + */ +AioContext *qemu_get_current_aio_context(void); + +/** + * @ctx: the aio context + * + * Return whether we are running in the I/O thread that manages @ctx. + */ +static inline bool aio_context_in_iothread(AioContext *ctx) +{ + return ctx == qemu_get_current_aio_context(); +} + +/** * aio_context_setup: * @ctx: the aio context * diff --git a/include/block/block.h b/include/block/block.h index 107c603605..b7dc7d54ae 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -218,7 +218,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference, BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, BlockDriverState *bs, QDict *options, int flags); -int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp); +int bdrv_reopen_multiple(AioContext *ctx, BlockReopenQueue *bs_queue, Error **errp); int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp); int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, Error **errp); @@ -314,17 +314,11 @@ BlockAIOCB *bdrv_aio_writev(BdrvChild *child, int64_t sector_num, BlockCompletionFunc *cb, void *opaque); BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque); -BlockAIOCB *bdrv_aio_pdiscard(BlockDriverState *bs, - int64_t offset, int count, - BlockCompletionFunc *cb, void *opaque); void bdrv_aio_cancel(BlockAIOCB *acb); void bdrv_aio_cancel_async(BlockAIOCB *acb); /* sg packet commands */ -int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf); -BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, - unsigned long int req, void *buf, - BlockCompletionFunc *cb, void *opaque); +int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); /* Invalidate any cached metadata used by image formats */ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp); @@ -340,6 +334,35 @@ void bdrv_drain(BlockDriverState *bs); void coroutine_fn bdrv_co_drain(BlockDriverState *bs); void bdrv_drain_all(void); +#define BDRV_POLL_WHILE(bs, cond) ({ \ + bool waited_ = false; \ + BlockDriverState *bs_ = (bs); \ + AioContext *ctx_ = bdrv_get_aio_context(bs_); \ + if (aio_context_in_iothread(ctx_)) { \ + while ((cond)) { \ + aio_poll(ctx_, true); \ + waited_ = true; \ + } \ + } else { \ + assert(qemu_get_current_aio_context() == \ + qemu_get_aio_context()); \ + /* Ask bdrv_dec_in_flight to wake up the main \ + * QEMU AioContext. Extra I/O threads never take \ + * other I/O threads' AioContexts (see for example \ + * block_job_defer_to_main_loop for how to do it). \ + */ \ + assert(!bs_->wakeup); \ + bs_->wakeup = true; \ + while ((cond)) { \ + aio_context_release(ctx_); \ + aio_poll(qemu_get_aio_context(), true); \ + aio_context_acquire(ctx_); \ + waited_ = true; \ + } \ + bs_->wakeup = false; \ + } \ + waited_; }) + int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int count); int bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, int count); int bdrv_has_zero_init_1(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index 3e79228eb0..e7ff58419c 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -62,8 +62,6 @@ enum BdrvTrackedRequestType { BDRV_TRACKED_READ, BDRV_TRACKED_WRITE, - BDRV_TRACKED_FLUSH, - BDRV_TRACKED_IOCTL, BDRV_TRACKED_DISCARD, }; @@ -244,6 +242,8 @@ struct BlockDriver { BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf, BlockCompletionFunc *cb, void *opaque); + int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs, + unsigned long int req, void *buf); /* List of options for creating images, terminated by name == NULL */ QemuOptsList *create_opts; @@ -443,7 +443,7 @@ struct BlockDriverState { note this is a reference count */ CoQueue flush_queue; /* Serializing flush queue */ - BdrvTrackedRequest *active_flush_req; /* Flush request in flight */ + bool active_flush_req; /* Flush request in flight? */ unsigned int write_gen; /* Current data generation */ unsigned int flushed_gen; /* Flushed write generation */ @@ -471,9 +471,12 @@ struct BlockDriverState { /* Callback before write request is processed */ NotifierWithReturnList before_write_notifiers; - /* number of in-flight serialising requests */ + /* 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; @@ -632,6 +635,21 @@ void bdrv_remove_aio_context_notifier(BlockDriverState *bs, void (*aio_context_detached)(void *), void *opaque); +/** + * bdrv_wakeup: + * @bs: The BlockDriverState for which an I/O operation has been completed. + * + * Wake up the main thread if it is waiting on BDRV_POLL_WHILE. During + * synchronous I/O on a BlockDriverState that is attached to another + * I/O thread, the main thread lets the I/O thread's event loop run, + * waiting for the I/O operation to complete. A bdrv_wakeup will wake + * up the main thread if necessary. + * + * Manual calls to bdrv_wakeup are rarely necessary, because + * bdrv_dec_in_flight already calls it. + */ +void bdrv_wakeup(BlockDriverState *bs); + #ifdef _WIN32 int is_windows_drive(const char *filename); #endif @@ -785,6 +803,9 @@ bool bdrv_requests_pending(BlockDriverState *bs); void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out); void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in); +void bdrv_inc_in_flight(BlockDriverState *bs); +void bdrv_dec_in_flight(BlockDriverState *bs); + void blockdev_close_all_bdrv_states(void); #endif /* BLOCK_INT_H */ diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 4ddb4ae2e1..2bb39f4d29 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -92,6 +92,13 @@ typedef struct BlockJobDriver { * besides job->blk to the new AioContext. */ void (*attached_aio_context)(BlockJob *job, AioContext *new_context); + + /* + * If the callback is not NULL, it will be invoked when the job has to be + * synchronously cancelled or completed; it should drain BlockDriverStates + * as required to ensure progress. + */ + void (*drain)(BlockJob *job); } BlockJobDriver; /** diff --git a/include/glib-compat.h b/include/glib-compat.h index 8093163bee..3f8370b3e4 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -304,4 +304,15 @@ static inline void g_slist_free_full(GSList *list, GDestroyNotify free_func) } #endif +#if !GLIB_CHECK_VERSION(2, 26, 0) +static inline void g_source_set_name(GSource *source, const char *name) +{ + /* This is just a debugging aid, so leaving it a no-op */ +} +static inline void g_source_set_name_by_id(guint tag, const char *name) +{ + /* This is just a debugging aid, so leaving it a no-op */ +} +#endif + #endif diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 17fff80c8a..98dc7722c3 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -13,7 +13,6 @@ #include "qemu/bitmap.h" #include "sysemu/sysemu.h" #include "hw/pci/pci.h" -#include "hw/boards.h" #include "hw/compat.h" #include "hw/mem/pc-dimm.h" #include "hw/mem/nvdimm.h" diff --git a/include/hw/nvram/chrp_nvram.h b/include/hw/nvram/chrp_nvram.h new file mode 100644 index 0000000000..b4f5b2b104 --- /dev/null +++ b/include/hw/nvram/chrp_nvram.h @@ -0,0 +1,54 @@ +/* + * Common Hardware Reference Platform NVRAM functions. + * + * This code is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CHRP_NVRAM_H +#define CHRP_NVRAM_H + +/* OpenBIOS NVRAM partition */ +typedef struct { + uint8_t signature; + uint8_t checksum; + uint16_t len; /* Big endian, length divided by 16 */ + char name[12]; +} ChrpNvramPartHdr; + +#define CHRP_NVPART_SYSTEM 0x70 +#define CHRP_NVPART_FREE 0x7f + +static inline void +chrp_nvram_finish_partition(ChrpNvramPartHdr *header, uint32_t size) +{ + unsigned int i, sum; + uint8_t *tmpptr; + + /* Length divided by 16 */ + header->len = cpu_to_be16(size >> 4); + + /* Checksum */ + tmpptr = (uint8_t *)header; + sum = *tmpptr; + for (i = 0; i < 14; i++) { + sum += tmpptr[2 + i]; + sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; + } + header->checksum = sum & 0xff; +} + +int chrp_nvram_create_system_partition(uint8_t *data, int min_len); +int chrp_nvram_create_free_partition(uint8_t *data, int len); + +#endif diff --git a/include/hw/nvram/openbios_firmware_abi.h b/include/hw/nvram/sun_nvram.h index 74cfd56180..68eaa60308 100644 --- a/include/hw/nvram/openbios_firmware_abi.h +++ b/include/hw/nvram/sun_nvram.h @@ -1,46 +1,5 @@ -#ifndef OPENBIOS_FIRMWARE_ABI_H -#define OPENBIOS_FIRMWARE_ABI_H - -/* OpenBIOS NVRAM partition */ -struct OpenBIOS_nvpart_v1 { - uint8_t signature; - uint8_t checksum; - uint16_t len; // BE, length divided by 16 - char name[12]; -}; - -#define OPENBIOS_PART_SYSTEM 0x70 -#define OPENBIOS_PART_FREE 0x7f - -static inline void -OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size) -{ - unsigned int i, sum; - uint8_t *tmpptr; - - // Length divided by 16 - header->len = cpu_to_be16(size >> 4); - - // Checksum - tmpptr = (uint8_t *)header; - sum = *tmpptr; - for (i = 0; i < 14; i++) { - sum += tmpptr[2 + i]; - sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; - } - header->checksum = sum & 0xff; -} - -static inline uint32_t -OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const char *str) -{ - uint32_t len; - - len = strlen(str) + 1; - memcpy(&nvram[addr], str, len); - - return addr + len; -} +#ifndef SUN_NVRAM_H +#define SUN_NVRAM_H /* Sun IDPROM structure at the end of NVRAM */ /* from http://www.squirrel.com/squirrel/sun-nvram-hostid.faq.html */ @@ -72,4 +31,4 @@ Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id header->checksum = tmp; } -#endif /* OPENBIOS_FIRMWARE_ABI_H */ +#endif /* SUN_NVRAM_H */ diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h new file mode 100644 index 0000000000..02ac1c5f42 --- /dev/null +++ b/include/hw/ppc/pnv.h @@ -0,0 +1,129 @@ +/* + * QEMU PowerPC PowerNV various definitions + * + * Copyright (c) 2014-2016 BenH, IBM Corporation. + * + * 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 _PPC_PNV_H +#define _PPC_PNV_H + +#include "hw/boards.h" +#include "hw/sysbus.h" +#include "hw/ppc/pnv_xscom.h" +#include "hw/ppc/pnv_lpc.h" + +#define TYPE_PNV_CHIP "powernv-chip" +#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP) +#define PNV_CHIP_CLASS(klass) \ + OBJECT_CLASS_CHECK(PnvChipClass, (klass), TYPE_PNV_CHIP) +#define PNV_CHIP_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PnvChipClass, (obj), TYPE_PNV_CHIP) + +typedef enum PnvChipType { + PNV_CHIP_POWER8E, /* AKA Murano (default) */ + PNV_CHIP_POWER8, /* AKA Venice */ + PNV_CHIP_POWER8NVL, /* AKA Naples */ + PNV_CHIP_POWER9, /* AKA Nimbus */ +} PnvChipType; + +typedef struct PnvChip { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + uint32_t chip_id; + uint64_t ram_start; + uint64_t ram_size; + + uint32_t nr_cores; + uint64_t cores_mask; + void *cores; + + hwaddr xscom_base; + MemoryRegion xscom_mmio; + MemoryRegion xscom; + AddressSpace xscom_as; + + PnvLpcController lpc; +} PnvChip; + +typedef struct PnvChipClass { + /*< private >*/ + SysBusDeviceClass parent_class; + + /*< public >*/ + const char *cpu_model; + PnvChipType chip_type; + uint64_t chip_cfam_id; + uint64_t cores_mask; + + hwaddr xscom_base; + + uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id); +} PnvChipClass; + +#define TYPE_PNV_CHIP_POWER8E TYPE_PNV_CHIP "-POWER8E" +#define PNV_CHIP_POWER8E(obj) \ + OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP_POWER8E) + +#define TYPE_PNV_CHIP_POWER8 TYPE_PNV_CHIP "-POWER8" +#define PNV_CHIP_POWER8(obj) \ + OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP_POWER8) + +#define TYPE_PNV_CHIP_POWER8NVL TYPE_PNV_CHIP "-POWER8NVL" +#define PNV_CHIP_POWER8NVL(obj) \ + OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP_POWER8NVL) + +#define TYPE_PNV_CHIP_POWER9 TYPE_PNV_CHIP "-POWER9" +#define PNV_CHIP_POWER9(obj) \ + OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP_POWER9) + +/* + * This generates a HW chip id depending on an index: + * + * 0x0, 0x1, 0x10, 0x11 + * + * 4 chips should be the maximum + */ +#define PNV_CHIP_HWID(i) ((((i) & 0x3e) << 3) | ((i) & 0x1)) + +#define TYPE_POWERNV_MACHINE MACHINE_TYPE_NAME("powernv") +#define POWERNV_MACHINE(obj) \ + OBJECT_CHECK(PnvMachineState, (obj), TYPE_POWERNV_MACHINE) + +typedef struct PnvMachineState { + /*< private >*/ + MachineState parent_obj; + + uint32_t initrd_base; + long initrd_size; + + uint32_t num_chips; + PnvChip **chips; + + ISABus *isa_bus; +} PnvMachineState; + +#define PNV_FDT_ADDR 0x01000000 +#define PNV_TIMEBASE_FREQ 512000000ULL + +/* + * POWER8 MMIO base addresses + */ +#define PNV_XSCOM_SIZE 0x800000000ull +#define PNV_XSCOM_BASE(chip) \ + (chip->xscom_base + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE) + +#endif /* _PPC_PNV_H */ diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h new file mode 100644 index 0000000000..2955a41c90 --- /dev/null +++ b/include/hw/ppc/pnv_core.h @@ -0,0 +1,50 @@ +/* + * QEMU PowerPC PowerNV CPU Core model + * + * Copyright (c) 2016, IBM Corporation. + * + * 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 _PPC_PNV_CORE_H +#define _PPC_PNV_CORE_H + +#include "hw/cpu/core.h" + +#define TYPE_PNV_CORE "powernv-cpu-core" +#define PNV_CORE(obj) \ + OBJECT_CHECK(PnvCore, (obj), TYPE_PNV_CORE) +#define PNV_CORE_CLASS(klass) \ + OBJECT_CLASS_CHECK(PnvCoreClass, (klass), TYPE_PNV_CORE) +#define PNV_CORE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PnvCoreClass, (obj), TYPE_PNV_CORE) + +typedef struct PnvCore { + /*< private >*/ + CPUCore parent_obj; + + /*< public >*/ + void *threads; + uint32_t pir; + + MemoryRegion xscom_regs; +} PnvCore; + +typedef struct PnvCoreClass { + DeviceClass parent_class; + ObjectClass *cpu_oc; +} PnvCoreClass; + +extern char *pnv_core_typename(const char *model); + +#endif /* _PPC_PNV_CORE_H */ diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h new file mode 100644 index 0000000000..38e5506975 --- /dev/null +++ b/include/hw/ppc/pnv_lpc.h @@ -0,0 +1,67 @@ +/* + * QEMU PowerPC PowerNV LPC controller + * + * Copyright (c) 2016, IBM Corporation. + * + * 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 _PPC_PNV_LPC_H +#define _PPC_PNV_LPC_H + +#define TYPE_PNV_LPC "pnv-lpc" +#define PNV_LPC(obj) \ + OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV_LPC) + +typedef struct PnvLpcController { + DeviceState parent; + + uint64_t eccb_stat_reg; + uint32_t eccb_data_reg; + + /* OPB bus */ + MemoryRegion opb_mr; + AddressSpace opb_as; + + /* ISA IO and Memory space */ + MemoryRegion isa_io; + MemoryRegion isa_mem; + + /* Windows from OPB to ISA (aliases) */ + MemoryRegion opb_isa_io; + MemoryRegion opb_isa_mem; + MemoryRegion opb_isa_fw; + + /* Registers */ + MemoryRegion lpc_hc_regs; + MemoryRegion opb_master_regs; + + /* OPB Master LS registers */ + uint32_t opb_irq_stat; + uint32_t opb_irq_mask; + uint32_t opb_irq_pol; + uint32_t opb_irq_input; + + /* LPC HC registers */ + uint32_t lpc_hc_fw_seg_idsel; + uint32_t lpc_hc_fw_rd_acc_size; + uint32_t lpc_hc_irqser_ctrl; + uint32_t lpc_hc_irqmask; + uint32_t lpc_hc_irqstat; + uint32_t lpc_hc_error_addr; + + /* XSCOM registers */ + MemoryRegion xscom_regs; +} PnvLpcController; + +#endif /* _PPC_PNV_LPC_H */ diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h new file mode 100644 index 0000000000..c0a2fbb9f6 --- /dev/null +++ b/include/hw/ppc/pnv_xscom.h @@ -0,0 +1,78 @@ +/* + * QEMU PowerPC PowerNV XSCOM bus definitions + * + * Copyright (c) 2016, IBM Corporation. + * + * 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 _PPC_PNV_XSCOM_H +#define _PPC_PNV_XSCOM_H + +#include "qom/object.h" + +typedef struct PnvChip PnvChip; + +typedef struct PnvXScomInterface { + Object parent; +} PnvXScomInterface; + +#define TYPE_PNV_XSCOM_INTERFACE "pnv-xscom-interface" +#define PNV_XSCOM_INTERFACE(obj) \ + OBJECT_CHECK(PnvXScomInterface, (obj), TYPE_PNV_XSCOM_INTERFACE) +#define PNV_XSCOM_INTERFACE_CLASS(klass) \ + OBJECT_CLASS_CHECK(PnvXScomInterfaceClass, (klass), \ + TYPE_PNV_XSCOM_INTERFACE) +#define PNV_XSCOM_INTERFACE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PnvXScomInterfaceClass, (obj), TYPE_PNV_XSCOM_INTERFACE) + +typedef struct PnvXScomInterfaceClass { + InterfaceClass parent; + int (*populate)(PnvXScomInterface *dev, void *fdt, int offset); +} PnvXScomInterfaceClass; + +/* + * Layout of the XSCOM PCB addresses of EX core 1 + * + * GPIO 0x1100xxxx + * SCOM 0x1101xxxx + * OHA 0x1102xxxx + * CLOCK CTL 0x1103xxxx + * FIR 0x1104xxxx + * THERM 0x1105xxxx + * <reserved> 0x1106xxxx + * .. + * 0x110Exxxx + * PCB SLAVE 0x110Fxxxx + */ + +#define PNV_XSCOM_EX_BASE 0x10000000 +#define PNV_XSCOM_EX_CORE_BASE(i) (PNV_XSCOM_EX_BASE | (((uint64_t)i) << 24)) +#define PNV_XSCOM_EX_CORE_SIZE 0x100000 + +#define PNV_XSCOM_LPC_BASE 0xb0020 +#define PNV_XSCOM_LPC_SIZE 0x4 + +extern void pnv_xscom_realize(PnvChip *chip, Error **errp); +extern int pnv_xscom_populate(PnvChip *chip, void *fdt, int offset); + +extern void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset, + MemoryRegion *mr); +extern void pnv_xscom_region_init(MemoryRegion *mr, + struct Object *owner, + const MemoryRegionOps *ops, + void *opaque, + const char *name, + uint64_t size); + +#endif /* _PPC_PNV_XSCOM_H */ diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index aeaba3edf9..bd5bcf70de 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -6,12 +6,14 @@ #include "hw/ppc/xics.h" #include "hw/ppc/spapr_drc.h" #include "hw/mem/pc-dimm.h" +#include "hw/ppc/spapr_ovec.h" struct VIOsPAPRBus; struct sPAPRPHBState; struct sPAPRNVRAM; typedef struct sPAPRConfigureConnectorState sPAPRConfigureConnectorState; typedef struct sPAPREventLogEntry sPAPREventLogEntry; +typedef struct sPAPREventSource sPAPREventSource; #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL #define SPAPR_ENTRY_POINT 0x100 @@ -63,17 +65,23 @@ struct sPAPRMachineState { uint32_t htab_shift; hwaddr rma_size; int vrma_adjust; - hwaddr fdt_addr, rtas_addr; ssize_t rtas_size; void *rtas_blob; - void *fdt_skel; + long kernel_size; + bool kernel_le; + uint32_t initrd_base; + long initrd_size; uint64_t rtc_offset; /* Now used only during incoming migration */ struct PPCTimebase tb; bool has_graphics; + sPAPROptionVector *ov5; /* QEMU-supported option vectors */ + sPAPROptionVector *ov5_cas; /* negotiated (via CAS) option vectors */ + bool cas_reboot; - uint32_t check_exception_irq; Notifier epow_notifier; QTAILQ_HEAD(, sPAPREventLogEntry) pending_events; + bool use_hotplug_event_source; + sPAPREventSource *event_sources; /* Migration state */ int htab_save_index; @@ -527,8 +535,8 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn); target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *sm, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets); -int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr, - hwaddr rtas_size); +void spapr_dt_rtas_tokens(void *fdt, int rtas); +void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr); #define SPAPR_TCE_PAGE_SHIFT 12 #define SPAPR_TCE_PAGE_SIZE (1ULL << SPAPR_TCE_PAGE_SHIFT) @@ -578,10 +586,11 @@ struct sPAPREventLogEntry { }; void spapr_events_init(sPAPRMachineState *sm); -void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq); +void spapr_dt_events(sPAPRMachineState *sm, void *fdt); int spapr_h_cas_compose_response(sPAPRMachineState *sm, target_ulong addr, target_ulong size, - bool cpu_update, bool memory_update); + bool cpu_update, + sPAPROptionVector *ov5_updates); sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn); void spapr_tce_table_enable(sPAPRTCETable *tcet, uint32_t page_shift, uint64_t bus_offset, @@ -601,6 +610,10 @@ void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type, uint32_t count); void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type, uint32_t count); +void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type, + uint32_t count, uint32_t index); +void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type, + uint32_t count, uint32_t index); void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp); void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, sPAPRMachineState *spapr); diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h new file mode 100644 index 0000000000..6a06da32e6 --- /dev/null +++ b/include/hw/ppc/spapr_ovec.h @@ -0,0 +1,67 @@ +/* + * QEMU SPAPR Option/Architecture Vector Definitions + * + * Each architecture option is organized/documented by the following + * in LoPAPR 1.1, Table 244: + * + * <vector number>: the bit-vector in which the option is located + * <vector byte>: the byte offset of the vector entry + * <vector bit>: the bit offset within the vector entry + * + * where each vector entry can be one or more bytes. + * + * Firmware expects a somewhat literal encoding of this bit-vector + * structure, where each entry is stored in little-endian so that the + * byte ordering reflects that of the documentation, but where each bit + * offset is from "left-to-right" in the traditional representation of + * a byte value where the MSB is the left-most bit. Thus, each + * individual byte encodes the option bits in reverse order of the + * documented bit. + * + * These definitions/helpers attempt to abstract away this internal + * representation so that we can define/set/test for individual option + * bits using only the documented values. This is done mainly by relying + * on a bitmap to approximate the documented "bit-vector" structure and + * handling conversations to-from the internal representation under the + * covers. + * + * Copyright IBM Corp. 2016 + * + * Authors: + * Michael Roth <mdroth@linux.vnet.ibm.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 _SPAPR_OVEC_H +#define _SPAPR_OVEC_H + +#include "cpu.h" + +typedef struct sPAPROptionVector sPAPROptionVector; + +#define OV_BIT(byte, bit) ((byte - 1) * BITS_PER_BYTE + bit) + +/* option vector 5 */ +#define OV5_DRCONF_MEMORY OV_BIT(2, 2) +#define OV5_FORM1_AFFINITY OV_BIT(5, 0) +#define OV5_HP_EVT OV_BIT(6, 5) + +/* interfaces */ +sPAPROptionVector *spapr_ovec_new(void); +sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig); +void spapr_ovec_intersect(sPAPROptionVector *ov, + sPAPROptionVector *ov1, + sPAPROptionVector *ov2); +bool spapr_ovec_diff(sPAPROptionVector *ov, + sPAPROptionVector *ov_old, + sPAPROptionVector *ov_new); +void spapr_ovec_cleanup(sPAPROptionVector *ov); +void spapr_ovec_set(sPAPROptionVector *ov, long bitnr); +void spapr_ovec_clear(sPAPROptionVector *ov, long bitnr); +bool spapr_ovec_test(sPAPROptionVector *ov, long bitnr); +sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector); +int spapr_ovec_populate_dt(void *fdt, int fdt_offset, + sPAPROptionVector *ov, const char *name); + +#endif /* !defined (_SPAPR_OVEC_H) */ diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 40d0e5f6a3..14f502240e 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -76,14 +76,12 @@ struct VIOsPAPRDevice { struct VIOsPAPRBus { BusState bus; uint32_t next_reg; - int (*init)(VIOsPAPRDevice *dev); - int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off); }; extern VIOsPAPRBus *spapr_vio_bus_init(void); extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg); -extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt); -extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus); +void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt); +extern gchar *spapr_vio_stdout_path(VIOsPAPRBus *bus); static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev) { diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 66ae55ded3..3f0c31610a 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -117,6 +117,8 @@ struct ICPState { uint8_t mfrr; qemu_irq output; bool cap_irq_xics_enabled; + + XICSState *xics; }; #define TYPE_ICS_BASE "ics-base" @@ -185,18 +187,21 @@ int xics_spapr_alloc(XICSState *icp, int irq_hint, bool lsi, Error **errp); int xics_spapr_alloc_block(XICSState *icp, int num, bool lsi, bool align, Error **errp); void xics_spapr_free(XICSState *icp, int irq, int num); +void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle); void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu); void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu); +void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, + const char *typename, Error **errp); /* Internal XICS interfaces */ int xics_get_cpu_index_by_dt_id(int cpu_dt_id); -void icp_set_cppr(XICSState *icp, int server, uint8_t cppr); -void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr); +void icp_set_cppr(ICPState *icp, uint8_t cppr); +void icp_set_mfrr(ICPState *icp, uint8_t mfrr); uint32_t icp_accept(ICPState *ss); uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr); -void icp_eoi(XICSState *icp, int server, uint32_t xirr); +void icp_eoi(ICPState *icp, uint32_t xirr); void ics_simple_write_xive(ICSState *ics, int nr, int server, uint8_t priority, uint8_t saved_priority); diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h index 0df282ab5f..cbda40ee53 100644 --- a/include/hw/xen/xen_backend.h +++ b/include/hw/xen/xen_backend.h @@ -2,60 +2,10 @@ #define QEMU_HW_XEN_BACKEND_H #include "hw/xen/xen_common.h" +#include "hw/xen/xen_pvdev.h" #include "sysemu/sysemu.h" #include "net/net.h" -/* ------------------------------------------------------------- */ - -#define XEN_BUFSIZE 1024 - -struct XenDevice; - -/* driver uses grant tables -> open gntdev device (xendev->gnttabdev) */ -#define DEVOPS_FLAG_NEED_GNTDEV 1 -/* don't expect frontend doing correct state transitions (aka console quirk) */ -#define DEVOPS_FLAG_IGNORE_STATE 2 - -struct XenDevOps { - size_t size; - uint32_t flags; - void (*alloc)(struct XenDevice *xendev); - int (*init)(struct XenDevice *xendev); - int (*initialise)(struct XenDevice *xendev); - void (*connected)(struct XenDevice *xendev); - void (*event)(struct XenDevice *xendev); - void (*disconnect)(struct XenDevice *xendev); - int (*free)(struct XenDevice *xendev); - void (*backend_changed)(struct XenDevice *xendev, const char *node); - void (*frontend_changed)(struct XenDevice *xendev, const char *node); - int (*backend_register)(void); -}; - -struct XenDevice { - const char *type; - int dom; - int dev; - char name[64]; - int debug; - - enum xenbus_state be_state; - enum xenbus_state fe_state; - int online; - char be[XEN_BUFSIZE]; - char *fe; - char *protocol; - int remote_port; - int local_port; - - xenevtchn_handle *evtchndev; - xengnttab_handle *gnttabdev; - - struct XenDevOps *ops; - QTAILQ_ENTRY(XenDevice) next; -}; - -/* ------------------------------------------------------------- */ - /* variables */ extern xc_interface *xen_xc; extern xenforeignmemory_handle *xen_fmem; @@ -63,26 +13,20 @@ extern struct xs_handle *xenstore; extern const char *xen_protocol; extern DeviceState *xen_sysdev; -/* xenstore helper functions */ int xenstore_mkdir(char *path, int p); -int xenstore_write_str(const char *base, const char *node, const char *val); -int xenstore_write_int(const char *base, const char *node, int ival); -int xenstore_write_int64(const char *base, const char *node, int64_t ival); -char *xenstore_read_str(const char *base, const char *node); -int xenstore_read_int(const char *base, const char *node, int *ival); - int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val); int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival); int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival); char *xenstore_read_be_str(struct XenDevice *xendev, const char *node); int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival); +void xenstore_update_fe(char *watch, struct XenDevice *xendev); +void xenstore_update_be(char *watch, char *type, int dom, + struct XenDevOps *ops); char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node); int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival); -int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval); -int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, uint64_t *uval); +int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, + uint64_t *uval); -const char *xenbus_strstate(enum xenbus_state state); -struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev); void xen_be_check_state(struct XenDevice *xendev); /* xen backend driver bits */ @@ -91,10 +35,6 @@ void xen_be_register_common(void); int xen_be_register(const char *type, struct XenDevOps *ops); int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state); int xen_be_bind_evtchn(struct XenDevice *xendev); -void xen_be_unbind_evtchn(struct XenDevice *xendev); -int xen_be_send_notify(struct XenDevice *xendev); -void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...) - GCC_FMT_ATTR(3, 4); /* actual backend drivers */ extern struct XenDevOps xen_console_ops; /* xen_console.c */ diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h new file mode 100644 index 0000000000..083f0a9cc7 --- /dev/null +++ b/include/hw/xen/xen_pvdev.h @@ -0,0 +1,78 @@ +#ifndef QEMU_HW_XEN_PVDEV_H +#define QEMU_HW_XEN_PVDEV_H + +#include "hw/xen/xen_common.h" +/* ------------------------------------------------------------- */ + +#define XEN_BUFSIZE 1024 + +struct XenDevice; + +/* driver uses grant tables -> open gntdev device (xendev->gnttabdev) */ +#define DEVOPS_FLAG_NEED_GNTDEV 1 +/* don't expect frontend doing correct state transitions (aka console quirk) */ +#define DEVOPS_FLAG_IGNORE_STATE 2 + +struct XenDevOps { + size_t size; + uint32_t flags; + void (*alloc)(struct XenDevice *xendev); + int (*init)(struct XenDevice *xendev); + int (*initialise)(struct XenDevice *xendev); + void (*connected)(struct XenDevice *xendev); + void (*event)(struct XenDevice *xendev); + void (*disconnect)(struct XenDevice *xendev); + int (*free)(struct XenDevice *xendev); + void (*backend_changed)(struct XenDevice *xendev, const char *node); + void (*frontend_changed)(struct XenDevice *xendev, const char *node); + int (*backend_register)(void); +}; + +struct XenDevice { + const char *type; + int dom; + int dev; + char name[64]; + int debug; + + enum xenbus_state be_state; + enum xenbus_state fe_state; + int online; + char be[XEN_BUFSIZE]; + char *fe; + char *protocol; + int remote_port; + int local_port; + + xenevtchn_handle *evtchndev; + xengnttab_handle *gnttabdev; + + struct XenDevOps *ops; + QTAILQ_ENTRY(XenDevice) next; +}; + +/* ------------------------------------------------------------- */ + +/* xenstore helper functions */ +int xenstore_write_str(const char *base, const char *node, const char *val); +int xenstore_write_int(const char *base, const char *node, int ival); +int xenstore_write_int64(const char *base, const char *node, int64_t ival); +char *xenstore_read_str(const char *base, const char *node); +int xenstore_read_int(const char *base, const char *node, int *ival); +int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval); +void xenstore_update(void *unused); + +const char *xenbus_strstate(enum xenbus_state state); + +void xen_pv_evtchn_event(void *opaque); +void xen_pv_insert_xendev(struct XenDevice *xendev); +void xen_pv_del_xendev(struct XenDevice *xendev); +struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev); + +void xen_pv_unbind_evtchn(struct XenDevice *xendev); +int xen_pv_send_notify(struct XenDevice *xendev); + +void xen_pv_printf(struct XenDevice *xendev, int msg_level, + const char *fmt, ...) GCC_FMT_ATTR(3, 4); + +#endif /* QEMU_HW_XEN_PVDEV_H */ diff --git a/include/io/channel.h b/include/io/channel.h index 752e89f4dc..32a9470794 100644 --- a/include/io/channel.h +++ b/include/io/channel.h @@ -40,9 +40,9 @@ typedef struct QIOChannelClass QIOChannelClass; typedef enum QIOChannelFeature QIOChannelFeature; enum QIOChannelFeature { - QIO_CHANNEL_FEATURE_FD_PASS = (1 << 0), - QIO_CHANNEL_FEATURE_SHUTDOWN = (1 << 1), - QIO_CHANNEL_FEATURE_LISTEN = (1 << 2), + QIO_CHANNEL_FEATURE_FD_PASS, + QIO_CHANNEL_FEATURE_SHUTDOWN, + QIO_CHANNEL_FEATURE_LISTEN, }; @@ -79,6 +79,7 @@ typedef gboolean (*QIOChannelFunc)(QIOChannel *ioc, struct QIOChannel { Object parent; unsigned int features; /* bitmask of QIOChannelFeatures */ + char *name; #ifdef _WIN32 HANDLE event; /* For use with GSource on Win32 */ #endif @@ -149,6 +150,28 @@ bool qio_channel_has_feature(QIOChannel *ioc, QIOChannelFeature feature); /** + * qio_channel_set_feature: + * @ioc: the channel object + * @feature: the feature to set support for + * + * Add channel support for the feature named in @feature. + */ +void qio_channel_set_feature(QIOChannel *ioc, + QIOChannelFeature feature); + +/** + * qio_channel_set_name: + * @ioc: the channel object + * @name: the name of the channel + * + * Sets the name of the channel, which serves as an aid + * to debugging. The name is used when creating GSource + * watches for this channel. + */ +void qio_channel_set_name(QIOChannel *ioc, + const char *name); + +/** * qio_channel_readv_full: * @ioc: the channel object * @iov: the array of memory regions to read data into diff --git a/include/migration/colo.h b/include/migration/colo.h new file mode 100644 index 0000000000..e32eef4763 --- /dev/null +++ b/include/migration/colo.h @@ -0,0 +1,38 @@ +/* + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) + * (a.k.a. Fault Tolerance or Continuous Replication) + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * Copyright (c) 2016 FUJITSU LIMITED + * Copyright (c) 2016 Intel Corporation + * + * 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 QEMU_COLO_H +#define QEMU_COLO_H + +#include "qemu-common.h" +#include "migration/migration.h" +#include "qemu/coroutine_int.h" +#include "qemu/thread.h" +#include "qemu/main-loop.h" + +bool colo_supported(void); +void colo_info_init(void); + +void migrate_start_colo_process(MigrationState *s); +bool migration_in_colo_state(void); + +/* loadvm */ +bool migration_incoming_enable_colo(void); +void migration_incoming_exit_colo(void); +void *colo_process_incoming_thread(void *opaque); +bool migration_incoming_in_colo_state(void); + +COLOMode get_colo_mode(void); + +/* failover */ +void colo_do_failover(MigrationState *s); +#endif diff --git a/include/migration/failover.h b/include/migration/failover.h new file mode 100644 index 0000000000..ad91ef2381 --- /dev/null +++ b/include/migration/failover.h @@ -0,0 +1,26 @@ +/* + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) + * (a.k.a. Fault Tolerance or Continuous Replication) + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO.,LTD. + * Copyright (c) 2016 FUJITSU LIMITED + * Copyright (c) 2016 Intel Corporation + * + * 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 QEMU_FAILOVER_H +#define QEMU_FAILOVER_H + +#include "qemu-common.h" +#include "qapi-types.h" + +void failover_init_state(void); +FailoverStatus failover_set_state(FailoverStatus old_state, + FailoverStatus new_state); +FailoverStatus failover_get_state(void); +void failover_request_active(Error **errp); +bool failover_request_is_active(void); + +#endif diff --git a/include/migration/migration.h b/include/migration/migration.h index 2791b90c00..c309d23370 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -21,6 +21,7 @@ #include "migration/vmstate.h" #include "qapi-types.h" #include "exec/cpu-common.h" +#include "qemu/coroutine_int.h" #define QEMU_VM_FILE_MAGIC 0x5145564d #define QEMU_VM_FILE_VERSION_COMPAT 0x00000002 @@ -107,6 +108,12 @@ struct MigrationIncomingState { QEMUBH *bh; int state; + + bool have_colo_incoming_thread; + QemuThread colo_incoming_thread; + /* The coroutine we should enter (back) after failover */ + Coroutine *migration_incoming_co; + /* See savevm.c */ LoadStateEntry_Head loadvm_handlers; }; @@ -298,6 +305,7 @@ int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen); int migrate_use_xbzrle(void); int64_t migrate_xbzrle_cache_size(void); +bool migrate_colo_enabled(void); int64_t xbzrle_cache_resize(int64_t new_size); diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index a714d8ef80..8cc532ec0e 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -9,7 +9,7 @@ extern Monitor *cur_mon; /* flags for monitor_init */ -#define MONITOR_IS_DEFAULT 0x01 +/* 0x01 unused */ #define MONITOR_USE_READLINE 0x02 #define MONITOR_USE_CONTROL 0x04 #define MONITOR_USE_PRETTY 0x08 diff --git a/include/qemu/rfifolock.h b/include/qemu/rfifolock.h deleted file mode 100644 index b23ab538a6..0000000000 --- a/include/qemu/rfifolock.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Recursive FIFO lock - * - * Copyright Red Hat, Inc. 2013 - * - * Authors: - * Stefan Hajnoczi <stefanha@redhat.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 QEMU_RFIFOLOCK_H -#define QEMU_RFIFOLOCK_H - -#include "qemu/thread.h" - -/* Recursive FIFO lock - * - * This lock provides more features than a plain mutex: - * - * 1. Fairness - enforces FIFO order. - * 2. Nesting - can be taken recursively. - * 3. Contention callback - optional, called when thread must wait. - * - * The recursive FIFO lock is heavyweight so prefer other synchronization - * primitives if you do not need its features. - */ -typedef struct { - QemuMutex lock; /* protects all fields */ - - /* FIFO order */ - unsigned int head; /* active ticket number */ - unsigned int tail; /* waiting ticket number */ - QemuCond cond; /* used to wait for our ticket number */ - - /* Nesting */ - QemuThread owner_thread; /* thread that currently has ownership */ - unsigned int nesting; /* amount of nesting levels */ - - /* Contention callback */ - void (*cb)(void *); /* called when thread must wait, with ->lock - * held so it may not recursively lock/unlock - */ - void *cb_opaque; -} RFifoLock; - -void rfifolock_init(RFifoLock *r, void (*cb)(void *), void *opaque); -void rfifolock_destroy(RFifoLock *r); -void rfifolock_lock(RFifoLock *r); -void rfifolock_unlock(RFifoLock *r); - -#endif /* QEMU_RFIFOLOCK_H */ diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h index aa03567e5e..09d1e15728 100644 --- a/include/qemu/thread-posix.h +++ b/include/qemu/thread-posix.h @@ -4,6 +4,12 @@ #include <pthread.h> #include <semaphore.h> +typedef QemuMutex QemuRecMutex; +#define qemu_rec_mutex_destroy qemu_mutex_destroy +#define qemu_rec_mutex_lock qemu_mutex_lock +#define qemu_rec_mutex_try_lock qemu_mutex_try_lock +#define qemu_rec_mutex_unlock qemu_mutex_unlock + struct QemuMutex { pthread_mutex_t lock; }; diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h index c7ce8dcd45..5fb6541ae9 100644 --- a/include/qemu/thread-win32.h +++ b/include/qemu/thread-win32.h @@ -8,6 +8,16 @@ struct QemuMutex { LONG owner; }; +typedef struct QemuRecMutex QemuRecMutex; +struct QemuRecMutex { + CRITICAL_SECTION lock; +}; + +void qemu_rec_mutex_destroy(QemuRecMutex *mutex); +void qemu_rec_mutex_lock(QemuRecMutex *mutex); +int qemu_rec_mutex_trylock(QemuRecMutex *mutex); +void qemu_rec_mutex_unlock(QemuRecMutex *mutex); + struct QemuCond { LONG waiters, target; HANDLE sema; diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 31237e93ee..e8e665f020 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -25,6 +25,9 @@ void qemu_mutex_lock(QemuMutex *mutex); int qemu_mutex_trylock(QemuMutex *mutex); void qemu_mutex_unlock(QemuMutex *mutex); +/* Prototypes for other functions are in thread-posix.h/thread-win32.h. */ +void qemu_rec_mutex_init(QemuRecMutex *mutex); + void qemu_cond_init(QemuCond *cond); void qemu_cond_destroy(QemuCond *cond); diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index b07159b639..6444e41d39 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -146,6 +146,7 @@ BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int count, BlockCompletionFunc *cb, void *opaque); void blk_aio_cancel(BlockAIOCB *acb); void blk_aio_cancel_async(BlockAIOCB *acb); +int blk_co_ioctl(BlockBackend *blk, unsigned long int req, void *buf); int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf); BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, BlockCompletionFunc *cb, void *opaque); diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h index 34c8eaf64e..c228c66513 100644 --- a/include/sysemu/dma.h +++ b/include/sysemu/dma.h @@ -199,14 +199,14 @@ typedef BlockAIOCB *DMAIOFunc(int64_t offset, QEMUIOVector *iov, void *opaque); BlockAIOCB *dma_blk_io(AioContext *ctx, - QEMUSGList *sg, uint64_t offset, + QEMUSGList *sg, uint64_t offset, uint32_t align, DMAIOFunc *io_func, void *io_func_opaque, BlockCompletionFunc *cb, void *opaque, DMADirection dir); BlockAIOCB *dma_blk_read(BlockBackend *blk, - QEMUSGList *sg, uint64_t offset, + QEMUSGList *sg, uint64_t offset, uint32_t align, BlockCompletionFunc *cb, void *opaque); BlockAIOCB *dma_blk_write(BlockBackend *blk, - QEMUSGList *sg, uint64_t offset, + QEMUSGList *sg, uint64_t offset, uint32_t align, BlockCompletionFunc *cb, void *opaque); uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg); uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg); |