aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig.host3
-rw-r--r--MAINTAINERS5
-rw-r--r--Makefile7
-rw-r--r--VERSION2
-rw-r--r--block/blkdebug.c2
-rw-r--r--block/copy-on-read.c7
-rw-r--r--block/file-posix.c24
-rw-r--r--block/io.c16
-rw-r--r--block/mirror.c3
-rw-r--r--block/raw-format.c2
-rw-r--r--default-configs/mips-softmmu-common.mak1
-rw-r--r--default-configs/mips64el-softmmu.mak2
-rw-r--r--exec.c5
-rw-r--r--gdbstub.c14
-rw-r--r--hmp.c26
-rw-r--r--hw/Kconfig1
-rw-r--r--hw/alpha/Kconfig1
-rw-r--r--hw/block/block.c48
-rw-r--r--hw/block/pflash_cfi01.c15
-rw-r--r--hw/block/pflash_cfi02.c13
-rw-r--r--hw/block/xen-block.c4
-rw-r--r--hw/char/Makefile.objs2
-rw-r--r--hw/char/parallel-isa.c3
-rw-r--r--hw/display/Kconfig2
-rw-r--r--hw/display/ati.c18
-rw-r--r--hw/hppa/Kconfig2
-rw-r--r--hw/i386/Kconfig8
-rw-r--r--hw/i386/intel_iommu.c91
-rw-r--r--hw/intc/Kconfig3
-rw-r--r--hw/isa/Kconfig2
-rw-r--r--hw/misc/Kconfig4
-rw-r--r--hw/net/Kconfig4
-rw-r--r--hw/net/e1000.c24
-rw-r--r--hw/pci-bridge/Kconfig6
-rw-r--r--hw/pci-host/Kconfig1
-rw-r--r--hw/pci/Kconfig6
-rw-r--r--hw/ppc/Kconfig5
-rw-r--r--hw/ppc/ppc.c2
-rw-r--r--hw/ppc/spapr.c65
-rw-r--r--hw/ppc/spapr_irq.c50
-rw-r--r--hw/rdma/Kconfig3
-rw-r--r--hw/rdma/Makefile.objs6
-rw-r--r--hw/riscv/Kconfig1
-rw-r--r--hw/riscv/sifive_plic.c3
-rw-r--r--hw/s390x/Kconfig1
-rw-r--r--hw/sh4/Kconfig1
-rw-r--r--hw/sparc64/Kconfig2
-rw-r--r--hw/usb/hcd-ohci.c7
-rw-r--r--include/block/block.h7
-rw-r--r--include/block/raw-aio.h1
-rw-r--r--include/hw/block/block.h7
-rw-r--r--include/hw/i386/intel_iommu.h7
-rw-r--r--include/hw/ppc/spapr.h1
-rw-r--r--memory.c9
-rw-r--r--migration/colo.c57
-rw-r--r--migration/migration.c70
-rw-r--r--migration/migration.h1
-rw-r--r--migration/ram.c82
-rw-r--r--migration/rdma.c6
-rw-r--r--migration/tls.c2
-rw-r--r--migration/trace-events4
-rw-r--r--net/socket.c25
-rw-r--r--net/tap.c10
-rw-r--r--qapi/migration.json81
-rw-r--r--qapi/qmp-dispatch.c2
-rw-r--r--qemu-img.c2
-rw-r--r--qemu-io-cmds.c13
-rw-r--r--qemu-seccomp.c52
-rw-r--r--qobject/json-lexer.c2
-rw-r--r--scripts/minikconf.py2
-rw-r--r--target/arm/cpu.c5
-rw-r--r--target/i386/sev.c11
-rw-r--r--target/ppc/cpu.h6
-rw-r--r--target/ppc/helper_regs.h2
-rw-r--r--target/ppc/translate.c66
-rw-r--r--target/ppc/translate/vsx-impl.inc.c2
-rw-r--r--target/riscv/insn_trans/trans_rvc.inc.c2
-rw-r--r--target/riscv/insn_trans/trans_rvm.inc.c4
-rw-r--r--target/riscv/translate.c21
-rw-r--r--target/xtensa/translate.c1
-rw-r--r--target/xtensa/xtensa-semi.c1
-rw-r--r--tests/Makefile.include3
-rwxr-xr-xtests/qemu-iotests/24871
-rw-r--r--tests/qemu-iotests/248.out8
-rw-r--r--tests/qemu-iotests/group1
-rw-r--r--tests/tcg/xtensa/Makefile.softmmu-target2
-rw-r--r--tests/tcg/xtensa/test_fail.S9
-rw-r--r--tests/tcg/xtensa/test_flix.S17
-rw-r--r--tests/tcg/xtensa/test_pipeline.S157
-rw-r--r--tests/test-announce-self.c73
-rw-r--r--tests/virtio-net-test.c30
-rw-r--r--util/error.c4
92 files changed, 849 insertions, 613 deletions
diff --git a/Kconfig.host b/Kconfig.host
index add5b179f7..aec95365ff 100644
--- a/Kconfig.host
+++ b/Kconfig.host
@@ -31,3 +31,6 @@ config XEN
config VIRTFS
bool
+
+config PVRDMA
+ bool
diff --git a/MAINTAINERS b/MAINTAINERS
index 85d7d764e5..56139ac8ab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1813,7 +1813,8 @@ F: qom/cpu.c
F: include/qom/cpu.h
Device Tree
-M: Alexander Graf <agraf@suse.de>
+M: Alistair Francis <alistair.francis@wdc.com>
+R: David Gibson <david@gibson.dropbear.id.au>
S: Maintained
F: device_tree.c
F: include/sysemu/device_tree.h
@@ -2178,7 +2179,7 @@ F: include/migration/failover.h
F: docs/COLO-FT.txt
COLO Proxy
-M: Zhang Chen <zhangckid@gmail.com>
+M: Zhang Chen <chen.zhang@intel.com>
M: Li Zhijian <lizhijian@cn.fujitsu.com>
S: Supported
F: docs/colo-proxy.txt
diff --git a/Makefile b/Makefile
index d8dad39c5d..04a0d45050 100644
--- a/Makefile
+++ b/Makefile
@@ -331,10 +331,10 @@ SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(filter %-softmmu, $(TAR
SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %.d, $(SUBDIR_DEVICES_MAK))
ifeq ($(SUBDIR_DEVICES_MAK),)
-config-all-devices.mak:
+config-all-devices.mak: config-host.mak
$(call quiet-command,echo '# no devices' > $@,"GEN","$@")
else
-config-all-devices.mak: $(SUBDIR_DEVICES_MAK)
+config-all-devices.mak: $(SUBDIR_DEVICES_MAK) config-host.mak
$(call quiet-command, sed -n \
's|^\([^=]*\)=\(.*\)$$|\1:=$$(findstring y,$$(\1)\2)|p' \
$(SUBDIR_DEVICES_MAK) | sort -u > $@, \
@@ -356,7 +356,8 @@ MINIKCONF_ARGS = \
CONFIG_X11=$(CONFIG_X11) \
CONFIG_VHOST_USER=$(CONFIG_VHOST_USER) \
CONFIG_VIRTFS=$(CONFIG_VIRTFS) \
- CONFIG_LINUX=$(CONFIG_LINUX)
+ CONFIG_LINUX=$(CONFIG_LINUX) \
+ CONFIG_PVRDMA=$(CONFIG_PVRDMA)
MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host $(SRC_PATH)/hw/Kconfig
MINIKCONF = $(PYTHON) $(SRC_PATH)/scripts/minikconf.py \
diff --git a/VERSION b/VERSION
index e55b56f5e2..d1aca36ce2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.1.90
+3.1.91
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 1ea835c2b9..efd9441625 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -401,7 +401,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
bs->file->bs->supported_zero_flags);
ret = -EINVAL;
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
index d670fec42b..53972b1da3 100644
--- a/block/copy-on-read.c
+++ b/block/copy-on-read.c
@@ -34,12 +34,11 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
}
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
- (BDRV_REQ_FUA &
- bs->file->bs->supported_write_flags);
+ (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
- bs->file->bs->supported_zero_flags);
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
+ bs->file->bs->supported_zero_flags);
return 0;
}
diff --git a/block/file-posix.c b/block/file-posix.c
index d102f3b222..db4cccbe51 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -652,7 +652,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
}
#endif
- bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
+ bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
ret = 0;
fail:
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
@@ -1500,14 +1500,19 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
}
#ifdef BLKZEROOUT
- do {
- uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
- if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
- return 0;
- }
- } while (errno == EINTR);
+ /* The BLKZEROOUT implementation in the kernel doesn't set
+ * BLKDEV_ZERO_NOFALLBACK, so we can't call this if we have to avoid slow
+ * fallbacks. */
+ if (!(aiocb->aio_type & QEMU_AIO_NO_FALLBACK)) {
+ do {
+ uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
+ if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
+ return 0;
+ }
+ } while (errno == EINTR);
- ret = translate_err(-errno);
+ ret = translate_err(-errno);
+ }
#endif
if (ret == -ENOTSUP) {
@@ -2659,6 +2664,9 @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
if (blkdev) {
acb.aio_type |= QEMU_AIO_BLKDEV;
}
+ if (flags & BDRV_REQ_NO_FALLBACK) {
+ acb.aio_type |= QEMU_AIO_NO_FALLBACK;
+ }
if (flags & BDRV_REQ_MAY_UNMAP) {
acb.aio_type |= QEMU_AIO_DISCARD;
diff --git a/block/io.c b/block/io.c
index 2ba603c7bc..dfc153b8d8 100644
--- a/block/io.c
+++ b/block/io.c
@@ -909,8 +909,6 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
}
ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
if (ret < 0) {
- error_report("error getting block status at offset %" PRId64 ": %s",
- offset, strerror(-ret));
return ret;
}
if (ret & BDRV_BLOCK_ZERO) {
@@ -919,8 +917,6 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
}
ret = bdrv_pwrite_zeroes(child, offset, bytes, flags);
if (ret < 0) {
- error_report("error writing zeroes at offset %" PRId64 ": %s",
- offset, strerror(-ret));
return ret;
}
offset += bytes;
@@ -1019,6 +1015,7 @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
unsigned int nb_sectors;
assert(!(flags & ~BDRV_REQ_MASK));
+ assert(!(flags & BDRV_REQ_NO_FALLBACK));
if (!drv) {
return -ENOMEDIUM;
@@ -1065,6 +1062,7 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
int ret;
assert(!(flags & ~BDRV_REQ_MASK));
+ assert(!(flags & BDRV_REQ_NO_FALLBACK));
if (!drv) {
return -ENOMEDIUM;
@@ -1471,6 +1469,10 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
return -ENOMEDIUM;
}
+ if ((flags & ~bs->supported_zero_flags) & BDRV_REQ_NO_FALLBACK) {
+ return -ENOTSUP;
+ }
+
assert(alignment % bs->bl.request_alignment == 0);
head = offset % alignment;
tail = (offset + bytes) % alignment;
@@ -1514,7 +1516,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
assert(!bs->supported_zero_flags);
}
- if (ret == -ENOTSUP) {
+ if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
/* Fall back to bounce buffer if write zeroes is unsupported */
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
@@ -2953,6 +2955,10 @@ static int coroutine_fn bdrv_co_copy_range_internal(
BdrvTrackedRequest req;
int ret;
+ /* TODO We can support BDRV_REQ_NO_FALLBACK here */
+ assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
+ assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
+
if (!dst || !dst->bs) {
return -ENOMEDIUM;
}
diff --git a/block/mirror.c b/block/mirror.c
index eb9a4cdf56..ff15cfb197 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1548,7 +1548,8 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
}
mirror_top_bs->total_sectors = bs->total_sectors;
mirror_top_bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
- mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED;
+ mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
+ BDRV_REQ_NO_FALLBACK;
bs_opaque = g_new0(MirrorBDSOpaque, 1);
mirror_top_bs->opaque = bs_opaque;
bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs));
diff --git a/block/raw-format.c b/block/raw-format.c
index cec29986cc..385cdc2490 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -434,7 +434,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
bs->file->bs->supported_zero_flags);
if (bs->probed && !bdrv_is_read_only(bs)) {
diff --git a/default-configs/mips-softmmu-common.mak b/default-configs/mips-softmmu-common.mak
index 0795d522db..8e54a74b7a 100644
--- a/default-configs/mips-softmmu-common.mak
+++ b/default-configs/mips-softmmu-common.mak
@@ -35,6 +35,7 @@ CONFIG_MIPS_CPS=y
CONFIG_MIPS_ITU=y
CONFIG_R4K=y
CONFIG_MALTA=y
+CONFIG_PCNET_PCI=y
CONFIG_MIPSSIM=y
CONFIG_ACPI_SMBUS=y
CONFIG_SMBUS_EEPROM=y
diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak
index 8b255efc54..a67c9517a2 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -6,6 +6,8 @@ CONFIG_RC4030=y
CONFIG_DP8393X=y
CONFIG_DS1225Y=y
CONFIG_FULONG=y
+CONFIG_ATI_VGA=y
+CONFIG_RTL8139_PCI=y
CONFIG_JAZZ=y
CONFIG_G364FB=y
CONFIG_JAZZ_LED=y
diff --git a/exec.c b/exec.c
index 86a38d3b3b..6ab62f4eee 100644
--- a/exec.c
+++ b/exec.c
@@ -1692,9 +1692,10 @@ static int find_max_supported_pagesize(Object *obj, void *opaque)
long *hpsize_min = opaque;
if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
- long hpsize = host_memory_backend_pagesize(MEMORY_BACKEND(obj));
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ long hpsize = host_memory_backend_pagesize(backend);
- if (hpsize < *hpsize_min) {
+ if (host_memory_backend_is_mapped(backend) && (hpsize < *hpsize_min)) {
*hpsize_min = hpsize;
}
}
diff --git a/gdbstub.c b/gdbstub.c
index bc774ae992..d54abd17cc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1152,6 +1152,7 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
uint32_t pid, tid;
GDBProcess *process;
CPUState *cpu;
+ GDBThreadIdKind kind;
#ifdef CONFIG_USER_ONLY
int max_cpus = 1; /* global variable max_cpus exists only in system mode */
@@ -1194,12 +1195,21 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
goto out;
}
- if (*p++ != ':') {
+ if (*p == '\0' || *p == ';') {
+ /*
+ * No thread specifier, action is on "all threads". The
+ * specification is unclear regarding the process to act on. We
+ * choose all processes.
+ */
+ kind = GDB_ALL_PROCESSES;
+ } else if (*p++ == ':') {
+ kind = read_thread_id(p, &p, &pid, &tid);
+ } else {
res = -ENOTSUP;
goto out;
}
- switch (read_thread_id(p, &p, &pid, &tid)) {
+ switch (kind) {
case GDB_READ_THREAD_ERR:
res = -EINVAL;
goto out;
diff --git a/hmp.c b/hmp.c
index fa1e59a2fc..92941142af 100644
--- a/hmp.c
+++ b/hmp.c
@@ -433,17 +433,17 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL),
params->block_incremental ? "on" : "off");
monitor_printf(mon, "%s: %u\n",
- MigrationParameter_str(MIGRATION_PARAMETER_X_MULTIFD_CHANNELS),
- params->x_multifd_channels);
- monitor_printf(mon, "%s: %u\n",
- MigrationParameter_str(MIGRATION_PARAMETER_X_MULTIFD_PAGE_COUNT),
- params->x_multifd_page_count);
+ MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
+ params->multifd_channels);
monitor_printf(mon, "%s: %" PRIu64 "\n",
MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
params->xbzrle_cache_size);
monitor_printf(mon, "%s: %" PRIu64 "\n",
MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
params->max_postcopy_bandwidth);
+ monitor_printf(mon, " %s: '%s'\n",
+ MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
+ params->has_tls_authz ? params->tls_authz : "");
}
qapi_free_MigrationParameters(params);
@@ -1786,6 +1786,12 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
p->tls_hostname->type = QTYPE_QSTRING;
visit_type_str(v, param, &p->tls_hostname->u.s, &err);
break;
+ case MIGRATION_PARAMETER_TLS_AUTHZ:
+ p->has_tls_authz = true;
+ p->tls_authz = g_new0(StrOrNull, 1);
+ p->tls_authz->type = QTYPE_QSTRING;
+ visit_type_str(v, param, &p->tls_authz->u.s, &err);
+ break;
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
p->has_max_bandwidth = true;
/*
@@ -1812,13 +1818,9 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
p->has_block_incremental = true;
visit_type_bool(v, param, &p->block_incremental, &err);
break;
- case MIGRATION_PARAMETER_X_MULTIFD_CHANNELS:
- p->has_x_multifd_channels = true;
- visit_type_int(v, param, &p->x_multifd_channels, &err);
- break;
- case MIGRATION_PARAMETER_X_MULTIFD_PAGE_COUNT:
- p->has_x_multifd_page_count = true;
- visit_type_int(v, param, &p->x_multifd_page_count, &err);
+ case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
+ p->has_multifd_channels = true;
+ visit_type_int(v, param, &p->multifd_channels, &err);
break;
case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
p->has_xbzrle_cache_size = true;
diff --git a/hw/Kconfig b/hw/Kconfig
index d5ecd02070..88b9f15007 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -26,6 +26,7 @@ source pci-bridge/Kconfig
source pci-host/Kconfig
source pcmcia/Kconfig
source pci/Kconfig
+source rdma/Kconfig
source scsi/Kconfig
source sd/Kconfig
source smbios/Kconfig
diff --git a/hw/alpha/Kconfig b/hw/alpha/Kconfig
index 22cefd9577..15c59ff264 100644
--- a/hw/alpha/Kconfig
+++ b/hw/alpha/Kconfig
@@ -2,6 +2,7 @@ config DP264
bool
imply PCI_DEVICES
imply TEST_DEVICES
+ imply E1000_PCI
select I82374
select I8254
select I8259
diff --git a/hw/block/block.c b/hw/block/block.c
index cf0eb826f1..bf56c7612b 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -13,7 +13,53 @@
#include "hw/block/block.h"
#include "qapi/error.h"
#include "qapi/qapi-types-block.h"
-#include "qemu/error-report.h"
+
+/*
+ * Read the entire contents of @blk into @buf.
+ * @blk's contents must be @size bytes, and @size must be at most
+ * BDRV_REQUEST_MAX_BYTES.
+ * On success, return true.
+ * On failure, store an error through @errp and return false.
+ * Note that the error messages do not identify the block backend.
+ * TODO Since callers don't either, this can result in confusing
+ * errors.
+ * This function not intended for actual block devices, which read on
+ * demand. It's for things like memory devices that (ab)use a block
+ * backend to provide persistence.
+ */
+bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
+ Error **errp)
+{
+ int64_t blk_len;
+ int ret;
+
+ blk_len = blk_getlength(blk);
+ if (blk_len < 0) {
+ error_setg_errno(errp, -blk_len,
+ "can't get size of block backend");
+ return false;
+ }
+ if (blk_len != size) {
+ error_setg(errp, "device requires %" HWADDR_PRIu " bytes, "
+ "block backend provides %" PRIu64 " bytes",
+ size, blk_len);
+ return false;
+ }
+
+ /*
+ * We could loop for @size > BDRV_REQUEST_MAX_BYTES, but if we
+ * ever get to the point we want to read *gigabytes* here, we
+ * should probably rework the device to be more like an actual
+ * block device and read only on demand.
+ */
+ assert(size <= BDRV_REQUEST_MAX_BYTES);
+ ret = blk_pread(blk, 0, buf, size);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "can't read block backend");
+ return false;
+ }
+ return true;
+}
void blkconf_blocksizes(BlockConf *conf)
{
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 125f70b8e4..16dfae14b8 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -38,6 +38,7 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
+#include "hw/block/block.h"
#include "hw/block/flash.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
@@ -730,13 +731,6 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
}
device_len = sector_len_per_device * blocks_per_device;
- /* XXX: to be fixed */
-#if 0
- if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
- total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
- return NULL;
-#endif
-
memory_region_init_rom_device(
&pfl->mem, OBJECT(dev),
&pflash_cfi01_ops,
@@ -763,12 +757,9 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
}
if (pfl->blk) {
- /* read the initial flash content */
- ret = blk_pread(pfl->blk, 0, pfl->storage, total_len);
-
- if (ret < 0) {
+ if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, total_len,
+ errp)) {
vmstate_unregister_ram(&pfl->mem, DEVICE(pfl));
- error_setg(errp, "failed to read the initial flash content");
return;
}
}
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index c9db430611..f2c6201f81 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -37,6 +37,7 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
+#include "hw/block/block.h"
#include "hw/block/flash.h"
#include "qapi/error.h"
#include "qemu/timer.h"
@@ -550,12 +551,6 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
}
chip_len = pfl->sector_len * pfl->nb_blocs;
- /* XXX: to be fixed */
-#if 0
- if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
- total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
- return NULL;
-#endif
memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), pfl->be ?
&pflash_cfi02_ops_be : &pflash_cfi02_ops_le,
@@ -581,11 +576,9 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
}
if (pfl->blk) {
- /* read the initial flash content */
- ret = blk_pread(pfl->blk, 0, pfl->storage, chip_len);
- if (ret < 0) {
+ if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, chip_len,
+ errp)) {
vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
- error_setg(errp, "failed to read the initial flash content");
return;
}
}
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 70fc2455e8..9c722b9b95 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -771,7 +771,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
QDict *cache_qdict = qdict_new();
qdict_put_bool(cache_qdict, "direct", true);
- qdict_put_obj(file_layer, "cache", QOBJECT(cache_qdict));
+ qdict_put(file_layer, "cache", cache_qdict);
qdict_put_str(file_layer, "aio", "native");
}
@@ -796,7 +796,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
qdict_put_str(driver_layer, "driver", driver);
g_free(driver);
- qdict_put_obj(driver_layer, "file", QOBJECT(file_layer));
+ qdict_put(driver_layer, "file", file_layer);
g_assert(!drive->node_name);
drive->node_name = xen_block_blockdev_add(drive->id, driver_layer,
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index c4947d7ae7..cf086e7114 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -2,7 +2,7 @@ common-obj-$(CONFIG_IPACK) += ipoctal232.o
common-obj-$(CONFIG_ESCC) += escc.o
common-obj-$(CONFIG_NRF51_SOC) += nrf51_uart.o
common-obj-$(CONFIG_PARALLEL) += parallel.o
-common-obj-$(CONFIG_PARALLEL) += parallel-isa.o
+common-obj-$(CONFIG_ISA_BUS) += parallel-isa.o
common-obj-$(CONFIG_PL011) += pl011.o
common-obj-$(CONFIG_SERIAL) += serial.o
common-obj-$(CONFIG_SERIAL_ISA) += serial-isa.o
diff --git a/hw/char/parallel-isa.c b/hw/char/parallel-isa.c
index 639e179585..a043832e72 100644
--- a/hw/char/parallel-isa.c
+++ b/hw/char/parallel-isa.c
@@ -1,6 +1,9 @@
/*
* QEMU Parallel PORT (ISA bus helpers)
*
+ * These functions reside in a separate file since they also might be
+ * required for linking when compiling QEMU without CONFIG_PARALLEL.
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* SPDX-License-Identifier: MIT
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index 86c1d544c5..72be57a403 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -100,7 +100,7 @@ config VIRTIO_GPU
config VIRTIO_VGA
bool
- default y if PCI_DEVICES
+ # defaults to "N", enabled by specific boards
depends on VIRTIO_PCI
select VGA
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 8322f52aff..db409be3c9 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -235,12 +235,9 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
case MM_DATA ... MM_DATA + 3:
/* indexed access to regs or memory */
if (s->regs.mm_index & BIT(31)) {
- if (s->regs.mm_index <= s->vga.vram_size - size) {
- int i = size - 1;
- while (i >= 0) {
- val <<= 8;
- val |= s->vga.vram_ptr[s->regs.mm_index + i--];
- }
+ uint32_t idx = s->regs.mm_index & ~BIT(31);
+ if (idx <= s->vga.vram_size - size) {
+ val = ldn_le_p(s->vga.vram_ptr + idx, size);
}
} else {
val = ati_mm_read(s, s->regs.mm_index + addr - MM_DATA, size);
@@ -434,12 +431,9 @@ static void ati_mm_write(void *opaque, hwaddr addr,
case MM_DATA ... MM_DATA + 3:
/* indexed access to regs or memory */
if (s->regs.mm_index & BIT(31)) {
- if (s->regs.mm_index <= s->vga.vram_size - size) {
- int i = 0;
- while (i < size) {
- s->vga.vram_ptr[s->regs.mm_index + i] = data & 0xff;
- data >>= 8;
- }
+ uint32_t idx = s->regs.mm_index & ~BIT(31);
+ if (idx <= s->vga.vram_size - size) {
+ stn_le_p(s->vga.vram_ptr + idx, size, data);
}
} else {
ati_mm_write(s, s->regs.mm_index + addr - MM_DATA, data, size);
diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 2d9b072c21..6e5d74a825 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -1,6 +1,8 @@
config DINO
bool
imply PCI_DEVICES
+ imply E1000_PCI
+ imply VIRTIO_VGA
select PCI
select SERIAL
select ISA_BUS
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index 78fd70396a..a6aed7c131 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -9,6 +9,7 @@ config PC
imply ISA_IPMI_KCS
imply ISA_IPMI_BT
imply ISA_DEBUG
+ imply PARALLEL
imply PCI_DEVICES
imply PVPANIC
imply QXL
@@ -17,16 +18,15 @@ config PC
imply TEST_DEVICES
imply TPM_CRB
imply TPM_TIS
+ imply VGA_PCI
+ imply VIRTIO_VGA
select FDC
select I8259
select I8254
select PCKBD
select PCSPK
- select I82374
select I8257
select MC146818RTC
- # Needed by the board code:
- select PARALLEL
# For ACPI builder:
select SERIAL_ISA
select ACPI_VMGENID
@@ -49,6 +49,7 @@ config PC_ACPI
config I440FX
bool
+ imply E1000_PCI
select PC_PCI
select PC_ACPI
select ACPI_SMBUS
@@ -74,6 +75,7 @@ config Q35
bool
imply VTD
imply AMD_IOMMU
+ imply E1000E_PCI_EXPRESS
select PC_PCI
select PC_ACPI
select PCI_EXPRESS_Q35
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index b90de6c664..055a1e865d 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1485,11 +1485,11 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
/* Turn off first then on the other */
if (use_iommu) {
- memory_region_set_enabled(&as->sys_alias, false);
+ memory_region_set_enabled(&as->nodmar, false);
memory_region_set_enabled(MEMORY_REGION(&as->iommu), true);
} else {
memory_region_set_enabled(MEMORY_REGION(&as->iommu), false);
- memory_region_set_enabled(&as->sys_alias, true);
+ memory_region_set_enabled(&as->nodmar, true);
}
if (take_bql) {
@@ -3286,7 +3286,8 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
vtd_dev_as = vtd_bus->dev_as[devfn];
if (!vtd_dev_as) {
- snprintf(name, sizeof(name), "intel_iommu_devfn_%d", devfn);
+ snprintf(name, sizeof(name), "vtd-%02x.%x", PCI_SLOT(devfn),
+ PCI_FUNC(devfn));
vtd_bus->dev_as[devfn] = vtd_dev_as = g_malloc0(sizeof(VTDAddressSpace));
vtd_dev_as->bus = bus;
@@ -3295,44 +3296,53 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
vtd_dev_as->context_cache_entry.context_cache_gen = 0;
vtd_dev_as->iova_tree = iova_tree_new();
+ memory_region_init(&vtd_dev_as->root, OBJECT(s), name, UINT64_MAX);
+ address_space_init(&vtd_dev_as->as, &vtd_dev_as->root, "vtd-root");
+
/*
- * Memory region relationships looks like (Address range shows
- * only lower 32 bits to make it short in length...):
- *
- * |-----------------+-------------------+----------|
- * | Name | Address range | Priority |
- * |-----------------+-------------------+----------+
- * | vtd_root | 00000000-ffffffff | 0 |
- * | intel_iommu | 00000000-ffffffff | 1 |
- * | vtd_sys_alias | 00000000-ffffffff | 1 |
- * | intel_iommu_ir | fee00000-feefffff | 64 |
- * |-----------------+-------------------+----------|
+ * Build the DMAR-disabled container with aliases to the
+ * shared MRs. Note that aliasing to a shared memory region
+ * could help the memory API to detect same FlatViews so we
+ * can have devices to share the same FlatView when DMAR is
+ * disabled (either by not providing "intel_iommu=on" or with
+ * "iommu=pt"). It will greatly reduce the total number of
+ * FlatViews of the system hence VM runs faster.
+ */
+ memory_region_init_alias(&vtd_dev_as->nodmar, OBJECT(s),
+ "vtd-nodmar", &s->mr_nodmar, 0,
+ memory_region_size(&s->mr_nodmar));
+
+ /*
+ * Build the per-device DMAR-enabled container.
*
- * We enable/disable DMAR by switching enablement for
- * vtd_sys_alias and intel_iommu regions. IR region is always
- * enabled.
+ * TODO: currently we have per-device IOMMU memory region only
+ * because we have per-device IOMMU notifiers for devices. If
+ * one day we can abstract the IOMMU notifiers out of the
+ * memory regions then we can also share the same memory
+ * region here just like what we've done above with the nodmar
+ * region.
*/
+ strcat(name, "-dmar");
memory_region_init_iommu(&vtd_dev_as->iommu, sizeof(vtd_dev_as->iommu),
TYPE_INTEL_IOMMU_MEMORY_REGION, OBJECT(s),
- "intel_iommu_dmar",
- UINT64_MAX);
- memory_region_init_alias(&vtd_dev_as->sys_alias, OBJECT(s),
- "vtd_sys_alias", get_system_memory(),
- 0, memory_region_size(get_system_memory()));
- memory_region_init_io(&vtd_dev_as->iommu_ir, OBJECT(s),
- &vtd_mem_ir_ops, s, "intel_iommu_ir",
- VTD_INTERRUPT_ADDR_SIZE);
- memory_region_init(&vtd_dev_as->root, OBJECT(s),
- "vtd_root", UINT64_MAX);
- memory_region_add_subregion_overlap(&vtd_dev_as->root,
+ name, UINT64_MAX);
+ memory_region_init_alias(&vtd_dev_as->iommu_ir, OBJECT(s), "vtd-ir",
+ &s->mr_ir, 0, memory_region_size(&s->mr_ir));
+ memory_region_add_subregion_overlap(MEMORY_REGION(&vtd_dev_as->iommu),
VTD_INTERRUPT_ADDR_FIRST,
- &vtd_dev_as->iommu_ir, 64);
- address_space_init(&vtd_dev_as->as, &vtd_dev_as->root, name);
- memory_region_add_subregion_overlap(&vtd_dev_as->root, 0,
- &vtd_dev_as->sys_alias, 1);
+ &vtd_dev_as->iommu_ir, 1);
+
+ /*
+ * Hook both the containers under the root container, we
+ * switch between DMAR & noDMAR by enable/disable
+ * corresponding sub-containers
+ */
memory_region_add_subregion_overlap(&vtd_dev_as->root, 0,
MEMORY_REGION(&vtd_dev_as->iommu),
- 1);
+ 0);
+ memory_region_add_subregion_overlap(&vtd_dev_as->root, 0,
+ &vtd_dev_as->nodmar, 0);
+
vtd_switch_address_space(vtd_dev_as);
}
return vtd_dev_as;
@@ -3676,6 +3686,21 @@ static void vtd_realize(DeviceState *dev, Error **errp)
memset(s->vtd_as_by_bus_num, 0, sizeof(s->vtd_as_by_bus_num));
memory_region_init_io(&s->csrmem, OBJECT(s), &vtd_mem_ops, s,
"intel_iommu", DMAR_REG_SIZE);
+
+ /* Create the shared memory regions by all devices */
+ memory_region_init(&s->mr_nodmar, OBJECT(s), "vtd-nodmar",
+ UINT64_MAX);
+ memory_region_init_io(&s->mr_ir, OBJECT(s), &vtd_mem_ir_ops,
+ s, "vtd-ir", VTD_INTERRUPT_ADDR_SIZE);
+ memory_region_init_alias(&s->mr_sys_alias, OBJECT(s),
+ "vtd-sys-alias", get_system_memory(), 0,
+ memory_region_size(get_system_memory()));
+ memory_region_add_subregion_overlap(&s->mr_nodmar, 0,
+ &s->mr_sys_alias, 0);
+ memory_region_add_subregion_overlap(&s->mr_nodmar,
+ VTD_INTERRUPT_ADDR_FIRST,
+ &s->mr_ir, 1);
+
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->csrmem);
/* No corresponding destroy */
s->iotlb = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal,
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index de10a6bcbf..5347f8412c 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -12,12 +12,15 @@ config IOAPIC
config ARM_GIC
bool
+ select MSI_NONBROKEN
config OPENPIC
bool
+ select MSI_NONBROKEN
config APIC
bool
+ select MSI_NONBROKEN
config ARM_GIC_KVM
bool
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 57e09a0cb8..6db0d7970c 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -11,6 +11,7 @@ config I82378
select I8254
select I82374
select MC146818RTC
+ select PCSPK
config PC87312
bool
@@ -29,6 +30,7 @@ config PIIX4
# For historical reasons, SuperIO devices are created in the board
# for PIIX4.
select ISA_BUS
+ select USB_UHCI
config VT82C686
bool
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 2c60be99bc..5f67d0d6d9 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -34,7 +34,7 @@ config PCI_TESTDEV
config EDU
bool
default y if TEST_DEVICES
- depends on PCI
+ depends on PCI && MSI_NONBROKEN
config PCA9552
bool
@@ -67,7 +67,7 @@ config MACIO
config IVSHMEM_DEVICE
bool
default y if PCI_DEVICES
- depends on PCI && LINUX && IVSHMEM
+ depends on PCI && LINUX && IVSHMEM && MSI_NONBROKEN
config ECCMEMCTL
bool
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index c00ec03cd1..7d7bbc5d7c 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -28,7 +28,7 @@ config E1000_PCI
config E1000E_PCI_EXPRESS
bool
default y if PCI_DEVICES
- depends on PCI_EXPRESS
+ depends on PCI_EXPRESS && MSI_NONBROKEN
config RTL8139_PCI
bool
@@ -107,7 +107,7 @@ config ETSEC
config ROCKER
bool
default y if PCI_DEVICES
- depends on PCI
+ depends on PCI && MSI_NONBROKEN
config CAN_BUS
bool
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 5e144cb4e4..9b39bccfb2 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -120,6 +120,8 @@ typedef struct E1000State_st {
bool mit_irq_level; /* Tracks interrupt pin level. */
uint32_t mit_ide; /* Tracks E1000_TXD_CMD_IDE bit. */
+ QEMUTimer *flush_queue_timer;
+
/* Compatibility flags for migration to/from qemu 1.3.0 and older */
#define E1000_FLAG_AUTONEG_BIT 0
#define E1000_FLAG_MIT_BIT 1
@@ -366,6 +368,7 @@ static void e1000_reset(void *opaque)
timer_del(d->autoneg_timer);
timer_del(d->mit_timer);
+ timer_del(d->flush_queue_timer);
d->mit_timer_on = 0;
d->mit_irq_level = 0;
d->mit_ide = 0;
@@ -392,6 +395,14 @@ set_ctrl(E1000State *s, int index, uint32_t val)
}
static void
+e1000_flush_queue_timer(void *opaque)
+{
+ E1000State *s = opaque;
+
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+}
+
+static void
set_rx_control(E1000State *s, int index, uint32_t val)
{
s->mac_reg[RCTL] = val;
@@ -399,7 +410,8 @@ set_rx_control(E1000State *s, int index, uint32_t val)
s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
s->mac_reg[RCTL]);
- qemu_flush_queued_packets(qemu_get_queue(s->nic));
+ timer_mod(s->flush_queue_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
}
static void
@@ -837,7 +849,7 @@ e1000_can_receive(NetClientState *nc)
E1000State *s = qemu_get_nic_opaque(nc);
return e1000x_rx_ready(&s->parent_obj, s->mac_reg) &&
- e1000_has_rxbufs(s, 1);
+ e1000_has_rxbufs(s, 1) && !timer_pending(s->flush_queue_timer);
}
static uint64_t rx_desc_base(E1000State *s)
@@ -881,6 +893,10 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
return -1;
}
+ if (timer_pending(s->flush_queue_timer)) {
+ return 0;
+ }
+
/* Pad to minimum Ethernet frame length */
if (size < sizeof(min_buf)) {
iov_to_buf(iov, iovcnt, 0, min_buf, size);
@@ -1637,6 +1653,8 @@ pci_e1000_uninit(PCIDevice *dev)
timer_free(d->autoneg_timer);
timer_del(d->mit_timer);
timer_free(d->mit_timer);
+ timer_del(d->flush_queue_timer);
+ timer_free(d->flush_queue_timer);
qemu_del_nic(d->nic);
}
@@ -1700,6 +1718,8 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
+ d->flush_queue_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
+ e1000_flush_queue_timer, d);
}
static void qdev_e1000_reset(DeviceState *dev)
diff --git a/hw/pci-bridge/Kconfig b/hw/pci-bridge/Kconfig
index b167b98497..a51ec716f5 100644
--- a/hw/pci-bridge/Kconfig
+++ b/hw/pci-bridge/Kconfig
@@ -1,7 +1,7 @@
config PCIE_PORT
bool
default y if PCI_DEVICES
- depends on PCI_EXPRESS
+ depends on PCI_EXPRESS && MSI_NONBROKEN
config PXB
bool
@@ -10,12 +10,12 @@ config PXB
config XIO3130
bool
default y if PCI_DEVICES
- depends on PCI_EXPRESS
+ depends on PCI_EXPRESS && MSI_NONBROKEN
config IOH3420
bool
default y if PCI_DEVICES
- depends on PCI_EXPRESS
+ depends on PCI_EXPRESS && MSI_NONBROKEN
config I82801B11
bool
diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index b39ea297ba..8c16d96b3f 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -49,3 +49,4 @@ config PCI_EXPRESS_XILINX
config PCI_EXPRESS_DESIGNWARE
bool
select PCI_EXPRESS
+ select MSI_NONBROKEN
diff --git a/hw/pci/Kconfig b/hw/pci/Kconfig
index 3b8638b51d..77f8b005ff 100644
--- a/hw/pci/Kconfig
+++ b/hw/pci/Kconfig
@@ -7,3 +7,9 @@ config PCI_EXPRESS
config PCI_DEVICES
bool
+
+config MSI_NONBROKEN
+ # selected by interrupt controllers that do not support MSI,
+ # or support it and have a good implementation. See commit
+ # 47d2b0f33c664533b8dbd5cb17faa8e6a01afe1f.
+ bool
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 2b83637511..a3465155f0 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -2,12 +2,14 @@ config PSERIES
bool
imply PCI_DEVICES
imply TEST_DEVICES
+ imply VIRTIO_VGA
select DIMM
select PCI
select SPAPR_VSCSI
select VFIO if LINUX # needed by spapr_pci_vfio.c
select XICS_SPAPR
select XIVE_SPAPR
+ select MSI_NONBROKEN
config SPAPR_RNG
bool
@@ -36,6 +38,7 @@ config PPC440
bool
imply PCI_DEVICES
imply TEST_DEVICES
+ imply E1000_PCI
select PCI_EXPRESS
select PPC4XX
select SERIAL
@@ -63,7 +66,6 @@ config PREP
imply TEST_DEVICES
select CS4231A
select PREP_PCI
- select I82374
select I82378
select LSI_SCSI_PCI
select M48T59
@@ -97,6 +99,7 @@ config MAC_NEWWORLD
config E500
bool
imply AT24C
+ imply VIRTIO_PCI
select ETSEC
select OPENPIC
select PLATFORM_BUS
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 49d57469fb..ad20584f26 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1101,7 +1101,7 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
tb_env = g_malloc0(sizeof(ppc_tb_t));
env->tb_env = tb_env;
tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
- if (env->insns_flags & PPC_SEGMENT_64B) {
+ if (is_book3s_arch2x(env)) {
/* All Book3S 64bit CPUs implement level based DEC logic */
tb_env->flags |= PPC_DECR_UNDERFLOW_LEVEL;
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6c16d6cfaf..b52b82d298 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1252,38 +1252,8 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
_FDT(fdt_setprop_string(fdt, 0, "model", "IBM pSeries (emulated by qemu)"));
_FDT(fdt_setprop_string(fdt, 0, "compatible", "qemu,pseries"));
- /*
- * Add info to guest to indentify which host is it being run on
- * and what is the uuid of the guest
- */
- if (spapr->host_model && !g_str_equal(spapr->host_model, "none")) {
- if (g_str_equal(spapr->host_model, "passthrough")) {
- /* -M host-model=passthrough */
- if (kvmppc_get_host_model(&buf)) {
- _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
- g_free(buf);
- }
- } else {
- /* -M host-model=<user-string> */
- _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
- }
- }
-
- if (spapr->host_serial && !g_str_equal(spapr->host_serial, "none")) {
- if (g_str_equal(spapr->host_serial, "passthrough")) {
- /* -M host-serial=passthrough */
- if (kvmppc_get_host_serial(&buf)) {
- _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
- g_free(buf);
- }
- } else {
- /* -M host-serial=<user-string> */
- _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
- }
- }
-
+ /* Guest UUID & Name*/
buf = qemu_uuid_unparse_strdup(&qemu_uuid);
-
_FDT(fdt_setprop_string(fdt, 0, "vm,uuid", buf));
if (qemu_uuid_set) {
_FDT(fdt_setprop_string(fdt, 0, "system-id", buf));
@@ -1295,6 +1265,21 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
qemu_get_vm_name()));
}
+ /* Host Model & Serial Number */
+ if (spapr->host_model) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
+ } else if (smc->broken_host_serial_model && kvmppc_get_host_model(&buf)) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
+ g_free(buf);
+ }
+
+ if (spapr->host_serial) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
+ } else if (smc->broken_host_serial_model && kvmppc_get_host_serial(&buf)) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
+ g_free(buf);
+ }
+
_FDT(fdt_setprop_cell(fdt, 0, "#address-cells", 2));
_FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
@@ -2795,13 +2780,7 @@ static void spapr_machine_init(MachineState *machine)
/* advertise XIVE on POWER9 machines */
if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
- if (ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00,
- 0, spapr->max_compat_pvr)) {
- spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
- } else if (spapr->irq->ov5 & SPAPR_OV5_XIVE_EXPLOIT) {
- error_report("XIVE-only machines require a POWER9 CPU");
- exit(1);
- }
+ spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
}
/* init CPUs */
@@ -3352,12 +3331,12 @@ static void spapr_instance_init(Object *obj)
spapr_get_host_model, spapr_set_host_model,
&error_abort);
object_property_set_description(obj, "host-model",
- "Set host's model-id to use - none|passthrough|string", &error_abort);
+ "Host model to advertise in guest device tree", &error_abort);
object_property_add_str(obj, "host-serial",
spapr_get_host_serial, spapr_set_host_serial,
&error_abort);
object_property_set_description(obj, "host-serial",
- "Set host's system-id to use - none|passthrough|string", &error_abort);
+ "Host serial number to advertise in guest device tree", &error_abort);
}
static void spapr_machine_finalizefn(Object *obj)
@@ -4381,18 +4360,14 @@ DEFINE_SPAPR_MACHINE(4_0, "4.0", true);
static void spapr_machine_3_1_class_options(MachineClass *mc)
{
SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
- static GlobalProperty compat[] = {
- { TYPE_SPAPR_MACHINE, "host-model", "passthrough" },
- { TYPE_SPAPR_MACHINE, "host-serial", "passthrough" },
- };
spapr_machine_4_0_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
- compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
smc->update_dt_enabled = false;
smc->dr_phb_enabled = false;
+ smc->broken_host_serial_model = true;
smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 253e4de7fd..0a84e4cf63 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -16,6 +16,7 @@
#include "hw/ppc/spapr_xive.h"
#include "hw/ppc/xics.h"
#include "hw/ppc/xics_spapr.h"
+#include "cpu-models.h"
#include "sysemu/kvm.h"
#include "trace.h"
@@ -582,12 +583,55 @@ SpaprIrq spapr_irq_dual = {
.get_nodename = spapr_irq_get_nodename_dual,
};
+
+static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
+{
+ MachineState *machine = MACHINE(spapr);
+
+ /*
+ * Sanity checks on non-P9 machines. On these, XIVE is not
+ * advertised, see spapr_dt_ov5_platform_support()
+ */
+ if (!ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00,
+ 0, spapr->max_compat_pvr)) {
+ /*
+ * If the 'dual' interrupt mode is selected, force XICS as CAS
+ * negotiation is useless.
+ */
+ if (spapr->irq == &spapr_irq_dual) {
+ spapr->irq = &spapr_irq_xics;
+ return;
+ }
+
+ /*
+ * Non-P9 machines using only XIVE is a bogus setup. We have two
+ * scenarios to take into account because of the compat mode:
+ *
+ * 1. POWER7/8 machines should fail to init later on when creating
+ * the XIVE interrupt presenters because a POWER9 exception
+ * model is required.
+
+ * 2. POWER9 machines using the POWER8 compat mode won't fail and
+ * will let the OS boot with a partial XIVE setup : DT
+ * properties but no hcalls.
+ *
+ * To cover both and not confuse the OS, add an early failure in
+ * QEMU.
+ */
+ if (spapr->irq == &spapr_irq_xive) {
+ error_setg(errp, "XIVE-only machines require a POWER9 CPU");
+ return;
+ }
+ }
+}
+
/*
* sPAPR IRQ frontend routines for devices
*/
void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
{
MachineState *machine = MACHINE(spapr);
+ Error *local_err = NULL;
if (machine_kernel_irqchip_split(machine)) {
error_setg(errp, "kernel_irqchip split mode not supported on pseries");
@@ -600,6 +644,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
return;
}
+ spapr_irq_check(spapr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
/* Initialize the MSI IRQ allocator. */
if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
diff --git a/hw/rdma/Kconfig b/hw/rdma/Kconfig
new file mode 100644
index 0000000000..8e2211288f
--- /dev/null
+++ b/hw/rdma/Kconfig
@@ -0,0 +1,3 @@
+config VMW_PVRDMA
+ default y if PCI_DEVICES
+ depends on PVRDMA && PCI && MSI_NONBROKEN
diff --git a/hw/rdma/Makefile.objs b/hw/rdma/Makefile.objs
index c354e60e5b..819bb12a35 100644
--- a/hw/rdma/Makefile.objs
+++ b/hw/rdma/Makefile.objs
@@ -1,5 +1,3 @@
-ifeq ($(CONFIG_PVRDMA),y)
-obj-$(CONFIG_PCI) += rdma_utils.o rdma_backend.o rdma_rm.o rdma.o
-obj-$(CONFIG_PCI) += vmw/pvrdma_dev_ring.o vmw/pvrdma_cmd.o \
+obj-$(CONFIG_VMW_PVRDMA) += rdma_utils.o rdma_backend.o rdma_rm.o rdma.o
+obj-$(CONFIG_VMW_PVRDMA) += vmw/pvrdma_dev_ring.o vmw/pvrdma_cmd.o \
vmw/pvrdma_qp_ops.o vmw/pvrdma_main.o
-endif
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 8c7fc1f31d..8674211085 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -6,6 +6,7 @@ config HART
config SIFIVE
bool
+ select MSI_NONBROKEN
config SIFIVE_E
bool
diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index 1c703e1a37..ac768e6c27 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -22,6 +22,7 @@
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "hw/sysbus.h"
+#include "hw/pci/msi.h"
#include "target/riscv/cpu.h"
#include "sysemu/sysemu.h"
#include "hw/riscv/sifive_plic.h"
@@ -458,6 +459,8 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
exit(1);
}
}
+
+ msi_nonbroken = true;
}
static void sifive_plic_class_init(ObjectClass *klass, void *data)
diff --git a/hw/s390x/Kconfig b/hw/s390x/Kconfig
index a7046ea41f..5e7d8a2bae 100644
--- a/hw/s390x/Kconfig
+++ b/hw/s390x/Kconfig
@@ -9,3 +9,4 @@ config S390_CCW_VIRTIO
select S390_FLIC
select SCLPCONSOLE
select VIRTIO_CCW
+ select MSI_NONBROKEN
diff --git a/hw/sh4/Kconfig b/hw/sh4/Kconfig
index 8597613a35..593662d28a 100644
--- a/hw/sh4/Kconfig
+++ b/hw/sh4/Kconfig
@@ -2,6 +2,7 @@ config R2D
bool
imply PCI_DEVICES
imply TEST_DEVICES
+ imply RTL8139_PCI
select I82378 if TEST_DEVICES
select IDE_MMIO
select PFLASH_CFI02
diff --git a/hw/sparc64/Kconfig b/hw/sparc64/Kconfig
index 4a8166ebb7..d4d76a89be 100644
--- a/hw/sparc64/Kconfig
+++ b/hw/sparc64/Kconfig
@@ -3,13 +3,13 @@ config SUN4U
imply PCI_DEVICES
imply SUNHME
imply TEST_DEVICES
+ imply PARALLEL
select M48T59
select ISA_BUS
select FDC
select SERIAL_ISA
select PCI_SABRE
select IDE_CMD646
- select PARALLEL
select PCKBD
select SIMBA
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 196a9f7200..81cf5ab7a5 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1200,7 +1200,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
if (head == 0)
return 0;
- for (cur = head; cur; cur = next_ed) {
+ for (cur = head; cur && link_cnt++ < ED_LINK_LIMIT; cur = next_ed) {
if (ohci_read_ed(ohci, cur, &ed)) {
trace_usb_ohci_ed_read_error(cur);
ohci_die(ohci);
@@ -1209,11 +1209,6 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
next_ed = ed.next & OHCI_DPTR_MASK;
- if (++link_cnt > ED_LINK_LIMIT) {
- ohci_die(ohci);
- return 0;
- }
-
if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
uint32_t addr;
/* Cancel pending packets for ED that have been paused. */
diff --git a/include/block/block.h b/include/block/block.h
index e452988b66..c7a26199aa 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -83,8 +83,13 @@ typedef enum {
*/
BDRV_REQ_SERIALISING = 0x80,
+ /* Execute the request only if the operation can be offloaded or otherwise
+ * be executed efficiently, but return an error instead of using a slow
+ * fallback. */
+ BDRV_REQ_NO_FALLBACK = 0x100,
+
/* Mask of valid flags */
- BDRV_REQ_MASK = 0xff,
+ BDRV_REQ_MASK = 0x1ff,
} BdrvRequestFlags;
typedef struct BlockSizes {
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
index 6799614e56..ba223dd1f1 100644
--- a/include/block/raw-aio.h
+++ b/include/block/raw-aio.h
@@ -40,6 +40,7 @@
/* AIO flags */
#define QEMU_AIO_MISALIGNED 0x1000
#define QEMU_AIO_BLKDEV 0x2000
+#define QEMU_AIO_NO_FALLBACK 0x4000
/* linux-aio.c - Linux native implementation */
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index e9f9e2223f..d06f25aa0f 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -11,7 +11,7 @@
#ifndef HW_BLOCK_H
#define HW_BLOCK_H
-#include "qemu-common.h"
+#include "exec/hwaddr.h"
#include "qapi/qapi-types-block-core.h"
/* Configuration */
@@ -70,6 +70,11 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \
BLOCKDEV_ON_ERROR_AUTO)
+/* Backend access helpers */
+
+bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
+ Error **errp);
+
/* Configuration helpers */
bool blkconf_geometry(BlockConf *conf, int *trans,
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index c11e3d5b34..536f62667b 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -105,8 +105,8 @@ struct VTDAddressSpace {
uint8_t devfn;
AddressSpace as;
IOMMUMemoryRegion iommu;
- MemoryRegion root;
- MemoryRegion sys_alias;
+ MemoryRegion root; /* The root container of the device */
+ MemoryRegion nodmar; /* The alias of shared nodmar MR */
MemoryRegion iommu_ir; /* Interrupt region: 0xfeeXXXXX */
IntelIOMMUState *iommu_state;
VTDContextCacheEntry context_cache_entry;
@@ -221,6 +221,9 @@ union VTD_IR_MSIAddress {
struct IntelIOMMUState {
X86IOMMUState x86_iommu;
MemoryRegion csrmem;
+ MemoryRegion mr_nodmar;
+ MemoryRegion mr_ir;
+ MemoryRegion mr_sys_alias;
uint8_t csr[DMAR_REG_SIZE]; /* register values */
uint8_t wmask[DMAR_REG_SIZE]; /* R/W bytes */
uint8_t w1cmask[DMAR_REG_SIZE]; /* RW1C(Write 1 to Clear) bytes */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 2b4c05a2ec..5ea8081041 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -118,6 +118,7 @@ struct SpaprMachineClass {
bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */
bool pre_2_10_has_unused_icps;
bool legacy_irq_allocation;
+ bool broken_host_serial_model; /* present real host info to the guest */
void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
diff --git a/memory.c b/memory.c
index e49369d85d..9fbca52e05 100644
--- a/memory.c
+++ b/memory.c
@@ -1649,10 +1649,17 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
uint64_t size,
void *ptr)
{
- memory_region_init_ram_ptr(mr, owner, name, size, ptr);
+ memory_region_init(mr, owner, name, size);
+ mr->ram = true;
+ mr->terminates = true;
mr->ram_device = true;
mr->ops = &ram_device_mem_ops;
mr->opaque = mr;
+ mr->destructor = memory_region_destructor_ram;
+ mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
+ /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL. */
+ assert(ptr != NULL);
+ mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
}
void memory_region_init_alias(MemoryRegion *mr,
diff --git a/migration/colo.c b/migration/colo.c
index 5ba610dc01..238a6d62c7 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -38,6 +38,9 @@
static bool vmstate_loading;
static Notifier packets_compare_notifier;
+/* User need to know colo mode after COLO failover */
+static COLOMode last_colo_mode;
+
#define COLO_BUFFER_BASE_SIZE (4 * 1024 * 1024)
bool migration_in_colo_state(void)
@@ -121,6 +124,7 @@ static void secondary_vm_do_failover(void)
}
/* Notify COLO incoming thread that failover work is finished */
qemu_sem_post(&mis->colo_incoming_sem);
+
/* For Secondary VM, jump to incoming co */
if (mis->migration_incoming_co) {
qemu_coroutine_enter(mis->migration_incoming_co);
@@ -196,10 +200,16 @@ void colo_do_failover(MigrationState *s)
vm_stop_force_state(RUN_STATE_COLO);
}
- if (get_colo_mode() == COLO_MODE_PRIMARY) {
+ switch (get_colo_mode()) {
+ case COLO_MODE_PRIMARY:
primary_vm_do_failover();
- } else {
+ break;
+ case COLO_MODE_SECONDARY:
secondary_vm_do_failover();
+ break;
+ default:
+ error_report("colo_do_failover failed because the colo mode"
+ " could not be obtained");
}
}
@@ -257,16 +267,21 @@ COLOStatus *qmp_query_colo_status(Error **errp)
COLOStatus *s = g_new0(COLOStatus, 1);
s->mode = get_colo_mode();
+ s->last_mode = last_colo_mode;
switch (failover_get_state()) {
case FAILOVER_STATUS_NONE:
s->reason = COLO_EXIT_REASON_NONE;
break;
- case FAILOVER_STATUS_REQUIRE:
+ case FAILOVER_STATUS_COMPLETED:
s->reason = COLO_EXIT_REASON_REQUEST;
break;
default:
- s->reason = COLO_EXIT_REASON_ERROR;
+ if (migration_in_colo_state()) {
+ s->reason = COLO_EXIT_REASON_PROCESSING;
+ } else {
+ s->reason = COLO_EXIT_REASON_ERROR;
+ }
}
return s;
@@ -504,6 +519,12 @@ static void colo_process_checkpoint(MigrationState *s)
Error *local_err = NULL;
int ret;
+ last_colo_mode = get_colo_mode();
+ if (last_colo_mode != COLO_MODE_PRIMARY) {
+ error_report("COLO mode must be COLO_MODE_PRIMARY");
+ return;
+ }
+
failover_init_state();
s->rp_state.from_dst_file = qemu_file_get_return_path(s->to_dst_file);
@@ -578,16 +599,13 @@ out:
* or the user triggered failover.
*/
switch (failover_get_state()) {
- case FAILOVER_STATUS_NONE:
- qapi_event_send_colo_exit(COLO_MODE_PRIMARY,
- COLO_EXIT_REASON_ERROR);
- break;
- case FAILOVER_STATUS_REQUIRE:
+ case FAILOVER_STATUS_COMPLETED:
qapi_event_send_colo_exit(COLO_MODE_PRIMARY,
COLO_EXIT_REASON_REQUEST);
break;
default:
- abort();
+ qapi_event_send_colo_exit(COLO_MODE_PRIMARY,
+ COLO_EXIT_REASON_ERROR);
}
/* Hope this not to be too long to wait here */
@@ -680,6 +698,12 @@ void *colo_process_incoming_thread(void *opaque)
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_COLO);
+ last_colo_mode = get_colo_mode();
+ if (last_colo_mode != COLO_MODE_SECONDARY) {
+ error_report("COLO mode must be COLO_MODE_SECONDARY");
+ return NULL;
+ }
+
failover_init_state();
mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
@@ -849,17 +873,18 @@ out:
error_report_err(local_err);
}
+ /*
+ * There are only two reasons we can get here, some error happened
+ * or the user triggered failover.
+ */
switch (failover_get_state()) {
- case FAILOVER_STATUS_NONE:
- qapi_event_send_colo_exit(COLO_MODE_SECONDARY,
- COLO_EXIT_REASON_ERROR);
- break;
- case FAILOVER_STATUS_REQUIRE:
+ case FAILOVER_STATUS_COMPLETED:
qapi_event_send_colo_exit(COLO_MODE_SECONDARY,
COLO_EXIT_REASON_REQUEST);
break;
default:
- abort();
+ qapi_event_send_colo_exit(COLO_MODE_SECONDARY,
+ COLO_EXIT_REASON_ERROR);
}
if (fb) {
diff --git a/migration/migration.c b/migration/migration.c
index df6fd8e0e5..69f75124c9 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -82,7 +82,6 @@
/* The delay time (in ms) between two COLO checkpoints */
#define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
#define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
-#define DEFAULT_MIGRATE_MULTIFD_PAGE_COUNT 16
/* Background transfer rate for postcopy, 0 means unlimited, note
* that page requests can still exceed this limit.
@@ -758,6 +757,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
params->tls_creds = g_strdup(s->parameters.tls_creds);
params->has_tls_hostname = true;
params->tls_hostname = g_strdup(s->parameters.tls_hostname);
+ params->has_tls_authz = true;
+ params->tls_authz = g_strdup(s->parameters.tls_authz);
params->has_max_bandwidth = true;
params->max_bandwidth = s->parameters.max_bandwidth;
params->has_downtime_limit = true;
@@ -766,10 +767,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
params->has_block_incremental = true;
params->block_incremental = s->parameters.block_incremental;
- params->has_x_multifd_channels = true;
- params->x_multifd_channels = s->parameters.x_multifd_channels;
- params->has_x_multifd_page_count = true;
- params->x_multifd_page_count = s->parameters.x_multifd_page_count;
+ params->has_multifd_channels = true;
+ params->multifd_channels = s->parameters.multifd_channels;
params->has_xbzrle_cache_size = true;
params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
params->has_max_postcopy_bandwidth = true;
@@ -1152,20 +1151,12 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp)
/* x_checkpoint_delay is now always positive */
- if (params->has_x_multifd_channels && (params->x_multifd_channels < 1)) {
+ if (params->has_multifd_channels && (params->multifd_channels < 1)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
"multifd_channels",
"is invalid, it should be in the range of 1 to 255");
return false;
}
- if (params->has_x_multifd_page_count &&
- (params->x_multifd_page_count < 1 ||
- params->x_multifd_page_count > 10000)) {
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
- "multifd_page_count",
- "is invalid, it should be in the range of 1 to 10000");
- return false;
- }
if (params->has_xbzrle_cache_size &&
(params->xbzrle_cache_size < qemu_target_page_size() ||
@@ -1274,11 +1265,8 @@ static void migrate_params_test_apply(MigrateSetParameters *params,
if (params->has_block_incremental) {
dest->block_incremental = params->block_incremental;
}
- if (params->has_x_multifd_channels) {
- dest->x_multifd_channels = params->x_multifd_channels;
- }
- if (params->has_x_multifd_page_count) {
- dest->x_multifd_page_count = params->x_multifd_page_count;
+ if (params->has_multifd_channels) {
+ dest->multifd_channels = params->multifd_channels;
}
if (params->has_xbzrle_cache_size) {
dest->xbzrle_cache_size = params->xbzrle_cache_size;
@@ -1345,9 +1333,15 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
}
+ if (params->has_tls_authz) {
+ g_free(s->parameters.tls_authz);
+ assert(params->tls_authz->type == QTYPE_QSTRING);
+ s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
+ }
+
if (params->has_max_bandwidth) {
s->parameters.max_bandwidth = params->max_bandwidth;
- if (s->to_dst_file) {
+ if (s->to_dst_file && !migration_in_postcopy()) {
qemu_file_set_rate_limit(s->to_dst_file,
s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
}
@@ -1367,11 +1361,8 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
if (params->has_block_incremental) {
s->parameters.block_incremental = params->block_incremental;
}
- if (params->has_x_multifd_channels) {
- s->parameters.x_multifd_channels = params->x_multifd_channels;
- }
- if (params->has_x_multifd_page_count) {
- s->parameters.x_multifd_page_count = params->x_multifd_page_count;
+ if (params->has_multifd_channels) {
+ s->parameters.multifd_channels = params->multifd_channels;
}
if (params->has_xbzrle_cache_size) {
s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
@@ -1379,6 +1370,10 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
}
if (params->has_max_postcopy_bandwidth) {
s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
+ if (s->to_dst_file && migration_in_postcopy()) {
+ qemu_file_set_rate_limit(s->to_dst_file,
+ s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO);
+ }
}
if (params->has_max_cpu_throttle) {
s->parameters.max_cpu_throttle = params->max_cpu_throttle;
@@ -2130,7 +2125,7 @@ bool migrate_use_multifd(void)
s = migrate_get_current();
- return s->enabled_capabilities[MIGRATION_CAPABILITY_X_MULTIFD];
+ return s->enabled_capabilities[MIGRATION_CAPABILITY_MULTIFD];
}
bool migrate_pause_before_switchover(void)
@@ -2149,16 +2144,7 @@ int migrate_multifd_channels(void)
s = migrate_get_current();
- return s->parameters.x_multifd_channels;
-}
-
-int migrate_multifd_page_count(void)
-{
- MigrationState *s;
-
- s = migrate_get_current();
-
- return s->parameters.x_multifd_page_count;
+ return s->parameters.multifd_channels;
}
int migrate_use_xbzrle(void)
@@ -3400,12 +3386,9 @@ static Property migration_properties[] = {
DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
parameters.x_checkpoint_delay,
DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
- DEFINE_PROP_UINT8("x-multifd-channels", MigrationState,
- parameters.x_multifd_channels,
+ DEFINE_PROP_UINT8("multifd-channels", MigrationState,
+ parameters.multifd_channels,
DEFAULT_MIGRATE_MULTIFD_CHANNELS),
- DEFINE_PROP_UINT32("x-multifd-page-count", MigrationState,
- parameters.x_multifd_page_count,
- DEFAULT_MIGRATE_MULTIFD_PAGE_COUNT),
DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
parameters.xbzrle_cache_size,
DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
@@ -3440,7 +3423,7 @@ static Property migration_properties[] = {
DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
- DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_X_MULTIFD),
+ DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
DEFINE_PROP_END_OF_LIST(),
};
@@ -3494,8 +3477,7 @@ static void migration_instance_init(Object *obj)
params->has_downtime_limit = true;
params->has_x_checkpoint_delay = true;
params->has_block_incremental = true;
- params->has_x_multifd_channels = true;
- params->has_x_multifd_page_count = true;
+ params->has_multifd_channels = true;
params->has_xbzrle_cache_size = true;
params->has_max_postcopy_bandwidth = true;
params->has_max_cpu_throttle = true;
diff --git a/migration/migration.h b/migration/migration.h
index 99e99e56bd..0f986935e1 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -274,7 +274,6 @@ bool migrate_auto_converge(void);
bool migrate_use_multifd(void);
bool migrate_pause_before_switchover(void);
int migrate_multifd_channels(void);
-int migrate_multifd_page_count(void);
int migrate_use_xbzrle(void);
int64_t migrate_xbzrle_cache_size(void);
diff --git a/migration/ram.c b/migration/ram.c
index 35bd6213e9..d7f8fe45a8 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -583,20 +583,29 @@ exit:
#define MULTIFD_FLAG_SYNC (1 << 0)
+/* This value needs to be a multiple of qemu_target_page_size() */
+#define MULTIFD_PACKET_SIZE (512 * 1024)
+
typedef struct {
uint32_t magic;
uint32_t version;
unsigned char uuid[16]; /* QemuUUID */
uint8_t id;
+ uint8_t unused1[7]; /* Reserved for future use */
+ uint64_t unused2[4]; /* Reserved for future use */
} __attribute__((packed)) MultiFDInit_t;
typedef struct {
uint32_t magic;
uint32_t version;
uint32_t flags;
- uint32_t size;
- uint32_t used;
+ /* maximum number of allocated pages */
+ uint32_t pages_alloc;
+ uint32_t pages_used;
+ /* size of the next packet that contains pages */
+ uint32_t next_packet_size;
uint64_t packet_num;
+ uint64_t unused[4]; /* Reserved for future use */
char ramblock[256];
uint64_t offset[];
} __attribute__((packed)) MultiFDPacket_t;
@@ -643,6 +652,8 @@ typedef struct {
MultiFDPacket_t *packet;
/* multifd flags for each packet */
uint32_t flags;
+ /* size of the next packet that contains pages */
+ uint32_t next_packet_size;
/* global number of generated multifd packets */
uint64_t packet_num;
/* thread local variables */
@@ -679,6 +690,8 @@ typedef struct {
/* global number of generated multifd packets */
uint64_t packet_num;
/* thread local variables */
+ /* size of the next packet that contains pages */
+ uint32_t next_packet_size;
/* packets sent through this channel */
uint64_t num_packets;
/* pages sent through this channel */
@@ -776,13 +789,15 @@ static void multifd_pages_clear(MultiFDPages_t *pages)
static void multifd_send_fill_packet(MultiFDSendParams *p)
{
MultiFDPacket_t *packet = p->packet;
+ uint32_t page_max = MULTIFD_PACKET_SIZE / qemu_target_page_size();
int i;
packet->magic = cpu_to_be32(MULTIFD_MAGIC);
packet->version = cpu_to_be32(MULTIFD_VERSION);
packet->flags = cpu_to_be32(p->flags);
- packet->size = cpu_to_be32(migrate_multifd_page_count());
- packet->used = cpu_to_be32(p->pages->used);
+ packet->pages_alloc = cpu_to_be32(page_max);
+ packet->pages_used = cpu_to_be32(p->pages->used);
+ packet->next_packet_size = cpu_to_be32(p->next_packet_size);
packet->packet_num = cpu_to_be64(p->packet_num);
if (p->pages->block) {
@@ -797,6 +812,7 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
{
MultiFDPacket_t *packet = p->packet;
+ uint32_t pages_max = MULTIFD_PACKET_SIZE / qemu_target_page_size();
RAMBlock *block;
int i;
@@ -818,22 +834,35 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
p->flags = be32_to_cpu(packet->flags);
- packet->size = be32_to_cpu(packet->size);
- if (packet->size > migrate_multifd_page_count()) {
+ packet->pages_alloc = be32_to_cpu(packet->pages_alloc);
+ /*
+ * If we recevied a packet that is 100 times bigger than expected
+ * just stop migration. It is a magic number.
+ */
+ if (packet->pages_alloc > pages_max * 100) {
error_setg(errp, "multifd: received packet "
- "with size %d and expected maximum size %d",
- packet->size, migrate_multifd_page_count()) ;
+ "with size %d and expected a maximum size of %d",
+ packet->pages_alloc, pages_max * 100) ;
return -1;
}
+ /*
+ * We received a packet that is bigger than expected but inside
+ * reasonable limits (see previous comment). Just reallocate.
+ */
+ if (packet->pages_alloc > p->pages->allocated) {
+ multifd_pages_clear(p->pages);
+ multifd_pages_init(packet->pages_alloc);
+ }
- p->pages->used = be32_to_cpu(packet->used);
- if (p->pages->used > packet->size) {
+ p->pages->used = be32_to_cpu(packet->pages_used);
+ if (p->pages->used > packet->pages_alloc) {
error_setg(errp, "multifd: received packet "
- "with size %d and expected maximum size %d",
- p->pages->used, packet->size) ;
+ "with %d pages and expected maximum pages are %d",
+ p->pages->used, packet->pages_alloc) ;
return -1;
}
+ p->next_packet_size = be32_to_cpu(packet->next_packet_size);
p->packet_num = be64_to_cpu(packet->packet_num);
if (p->pages->used) {
@@ -1073,6 +1102,7 @@ static void *multifd_send_thread(void *opaque)
uint64_t packet_num = p->packet_num;
uint32_t flags = p->flags;
+ p->next_packet_size = used * qemu_target_page_size();
multifd_send_fill_packet(p);
p->flags = 0;
p->num_packets++;
@@ -1080,7 +1110,8 @@ static void *multifd_send_thread(void *opaque)
p->pages->used = 0;
qemu_mutex_unlock(&p->mutex);
- trace_multifd_send(p->id, packet_num, used, flags);
+ trace_multifd_send(p->id, packet_num, used, flags,
+ p->next_packet_size);
ret = qio_channel_write_all(p->c, (void *)p->packet,
p->packet_len, &local_err);
@@ -1088,9 +1119,12 @@ static void *multifd_send_thread(void *opaque)
break;
}
- ret = qio_channel_writev_all(p->c, p->pages->iov, used, &local_err);
- if (ret != 0) {
- break;
+ if (used) {
+ ret = qio_channel_writev_all(p->c, p->pages->iov,
+ used, &local_err);
+ if (ret != 0) {
+ break;
+ }
}
qemu_mutex_lock(&p->mutex);
@@ -1148,7 +1182,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
int multifd_save_setup(void)
{
int thread_count;
- uint32_t page_count = migrate_multifd_page_count();
+ uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
uint8_t i;
if (!migrate_use_multifd()) {
@@ -1312,14 +1346,18 @@ static void *multifd_recv_thread(void *opaque)
used = p->pages->used;
flags = p->flags;
- trace_multifd_recv(p->id, p->packet_num, used, flags);
+ trace_multifd_recv(p->id, p->packet_num, used, flags,
+ p->next_packet_size);
p->num_packets++;
p->num_pages += used;
qemu_mutex_unlock(&p->mutex);
- ret = qio_channel_readv_all(p->c, p->pages->iov, used, &local_err);
- if (ret != 0) {
- break;
+ if (used) {
+ ret = qio_channel_readv_all(p->c, p->pages->iov,
+ used, &local_err);
+ if (ret != 0) {
+ break;
+ }
}
if (flags & MULTIFD_FLAG_SYNC) {
@@ -1344,7 +1382,7 @@ static void *multifd_recv_thread(void *opaque)
int multifd_load_setup(void)
{
int thread_count;
- uint32_t page_count = migrate_multifd_page_count();
+ uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
uint8_t i;
if (!migrate_use_multifd()) {
diff --git a/migration/rdma.c b/migration/rdma.c
index 63c118af09..c1bcece53b 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -641,10 +641,14 @@ static int qemu_rdma_init_one_block(RAMBlock *rb, void *opaque)
static int qemu_rdma_init_ram_blocks(RDMAContext *rdma)
{
RDMALocalBlocks *local = &rdma->local_ram_blocks;
+ int ret;
assert(rdma->blockmap == NULL);
memset(local, 0, sizeof *local);
- foreach_not_ignored_block(qemu_rdma_init_one_block, rdma);
+ ret = foreach_not_ignored_block(qemu_rdma_init_one_block, rdma);
+ if (ret) {
+ return ret;
+ }
trace_qemu_rdma_init_ram_blocks(local->nb_blocks);
rdma->dest_blocks = g_new0(RDMADestBlock,
rdma->local_ram_blocks.nb_blocks);
diff --git a/migration/tls.c b/migration/tls.c
index 3b9e8c9263..5171afc6c4 100644
--- a/migration/tls.c
+++ b/migration/tls.c
@@ -94,7 +94,7 @@ void migration_tls_channel_process_incoming(MigrationState *s,
tioc = qio_channel_tls_new_server(
ioc, creds,
- NULL, /* XXX pass ACL name */
+ s->parameters.tls_authz,
errp);
if (!tioc) {
return;
diff --git a/migration/trace-events b/migration/trace-events
index 5da4512030..de2e136e57 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -80,13 +80,13 @@ get_queued_page_not_dirty(const char *block_name, uint64_t tmp_offset, unsigned
migration_bitmap_sync_start(void) ""
migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64
migration_throttle(void) ""
-multifd_recv(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags) "channel %d packet number %" PRIu64 " pages %d flags 0x%x"
+multifd_recv(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags, uint32_t next_packet_size) "channel %d packet number %" PRIu64 " pages %d flags 0x%x next packet size %d"
multifd_recv_sync_main(long packet_num) "packet num %ld"
multifd_recv_sync_main_signal(uint8_t id) "channel %d"
multifd_recv_sync_main_wait(uint8_t id) "channel %d"
multifd_recv_thread_end(uint8_t id, uint64_t packets, uint64_t pages) "channel %d packets %" PRIu64 " pages %" PRIu64
multifd_recv_thread_start(uint8_t id) "%d"
-multifd_send(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags) "channel %d packet_num %" PRIu64 " pages %d flags 0x%x"
+multifd_send(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags, uint32_t next_packet_size) "channel %d packet_num %" PRIu64 " pages %d flags 0x%x next packet size %d"
multifd_send_sync_main(long packet_num) "packet num %ld"
multifd_send_sync_main_signal(uint8_t id) "channel %d"
multifd_send_sync_main_wait(uint8_t id) "channel %d"
diff --git a/net/socket.c b/net/socket.c
index 90ef3517be..c92354049b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -119,9 +119,13 @@ static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf,
ssize_t ret;
do {
- ret = qemu_sendto(s->fd, buf, size, 0,
- (struct sockaddr *)&s->dgram_dst,
- sizeof(s->dgram_dst));
+ if (s->dgram_dst.sin_family != AF_UNIX) {
+ ret = qemu_sendto(s->fd, buf, size, 0,
+ (struct sockaddr *)&s->dgram_dst,
+ sizeof(s->dgram_dst));
+ } else {
+ ret = send(s->fd, buf, size, 0);
+ }
} while (ret == -1 && errno == EINTR);
if (ret == -1 && errno == EAGAIN) {
@@ -336,6 +340,15 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
int newfd;
NetClientState *nc;
NetSocketState *s;
+ SocketAddress *sa;
+ SocketAddressType sa_type;
+
+ sa = socket_local_address(fd, errp);
+ if (!sa) {
+ return NULL;
+ }
+ sa_type = sa->type;
+ qapi_free_SocketAddress(sa);
/* fd passed: multicast: "learn" dgram_dst address from bound address and save it
* Because this may be "shared" socket from a "master" process, datagrams would be recv()
@@ -379,8 +392,12 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
"socket: fd=%d (cloned mcast=%s:%d)",
fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
} else {
+ if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) {
+ s->dgram_dst.sin_family = AF_UNIX;
+ }
+
snprintf(nc->info_str, sizeof(nc->info_str),
- "socket: fd=%d", fd);
+ "socket: fd=%d %s", fd, SocketAddressType_str(sa_type));
}
return s;
diff --git a/net/tap.c b/net/tap.c
index cc8525f154..e8aadd8d4b 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -592,7 +592,7 @@ int net_init_bridge(const Netdev *netdev, const char *name,
return -1;
}
- fcntl(fd, F_SETFL, O_NONBLOCK);
+ qemu_set_nonblock(fd);
vnet_hdr = tap_probe_vnet_hdr(fd);
s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
@@ -707,7 +707,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
}
return;
}
- fcntl(vhostfd, F_SETFL, O_NONBLOCK);
+ qemu_set_nonblock(vhostfd);
}
options.opaque = (void *)(uintptr_t)vhostfd;
@@ -791,7 +791,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
- fcntl(fd, F_SETFL, O_NONBLOCK);
+ qemu_set_nonblock(fd);
vnet_hdr = tap_probe_vnet_hdr(fd);
@@ -839,7 +839,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto free_fail;
}
- fcntl(fd, F_SETFL, O_NONBLOCK);
+ qemu_set_nonblock(fd);
if (i == 0) {
vnet_hdr = tap_probe_vnet_hdr(fd);
@@ -887,7 +887,7 @@ free_fail:
return -1;
}
- fcntl(fd, F_SETFL, O_NONBLOCK);
+ qemu_set_nonblock(fd);
vnet_hdr = tap_probe_vnet_hdr(fd);
net_init_tap_one(tap, peer, "bridge", name, ifname,
diff --git a/qapi/migration.json b/qapi/migration.json
index 5684733754..cfde29acf8 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -401,7 +401,7 @@
# @pause-before-switchover: Pause outgoing migration before serialising device
# state and before disabling block IO (since 2.11)
#
-# @x-multifd: Use more than one fd for migration (since 2.11)
+# @multifd: Use more than one fd for migration (since 4.0)
#
# @dirty-bitmaps: If enabled, QEMU will migrate named dirty bitmaps.
# (since 2.12)
@@ -420,7 +420,7 @@
{ 'enum': 'MigrationCapability',
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
- 'block', 'return-path', 'pause-before-switchover', 'x-multifd',
+ 'block', 'return-path', 'pause-before-switchover', 'multifd',
'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
'x-ignore-shared' ] }
@@ -541,6 +541,12 @@
# hostname must be provided so that the server's x509
# certificate identity can be validated. (Since 2.7)
#
+# @tls-authz: ID of the 'authz' object subclass that provides access control
+# checking of the TLS x509 certificate distinguished name.
+# This object is only resolved at time of use, so can be deleted
+# and recreated on the fly while the migration server is active.
+# If missing, it will default to denying access (Since 4.0)
+#
# @max-bandwidth: to set maximum speed for migration. maximum speed in
# bytes per second. (Since 2.8)
#
@@ -557,13 +563,10 @@
# migrated and the destination must already have access to the
# same backing chain as was used on the source. (since 2.10)
#
-# @x-multifd-channels: Number of channels used to migrate data in
-# parallel. This is the same number that the
-# number of sockets used for migration. The
-# default value is 2 (since 2.11)
-#
-# @x-multifd-page-count: Number of pages sent together to a thread.
-# The default value is 16 (since 2.11)
+# @multifd-channels: Number of channels used to migrate data in
+# parallel. This is the same number that the
+# number of sockets used for migration. The
+# default value is 2 (since 4.0)
#
# @xbzrle-cache-size: cache size to be used by XBZRLE migration. It
# needs to be a multiple of the target page size
@@ -585,9 +588,9 @@
'compress-level', 'compress-threads', 'decompress-threads',
'compress-wait-thread',
'cpu-throttle-initial', 'cpu-throttle-increment',
- 'tls-creds', 'tls-hostname', 'max-bandwidth',
+ 'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth',
'downtime-limit', 'x-checkpoint-delay', 'block-incremental',
- 'x-multifd-channels', 'x-multifd-page-count',
+ 'multifd-channels',
'xbzrle-cache-size', 'max-postcopy-bandwidth',
'max-cpu-throttle' ] }
@@ -662,13 +665,10 @@
# migrated and the destination must already have access to the
# same backing chain as was used on the source. (since 2.10)
#
-# @x-multifd-channels: Number of channels used to migrate data in
-# parallel. This is the same number that the
-# number of sockets used for migration. The
-# default value is 2 (since 2.11)
-#
-# @x-multifd-page-count: Number of pages sent together to a thread.
-# The default value is 16 (since 2.11)
+# @multifd-channels: Number of channels used to migrate data in
+# parallel. This is the same number that the
+# number of sockets used for migration. The
+# default value is 2 (since 4.0)
#
# @xbzrle-cache-size: cache size to be used by XBZRLE migration. It
# needs to be a multiple of the target page size
@@ -699,12 +699,12 @@
'*cpu-throttle-increment': 'int',
'*tls-creds': 'StrOrNull',
'*tls-hostname': 'StrOrNull',
+ '*tls-authz': 'StrOrNull',
'*max-bandwidth': 'int',
'*downtime-limit': 'int',
'*x-checkpoint-delay': 'int',
'*block-incremental': 'bool',
- '*x-multifd-channels': 'int',
- '*x-multifd-page-count': 'int',
+ '*multifd-channels': 'int',
'*xbzrle-cache-size': 'size',
'*max-postcopy-bandwidth': 'size',
'*max-cpu-throttle': 'int' } }
@@ -780,6 +780,10 @@
# associated with the migration URI, if any. (Since 2.9)
# Note: 2.8 reports this by omitting tls-hostname instead.
#
+# @tls-authz: ID of the 'authz' object subclass that provides access control
+# checking of the TLS x509 certificate distinguished name. (Since
+# 4.0)
+#
# @max-bandwidth: to set maximum speed for migration. maximum speed in
# bytes per second. (Since 2.8)
#
@@ -795,13 +799,10 @@
# migrated and the destination must already have access to the
# same backing chain as was used on the source. (since 2.10)
#
-# @x-multifd-channels: Number of channels used to migrate data in
-# parallel. This is the same number that the
-# number of sockets used for migration.
-# The default value is 2 (since 2.11)
-#
-# @x-multifd-page-count: Number of pages sent together to a thread.
-# The default value is 16 (since 2.11)
+# @multifd-channels: Number of channels used to migrate data in
+# parallel. This is the same number that the
+# number of sockets used for migration.
+# The default value is 2 (since 4.0)
#
# @xbzrle-cache-size: cache size to be used by XBZRLE migration. It
# needs to be a multiple of the target page size
@@ -831,12 +832,12 @@
'*cpu-throttle-increment': 'uint8',
'*tls-creds': 'str',
'*tls-hostname': 'str',
+ '*tls-authz': 'str',
'*max-bandwidth': 'size',
'*downtime-limit': 'uint64',
'*x-checkpoint-delay': 'uint32',
'*block-incremental': 'bool' ,
- '*x-multifd-channels': 'uint8',
- '*x-multifd-page-count': 'uint32',
+ '*multifd-channels': 'uint8',
'*xbzrle-cache-size': 'size',
'*max-postcopy-bandwidth': 'size',
'*max-cpu-throttle':'uint8'} }
@@ -1037,19 +1038,22 @@
##
# @COLOExitReason:
#
-# The reason for a COLO exit
+# The reason for a COLO exit.
+#
+# @none: failover has never happened. This state does not occur
+# in the COLO_EXIT event, and is only visible in the result of
+# query-colo-status.
#
-# @none: no failover has ever happened. This can't occur in the
-# COLO_EXIT event, only in the result of query-colo-status.
+# @request: COLO exit is due to an external request.
#
-# @request: COLO exit is due to an external request
+# @error: COLO exit is due to an internal error.
#
-# @error: COLO exit is due to an internal error
+# @processing: COLO is currently handling a failover (since 4.0).
#
# Since: 3.1
##
{ 'enum': 'COLOExitReason',
- 'data': [ 'none', 'request', 'error' ] }
+ 'data': [ 'none', 'request', 'error' , 'processing' ] }
##
# @x-colo-lost-heartbeat:
@@ -1376,12 +1380,17 @@
# @mode: COLO running mode. If COLO is running, this field will return
# 'primary' or 'secondary'.
#
+# @last_mode: COLO last running mode. If COLO is running, this field
+# will return same like mode field, after failover we can
+# use this field to get last colo mode. (since 4.1)
+#
# @reason: describes the reason for the COLO exit.
#
# Since: 3.1
##
{ 'struct': 'COLOStatus',
- 'data': { 'mode': 'COLOMode', 'reason': 'COLOExitReason' } }
+ 'data': { 'mode': 'COLOMode', 'last_mode': 'COLOMode',
+ 'reason': 'COLOExitReason' } }
##
# @query-colo-status:
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 5f812bb9f2..e2c366e09e 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -111,7 +111,7 @@ static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,
if (oob && !(cmd->options & QCO_ALLOW_OOB)) {
error_setg(errp, "The command %s does not support OOB",
command);
- return false;
+ return NULL;
}
if (runstate_check(RUN_STATE_PRECONFIG) &&
diff --git a/qemu-img.c b/qemu-img.c
index 5fac840742..8ee63daeae 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1932,7 +1932,7 @@ static int convert_do_copy(ImgConvertState *s)
if (!s->has_zero_init && !s->target_has_backing &&
bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)))
{
- ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP);
+ ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK);
if (ret == 0) {
s->has_zero_init = true;
}
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 35dcdcf413..09750a23ce 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -946,6 +946,7 @@ static void write_help(void)
" -b, -- write to the VM state rather than the virtual disk\n"
" -c, -- write compressed data with blk_write_compressed\n"
" -f, -- use Force Unit Access semantics\n"
+" -n, -- with -z, don't allow slow fallback\n"
" -p, -- ignored for backwards compatibility\n"
" -P, -- use different pattern to fill file\n"
" -C, -- report statistics in a machine parsable format\n"
@@ -964,7 +965,7 @@ static const cmdinfo_t write_cmd = {
.perm = BLK_PERM_WRITE,
.argmin = 2,
.argmax = -1,
- .args = "[-bcCfquz] [-P pattern] off len",
+ .args = "[-bcCfnquz] [-P pattern] off len",
.oneline = "writes a number of bytes at a specified offset",
.help = write_help,
};
@@ -983,7 +984,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
int64_t total = 0;
int pattern = 0xcd;
- while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) {
+ while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
switch (c) {
case 'b':
bflag = true;
@@ -997,6 +998,9 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
case 'f':
flags |= BDRV_REQ_FUA;
break;
+ case 'n':
+ flags |= BDRV_REQ_NO_FALLBACK;
+ break;
case 'p':
/* Ignored for backwards compatibility */
break;
@@ -1037,6 +1041,11 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
return -EINVAL;
}
+ if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
+ printf("-n requires -z to be specified\n");
+ return -EINVAL;
+ }
+
if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
printf("-u requires -z to be specified\n");
return -EINVAL;
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index 36d5829831..e0a1829b3d 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -121,58 +121,84 @@ qemu_seccomp(unsigned int operation, unsigned int flags, void *args)
#endif
}
-static uint32_t qemu_seccomp_get_kill_action(void)
+static uint32_t qemu_seccomp_get_action(int set)
{
+ switch (set) {
+ case QEMU_SECCOMP_SET_DEFAULT:
+ case QEMU_SECCOMP_SET_OBSOLETE:
+ case QEMU_SECCOMP_SET_PRIVILEGED:
+ case QEMU_SECCOMP_SET_SPAWN: {
#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \
defined(SECCOMP_RET_KILL_PROCESS)
- {
- uint32_t action = SECCOMP_RET_KILL_PROCESS;
+ static int kill_process = -1;
+ if (kill_process == -1) {
+ uint32_t action = SECCOMP_RET_KILL_PROCESS;
- if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
+ if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
+ kill_process = 1;
+ }
+ kill_process = 0;
+ }
+ if (kill_process == 1) {
return SCMP_ACT_KILL_PROCESS;
}
- }
#endif
+ return SCMP_ACT_TRAP;
+ }
- return SCMP_ACT_TRAP;
+ case QEMU_SECCOMP_SET_RESOURCECTL:
+ return SCMP_ACT_ERRNO(EPERM);
+
+ default:
+ g_assert_not_reached();
+ }
}
-static int seccomp_start(uint32_t seccomp_opts)
+static int seccomp_start(uint32_t seccomp_opts, Error **errp)
{
- int rc = 0;
+ int rc = -1;
unsigned int i = 0;
scmp_filter_ctx ctx;
- uint32_t action = qemu_seccomp_get_kill_action();
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL) {
- rc = -1;
+ error_setg(errp, "failed to initialize seccomp context");
goto seccomp_return;
}
rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1);
if (rc != 0) {
+ error_setg_errno(errp, -rc,
+ "failed to set seccomp thread synchronization");
goto seccomp_return;
}
for (i = 0; i < ARRAY_SIZE(blacklist); i++) {
+ uint32_t action;
if (!(seccomp_opts & blacklist[i].set)) {
continue;
}
+ action = qemu_seccomp_get_action(blacklist[i].set);
rc = seccomp_rule_add_array(ctx, action, blacklist[i].num,
blacklist[i].narg, blacklist[i].arg_cmp);
if (rc < 0) {
+ error_setg_errno(errp, -rc,
+ "failed to add seccomp blacklist rules");
goto seccomp_return;
}
}
rc = seccomp_load(ctx);
+ if (rc < 0) {
+ error_setg_errno(errp, -rc,
+ "failed to load seccomp syscall filter in kernel");
+ }
seccomp_return:
seccomp_release(ctx);
- return rc;
+ return rc < 0 ? -1 : 0;
}
#ifdef CONFIG_SECCOMP
@@ -242,9 +268,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
}
}
- if (seccomp_start(seccomp_opts) < 0) {
- error_setg(errp, "failed to install seccomp syscall filter "
- "in the kernel");
+ if (seccomp_start(seccomp_opts, errp) < 0) {
return -1;
}
}
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index a7df2093aa..632320d72d 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -266,7 +266,7 @@ static inline uint8_t next_state(JSONLexer *lexer, char ch, bool flush,
{
uint8_t next;
- assert(lexer->state <= ARRAY_SIZE(json_lexer));
+ assert(lexer->state < ARRAY_SIZE(json_lexer));
next = json_lexer[lexer->state][(uint8_t)ch];
*char_consumed = !flush && !(next & LOOKAHEAD);
return next & ~LOOKAHEAD;
diff --git a/scripts/minikconf.py b/scripts/minikconf.py
index 5421db0ed0..0ffc6c38da 100644
--- a/scripts/minikconf.py
+++ b/scripts/minikconf.py
@@ -592,7 +592,7 @@ class KconfigParser:
if not self.src.startswith(rest, self.cursor):
return False
length = len(rest)
- if self.src[self.cursor + length].isalnum() or self.src[self.cursor + length] == '|':
+ if self.src[self.cursor + length].isalnum() or self.src[self.cursor + length] == '_':
return False
self.cursor += length
return True
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 504a4771fb..4155782197 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2028,6 +2028,11 @@ static void arm_max_initfn(Object *obj)
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
cpu->isar.id_isar6 = t;
+ t = cpu->isar.mvfr2;
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
+ cpu->isar.mvfr2 = t;
+
t = cpu->id_mmfr4;
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
cpu->id_mmfr4 = t;
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 20b2d325d8..cd77f6b5d4 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -131,6 +131,17 @@ sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
{
int r;
struct kvm_enc_region range;
+ ram_addr_t offset;
+ MemoryRegion *mr;
+
+ /*
+ * The RAM device presents a memory region that should be treated
+ * as IO region and should not be pinned.
+ */
+ mr = memory_region_from_host(host, &offset);
+ if (mr && memory_region_is_ram_device(mr)) {
+ return;
+ }
range.addr = (__u64)(unsigned long)host;
range.size = size;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fc12b4688e..0707177584 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2409,6 +2409,12 @@ enum {
target_ulong cpu_read_xer(CPUPPCState *env);
void cpu_write_xer(CPUPPCState *env, target_ulong xer);
+/*
+ * All 64-bit server processors compliant with arch 2.x, ie. 970 and newer,
+ * have PPC_SEGMENT_64B.
+ */
+#define is_book3s_arch2x(ctx) (!!((ctx)->insns_flags & PPC_SEGMENT_64B))
+
static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *flags)
{
diff --git a/target/ppc/helper_regs.h b/target/ppc/helper_regs.h
index a2205e1044..c863abc0bf 100644
--- a/target/ppc/helper_regs.h
+++ b/target/ppc/helper_regs.h
@@ -152,7 +152,7 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
* - 64-bit embedded implementations do not need any operation to be
* performed when PR is set.
*/
- if ((env->insns_flags & PPC_SEGMENT_64B) && ((value >> MSR_PR) & 1)) {
+ if (is_book3s_arch2x(env) && ((value >> MSR_PR) & 1)) {
value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR);
}
#endif
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 98b37cebc2..badc1ae1a3 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -3747,20 +3747,52 @@ static void gen_bcond(DisasContext *ctx, int type)
if ((bo & 0x4) == 0) {
/* Decrement and test CTR */
TCGv temp = tcg_temp_new();
- if (unlikely(type == BCOND_CTR)) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(temp, cpu_ctr);
- } else {
- tcg_gen_mov_tl(temp, cpu_ctr);
- }
- if (bo & 0x2) {
- tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
+
+ if (type == BCOND_CTR) {
+ /*
+ * All ISAs up to v3 describe this form of bcctr as invalid but
+ * some processors, ie. 64-bit server processors compliant with
+ * arch 2.x, do implement a "test and decrement" logic instead,
+ * as described in their respective UMs. This logic involves CTR
+ * to act as both the branch target and a counter, which makes
+ * it basically useless and thus never used in real code.
+ *
+ * This form was hence chosen to trigger extra micro-architectural
+ * side-effect on real HW needed for the Spectre v2 workaround.
+ * It is up to guests that implement such workaround, ie. linux, to
+ * use this form in a way it just triggers the side-effect without
+ * doing anything else harmful.
+ */
+ if (unlikely(!is_book3s_arch2x(ctx))) {
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+ tcg_temp_free(temp);
+ tcg_temp_free(target);
+ return;
+ }
+
+ if (NARROW_MODE(ctx)) {
+ tcg_gen_ext32u_tl(temp, cpu_ctr);
+ } else {
+ tcg_gen_mov_tl(temp, cpu_ctr);
+ }
+ if (bo & 0x2) {
+ tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
+ } else {
+ tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+ }
+ tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
} else {
- tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+ tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
+ if (NARROW_MODE(ctx)) {
+ tcg_gen_ext32u_tl(temp, cpu_ctr);
+ } else {
+ tcg_gen_mov_tl(temp, cpu_ctr);
+ }
+ if (bo & 0x2) {
+ tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
+ } else {
+ tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+ }
}
tcg_temp_free(temp);
}
@@ -3889,7 +3921,7 @@ static void gen_rfi(DisasContext *ctx)
/* This instruction doesn't exist anymore on 64-bit server
* processors compliant with arch 2.x
*/
- if (ctx->insns_flags & PPC_SEGMENT_64B) {
+ if (is_book3s_arch2x(ctx)) {
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
return;
}
@@ -6511,8 +6543,7 @@ static void gen_msgclr(DisasContext *ctx)
GEN_PRIV;
#else
CHK_HV;
- /* 64-bit server processors compliant with arch 2.x */
- if (ctx->insns_flags & PPC_SEGMENT_64B) {
+ if (is_book3s_arch2x(ctx)) {
gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
} else {
gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
@@ -6526,8 +6557,7 @@ static void gen_msgsnd(DisasContext *ctx)
GEN_PRIV;
#else
CHK_HV;
- /* 64-bit server processors compliant with arch 2.x */
- if (ctx->insns_flags & PPC_SEGMENT_64B) {
+ if (is_book3s_arch2x(ctx)) {
gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]);
} else {
gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c
index 508e9199c8..489b2436e4 100644
--- a/target/ppc/translate/vsx-impl.inc.c
+++ b/target/ppc/translate/vsx-impl.inc.c
@@ -356,8 +356,8 @@ static void gen_##name(DisasContext *ctx) \
gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
gen_addr_reg_index(ctx, EA); \
+ get_cpu_vsrh(t0, xS(ctx->opcode)); \
gen_qemu_##operation(ctx, t0, EA); \
- set_cpu_vsrh(xS(ctx->opcode), t0); \
tcg_temp_free(EA); \
tcg_temp_free_i64(t0); \
}
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c
index 5819f53f90..ebcd977b2f 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -337,7 +337,7 @@ static bool trans_c_fswsp_sdsp(DisasContext *ctx, arg_c_fswsp_sdsp *a)
{
#ifdef TARGET_RISCV32
/* C.FSWSP */
- arg_fsw a_fsw = { .rs1 = a->rs2, .rs2 = 2, .imm = a->uimm_fswsp };
+ arg_fsw a_fsw = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm_fswsp };
return trans_fsw(ctx, &a_fsw);
#else
/* C.SDSP */
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c b/target/riscv/insn_trans/trans_rvm.inc.c
index 204af225f8..47cd6edc72 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -103,7 +103,7 @@ static bool trans_divw(DisasContext *ctx, arg_divw *a)
static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
{
REQUIRE_EXT(ctx, RVM);
- return gen_arith_div_w(ctx, a, &gen_divu);
+ return gen_arith_div_uw(ctx, a, &gen_divu);
}
static bool trans_remw(DisasContext *ctx, arg_remw *a)
@@ -115,6 +115,6 @@ static bool trans_remw(DisasContext *ctx, arg_remw *a)
static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
{
REQUIRE_EXT(ctx, RVM);
- return gen_arith_div_w(ctx, a, &gen_remu);
+ return gen_arith_div_uw(ctx, a, &gen_remu);
}
#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 049fa65c66..dd763647ea 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -600,6 +600,27 @@ static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
return true;
}
+static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
+ void(*func)(TCGv, TCGv, TCGv))
+{
+ TCGv source1, source2;
+ source1 = tcg_temp_new();
+ source2 = tcg_temp_new();
+
+ gen_get_gpr(source1, a->rs1);
+ gen_get_gpr(source2, a->rs2);
+ tcg_gen_ext32u_tl(source1, source1);
+ tcg_gen_ext32u_tl(source2, source2);
+
+ (*func)(source1, source1, source2);
+
+ tcg_gen_ext32s_tl(source1, source1);
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ tcg_temp_free(source2);
+ return true;
+}
+
#endif
static bool gen_arith(DisasContext *ctx, arg_r *a,
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 77bc04d6b0..65561d2c49 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -1041,7 +1041,6 @@ static bool break_dependency(struct slot_prop *a,
copy[n].resource = b->in[j].resource;
copy[n].arg = b->arg + index;
++n;
- ++i;
++j;
rv = true;
}
diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c
index 2f76216276..5f5ce4f344 100644
--- a/target/xtensa/xtensa-semi.c
+++ b/target/xtensa/xtensa-semi.c
@@ -202,7 +202,6 @@ void HELPER(simcall)(CPUXtensaState *env)
switch (regs[2]) {
case TARGET_SYS_exit:
- qemu_log("exit(%d) simcall\n", regs[3]);
exit(regs[3]);
break;
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 852f17b8c7..6b904d7430 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -195,7 +195,6 @@ check-qtest-i386-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
check-qtest-i386-$(CONFIG_POSIX) += tests/test-filter-mirror$(EXESUF)
check-qtest-i386-$(CONFIG_RTL8139_PCI) += tests/test-filter-redirector$(EXESUF)
check-qtest-i386-y += tests/migration-test$(EXESUF)
-check-qtest-i386-y += tests/test-announce-self$(EXESUF)
check-qtest-i386-y += tests/test-x86-cpuid-compat$(EXESUF)
check-qtest-i386-y += tests/numa-test$(EXESUF)
check-qtest-x86_64-y += $(check-qtest-i386-y)
@@ -232,7 +231,6 @@ check-qtest-ppc64-y += $(check-qtest-ppc-y)
check-qtest-ppc64-$(CONFIG_PSERIES) += tests/device-plug-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_POWERNV) += tests/pnv-xscom-test$(EXESUF)
check-qtest-ppc64-y += tests/migration-test$(EXESUF)
-check-qtest-ppc64-y += tests/test-announce-self$(EXESUF)
check-qtest-ppc64-$(CONFIG_PSERIES) += tests/rtas-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_USB_UHCI) += tests/usb-hcd-uhci-test$(EXESUF)
@@ -817,7 +815,6 @@ tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y)
tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
tests/cpu-plug-test$(EXESUF): tests/cpu-plug-test.o
tests/migration-test$(EXESUF): tests/migration-test.o
-tests/test-announce-self$(EXESUF): tests/test-announce-self.o
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
tests/test-keyval$(EXESUF): tests/test-keyval.o $(test-util-obj-y) $(test-qapi-obj-y)
diff --git a/tests/qemu-iotests/248 b/tests/qemu-iotests/248
new file mode 100755
index 0000000000..f26b4bb2aa
--- /dev/null
+++ b/tests/qemu-iotests/248
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# Test resume mirror after auto pause on ENOSPC
+#
+# Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved.
+#
+# This program 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/>.
+#
+
+import iotests
+from iotests import qemu_img_create, qemu_io, file_path, filter_qmp_testfiles
+
+iotests.verify_image_format(supported_fmts=['qcow2'])
+
+source, target = file_path('source', 'target')
+size = 5 * 1024 * 1024
+limit = 2 * 1024 * 1024
+
+qemu_img_create('-f', iotests.imgfmt, source, str(size))
+qemu_img_create('-f', iotests.imgfmt, target, str(size))
+qemu_io('-c', 'write 0 {}'.format(size), source)
+
+# raw format don't like empty files
+qemu_io('-c', 'write 0 {}'.format(size), target)
+
+vm = iotests.VM().add_drive(source)
+vm.launch()
+
+blockdev_opts = {
+ 'driver': iotests.imgfmt,
+ 'node-name': 'target',
+ 'file': {
+ 'driver': 'raw',
+ 'size': limit,
+ 'file': {
+ 'driver': 'file',
+ 'filename': target
+ }
+ }
+}
+vm.qmp_log('blockdev-add', filters=[filter_qmp_testfiles], **blockdev_opts)
+
+vm.qmp_log('blockdev-mirror', device='drive0', sync='full', target='target',
+ on_target_error='enospc')
+
+vm.event_wait('JOB_STATUS_CHANGE', timeout=3.0,
+ match={'data': {'status': 'paused'}})
+
+# drop other cached events, to not interfere with further wait for 'running'
+vm.get_qmp_events()
+
+del blockdev_opts['file']['size']
+vm.qmp_log('x-blockdev-reopen', filters=[filter_qmp_testfiles],
+ **blockdev_opts)
+
+vm.qmp_log('block-job-resume', device='drive0')
+vm.event_wait('JOB_STATUS_CHANGE', timeout=1.0,
+ match={'data': {'status': 'running'}})
+
+vm.shutdown()
diff --git a/tests/qemu-iotests/248.out b/tests/qemu-iotests/248.out
new file mode 100644
index 0000000000..369b25bf26
--- /dev/null
+++ b/tests/qemu-iotests/248.out
@@ -0,0 +1,8 @@
+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}, "size": 2097152}, "node-name": "target"}}
+{"return": {}}
+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "on-target-error": "enospc", "sync": "full", "target": "target"}}
+{"return": {}}
+{"execute": "x-blockdev-reopen", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}}, "node-name": "target"}}
+{"return": {}}
+{"execute": "block-job-resume", "arguments": {"device": "drive0"}}
+{"return": {}}
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index d192abaecf..41da10c6cf 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -246,3 +246,4 @@
245 rw auto
246 rw auto quick
247 rw auto quick
+248 rw auto quick
diff --git a/tests/tcg/xtensa/Makefile.softmmu-target b/tests/tcg/xtensa/Makefile.softmmu-target
index 86bb47db77..8212d96b81 100644
--- a/tests/tcg/xtensa/Makefile.softmmu-target
+++ b/tests/tcg/xtensa/Makefile.softmmu-target
@@ -8,7 +8,7 @@ XTENSA_SRC = $(SRC_PATH)/tests/tcg/xtensa
XTENSA_ALL = $(filter-out $(XTENSA_SRC)/linker.ld.S,$(wildcard $(XTENSA_SRC)/*.S))
XTENSA_TESTS = $(patsubst $(XTENSA_SRC)/%.S, %, $(XTENSA_ALL))
# Filter out common blobs and broken tests
-XTENSA_BROKEN_TESTS = crt vectors test_boolean test_pipeline test_fail
+XTENSA_BROKEN_TESTS = crt vectors
XTENSA_USABLE_TESTS = $(filter-out $(XTENSA_BROKEN_TESTS), $(XTENSA_TESTS))
# add to the list of tests
diff --git a/tests/tcg/xtensa/test_fail.S b/tests/tcg/xtensa/test_fail.S
deleted file mode 100644
index 1c26d50790..0000000000
--- a/tests/tcg/xtensa/test_fail.S
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "macros.inc"
-
-test_suite fail
-
-test fail
- test_fail
-test_end
-
-test_suite_end
diff --git a/tests/tcg/xtensa/test_flix.S b/tests/tcg/xtensa/test_flix.S
index 7c259e7018..7af06b2b88 100644
--- a/tests/tcg/xtensa/test_flix.S
+++ b/tests/tcg/xtensa/test_flix.S
@@ -55,6 +55,23 @@ test sum
.previous
test_end
+test rep_dependency
+
+ {
+ movi a2, 1
+ movi a3, 2
+ nop
+ }
+ {
+ or a2, a3, a3
+ or a3, a2, a2
+ nop
+ }
+ assert eqi, a2, 2
+ assert eqi, a3, 1
+
+test_end
+
#endif
test_suite_end
diff --git a/tests/tcg/xtensa/test_pipeline.S b/tests/tcg/xtensa/test_pipeline.S
deleted file mode 100644
index f418c11974..0000000000
--- a/tests/tcg/xtensa/test_pipeline.S
+++ /dev/null
@@ -1,157 +0,0 @@
-#include "macros.inc"
-
-.purgem test
-.macro test name
- movi a2, 1f
- movi a3, 99f
-0:
- ipf a2, 0
- ipf a2, 4
- ipf a2, 8
- ipf a2, 12
- addi a2, a2, 16
- blt a2, a3, 0b
- j 1f
- .align 4
-1:
-.endm
-
-test_suite pipeline
-
-test register_no_stall
- rsr a3, ccount
- add a5, a6, a6
- add a6, a5, a5
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 3
-test_end
-
-test register_stall
- l32i a5, a1, 0 /* data cache preload */
- nop
- rsr a3, ccount
- l32i a5, a1, 0
- add a6, a5, a5 /* M-to-E interlock */
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 4
-test_end
-
-test j0_stall
- rsr a3, ccount
- j 1f /* E + 2-cycle penalty */
-1:
- rsr a4, ccount /* E */
- sub a3, a4, a3
- assert eqi, a3, 4
-test_end
-
-test j1_stall
- rsr a3, ccount
- j 1f
- nop
-1:
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 4
-test_end
-
-test j5_stall
- rsr a3, ccount
- j 1f
- nop
- nop
- nop
- nop
- nop
-1:
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 4
-test_end
-
-test b_no_stall
- movi a5, 1
- rsr a3, ccount
- beqi a5, 2, 1f
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 2
-1:
-test_end
-
-test b1_stall
- movi a5, 1
- rsr a3, ccount
- beqi a5, 1, 1f
- nop
-1:
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 4
-test_end
-
-test b5_stall
- movi a5, 1
- rsr a3, ccount
- beqi a5, 1, 1f
- nop
- nop
- nop
- nop
- nop
-1:
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 4
-test_end
-
-/* PS *SYNC */
-
-test ps_dsync
- rsr a5, ps
- isync
- rsr a3, ccount
- wsr a5, ps
- dsync
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 5
-test_end
-
-test ps_esync
- rsr a5, ps
- isync
- rsr a3, ccount
- wsr a5, ps
- esync
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 5
-test_end
-
-test ps_rsync
- rsr a5, ps
- isync
- rsr a3, ccount
- wsr a5, ps
- rsync
- rsr a4, ccount
- sub a3, a4, a3
- assert eqi, a3, 5
-test_end
-
-test ps_isync
- rsr a5, ps
- isync
- rsr a3, ccount
- wsr a5, ps
- isync
- rsr a4, ccount
- sub a3, a4, a3
- movi a4, 9
- assert eq, a3, a4
-test_end
-
-test_suite_end
diff --git a/tests/test-announce-self.c b/tests/test-announce-self.c
deleted file mode 100644
index 0e6d466aa4..0000000000
--- a/tests/test-announce-self.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * QTest testcase for qemu_announce_self
- *
- * Copyright (c) 2017 Red hat, Inc.
- * Copyright (c) 2014 SUSE LINUX Products GmbH
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "libqtest.h"
-#include "qapi/qmp/qdict.h"
-#include "qemu-common.h"
-#include "qemu/sockets.h"
-#include "qemu/iov.h"
-#include "libqos/libqos-pc.h"
-#include "libqos/libqos-spapr.h"
-
-#ifndef ETH_P_RARP
-#define ETH_P_RARP 0x8035
-#endif
-
-
-static void test_announce(QTestState *qs, int socket)
-{
- char buffer[60];
- int len;
- QDict *rsp;
- int ret;
- uint16_t *proto = (uint16_t *)&buffer[12];
-
- rsp = qtest_qmp(qs, "{ 'execute' : 'announce-self', "
- " 'arguments': {"
- " 'initial': 50, 'max': 550,"
- " 'rounds': 10, 'step': 50 } }");
- assert(!qdict_haskey(rsp, "error"));
- qobject_unref(rsp);
-
- /* Catch the packet and make sure it's a RARP */
- ret = qemu_recv(socket, &len, sizeof(len), 0);
- g_assert_cmpint(ret, ==, sizeof(len));
- len = ntohl(len);
-
- ret = qemu_recv(socket, buffer, len, 0);
- g_assert_cmpint(*proto, ==, htons(ETH_P_RARP));
-}
-
-static void setup(gconstpointer data)
-{
- QTestState *qs;
- void (*func) (QTestState *qs, int socket) = data;
- int sv[2], ret;
-
- ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
- g_assert_cmpint(ret, !=, -1);
-
- qs = qtest_initf("-netdev socket,fd=%d,id=hs0 -device "
- "virtio-net-pci,netdev=hs0", sv[1]);
- func(qs, sv[0]);
-
- /* End test */
- close(sv[0]);
- qtest_quit(qs);
-}
-
-int main(int argc, char **argv)
-{
- g_test_init(&argc, &argv, NULL);
- qtest_add_data_func("/virtio/net/test_announce_self", test_announce, setup);
-
- return g_test_run();
-}
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
index c58e670e2f..0d956f36fe 100644
--- a/tests/virtio-net-test.c
+++ b/tests/virtio-net-test.c
@@ -15,6 +15,10 @@
#include "libqos/qgraph.h"
#include "libqos/virtio-net.h"
+#ifndef ETH_P_RARP
+#define ETH_P_RARP 0x8035
+#endif
+
#define PCI_SLOT_HP 0x06
#define PCI_SLOT 0x04
@@ -168,6 +172,31 @@ static void hotplug(void *obj, void *data, QGuestAllocator *t_alloc)
}
}
+static void announce_self(void *obj, void *data, QGuestAllocator *t_alloc)
+{
+ int *sv = data;
+ char buffer[60];
+ int len;
+ QDict *rsp;
+ int ret;
+ uint16_t *proto = (uint16_t *)&buffer[12];
+
+ rsp = qmp("{ 'execute' : 'announce-self', "
+ " 'arguments': {"
+ " 'initial': 50, 'max': 550,"
+ " 'rounds': 10, 'step': 50 } }");
+ assert(!qdict_haskey(rsp, "error"));
+ qobject_unref(rsp);
+
+ /* Catch the packet and make sure it's a RARP */
+ ret = qemu_recv(sv[0], &len, sizeof(len), 0);
+ g_assert_cmpint(ret, ==, sizeof(len));
+ len = ntohl(len);
+
+ ret = qemu_recv(sv[0], buffer, len, 0);
+ g_assert_cmpint(*proto, ==, htons(ETH_P_RARP));
+}
+
static void virtio_net_test_cleanup(void *sockets)
{
int *sv = sockets;
@@ -233,6 +262,7 @@ static void register_virtio_net_test(void)
qos_add_test("basic", "virtio-net", send_recv_test, &opts);
qos_add_test("rx_stop_cont", "virtio-net", stop_cont_test, &opts);
#endif
+ qos_add_test("announce-self", "virtio-net", announce_self, &opts);
/* These tests do not need a loopback backend. */
opts.before = virtio_net_test_setup_nosocket;
diff --git a/util/error.c b/util/error.c
index b5ccbd8eac..934a78e1b1 100644
--- a/util/error.c
+++ b/util/error.c
@@ -103,10 +103,6 @@ void error_setg_errno_internal(Error **errp,
va_list ap;
int saved_errno = errno;
- if (errp == NULL) {
- return;
- }
-
va_start(ap, fmt);
error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap,
os_errno != 0 ? strerror(os_errno) : NULL);