|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [qemu-xen stable-4.12] Merge tag 'v3.0.1' into staging-4.12
=== This changeset includes merge from high-traffic branch ===
Commits on that branch are not reported individually.
commit 8023a62081ffbe3f734019076ec1a2b4213142bb
Merge: a55e2eca4b45108c9ffa4ab6f6068cd2e8501654
1dfcf652e6ae5eb6b98d2c55a509e8eb054a2fab
Author: Anthony PERARD <anthony.perard@xxxxxxxxxx>
AuthorDate: Tue Apr 16 10:52:53 2019 +0100
Commit: Anthony PERARD <anthony.perard@xxxxxxxxxx>
CommitDate: Tue Apr 16 10:52:53 2019 +0100
Merge tag 'v3.0.1' into staging-4.12
3.0.1
VERSION | 2 +-
block.c | 2 +
block/block-backend.c | 3 +
block/mirror.c | 18 +++---
block/nbd-client.c | 22 ++++++-
block/nvme.c | 37 ++++--------
block/qapi.c | 3 +-
block/rbd.c | 90 ++++++++++++++++++++++++-----
configure | 7 +--
exec.c | 10 ++--
hw/acpi/piix4.c | 1 +
hw/arm/virt.c | 2 +
hw/audio/fmopl.h | 4 +-
hw/block/fdc.c | 2 +-
hw/char/virtio-serial-bus.c | 6 +-
hw/i2c/bitbang_i2c.h | 2 -
hw/i2c/smbus.c | 6 +-
hw/i386/acpi-build.c | 85 +++++++--------------------
hw/i386/intel_iommu.c | 34 +++++++----
hw/net/ne2000.c | 4 +-
hw/net/pcnet.c | 4 +-
hw/net/rtl8139.c | 8 +--
hw/pci/pcie.c | 12 ++++
hw/ppc/pnv_lpc.c | 8 ++-
hw/ppc/spapr_cpu_core.c | 62 ++++++++++----------
hw/rdma/rdma_rm_defs.h | 4 +-
hw/scsi/lsi53c895a.c | 19 +++++-
hw/scsi/vhost-scsi.c | 2 +-
hw/tpm/tpm_emulator.c | 1 +
hw/tpm/tpm_tis.c | 10 +++-
hw/usb/dev-mtp.c | 19 ++++--
hw/virtio/vhost-user.c | 20 +++----
hw/virtio/vhost.c | 4 +-
hw/virtio/virtio.c | 17 +++++-
include/block/nbd.h | 4 +-
include/hw/i2c/i2c.h | 2 +
include/hw/i2c/ppc4xx_i2c.h | 3 -
include/hw/s390x/tod.h | 2 +-
job.c | 20 ++-----
linux-user/syscall.c | 44 ++++++++++----
migration/postcopy-ram.c | 11 ++--
monitor.c | 2 +
nbd/server.c | 9 ++-
net/slirp.c | 9 +++
qemu-deprecated.texi | 15 +++++
qemu-img.c | 35 ++++++-----
qemu-seccomp.c | 36 +++++++++++-
qga/qapi-schema.json | 25 ++++----
scripts/make-release | 1 +
slirp/bootp.c | 32 ++++++----
slirp/tcp_subr.c | 15 +++--
target/arm/cpu.c | 6 +-
target/arm/cpu.h | 5 +-
target/arm/cpu64.c | 29 ++++++++++
target/arm/helper.c | 55 +++++++++++-------
target/arm/sve_helper.c | 23 +++-----
target/arm/translate-a64.c | 106 ++++++++++++++++++++++++++++------
target/arm/translate-sve.c | 81 +++++++++++++++-----------
target/i386/cpu.c | 6 ++
target/ppc/translate/vmx-ops.inc.c | 2 +-
target/s390x/diag.c | 2 +-
target/xtensa/translate.c | 8 +--
tests/acpi-test-data/pc/DSDT | Bin 5144 -> 5131 bytes
tests/acpi-test-data/pc/DSDT.bridge | Bin 7003 -> 6990 bytes
tests/acpi-test-data/pc/DSDT.cphp | Bin 5607 -> 5594 bytes
tests/acpi-test-data/pc/DSDT.dimmpxm | Bin 6803 -> 6790 bytes
tests/acpi-test-data/pc/DSDT.ipmikcs | Bin 5216 -> 5203 bytes
tests/acpi-test-data/pc/DSDT.memhp | Bin 6509 -> 6496 bytes
tests/acpi-test-data/pc/DSDT.numamem | Bin 5150 -> 5137 bytes
tests/acpi-test-data/pc/SRAT.dimmpxm | Bin 472 -> 392 bytes
tests/acpi-test-data/pc/SRAT.memhp | Bin 264 -> 264 bytes
tests/acpi-test-data/q35/DSDT | Bin 7828 -> 7815 bytes
tests/acpi-test-data/q35/DSDT.bridge | Bin 7845 -> 7832 bytes
tests/acpi-test-data/q35/DSDT.cphp | Bin 8291 -> 8278 bytes
tests/acpi-test-data/q35/DSDT.dimmpxm | Bin 9487 -> 9474 bytes
tests/acpi-test-data/q35/DSDT.ipmibt | Bin 7903 -> 7890 bytes
tests/acpi-test-data/q35/DSDT.memhp | Bin 9193 -> 9180 bytes
tests/acpi-test-data/q35/DSDT.numamem | Bin 7834 -> 7821 bytes
tests/acpi-test-data/q35/SRAT.dimmpxm | Bin 472 -> 392 bytes
tests/acpi-test-data/q35/SRAT.memhp | Bin 264 -> 264 bytes
tests/qemu-iotests/041 | 6 ++
tests/qemu-iotests/041.out | 4 +-
tests/qemu-iotests/067.out | 1 +
tests/qemu-iotests/229 | 95 ++++++++++++++++++++++++++++++
tests/qemu-iotests/229.out | 23 ++++++++
tests/qemu-iotests/231 | 62 ++++++++++++++++++++
tests/qemu-iotests/231.out | 9 +++
tests/qemu-iotests/235 | 78 +++++++++++++++++++++++++
tests/qemu-iotests/235.out | 3 +
tests/qemu-iotests/group | 3 +
ui/vnc-jobs.c | 3 +-
util/aio-posix.c | 7 ++-
util/aio-win32.c | 3 +-
util/hbitmap.c | 3 +
util/vfio-helpers.c | 2 +-
vl.c | 1 +
96 files changed, 1026 insertions(+), 395 deletions(-)
diff --git a/VERSION b/VERSION
index 4a36342fca..cb2b00e4f7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.0.0
+3.0.1
diff --git a/block.c b/block.c
index 39f373e035..50b9bd695d 100644
--- a/block.c
+++ b/block.c
@@ -2787,6 +2787,7 @@ static BlockDriverState *bdrv_open_inherit(const char
*filename,
bdrv_parent_cb_change_media(bs, true);
qobject_unref(options);
+ options = NULL;
/* For snapshot=on, create a temporary qcow2 overlay. bs points to the
* temporary snapshot afterwards. */
@@ -4394,6 +4395,7 @@ static void coroutine_fn
bdrv_co_invalidate_cache(BlockDriverState *bs,
if (parent->role->activate) {
parent->role->activate(parent, &local_err);
if (local_err) {
+ bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
return;
}
diff --git a/block/block-backend.c b/block/block-backend.c
index f2f75a977d..1b27a68ae7 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -324,6 +324,9 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
blk->shared_perm = shared_perm;
blk_set_enable_write_cache(blk, true);
+ blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT;
+ blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
+
block_acct_init(&blk->stats);
notifier_list_init(&blk->remove_bs_notifiers);
diff --git a/block/mirror.c b/block/mirror.c
index b48c3f8cf5..b097853983 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -198,7 +198,6 @@ static void coroutine_fn mirror_write_complete(MirrorOp
*op, int ret)
{
MirrorBlockJob *s = op->s;
- aio_context_acquire(blk_get_aio_context(s->common.blk));
if (ret < 0) {
BlockErrorAction action;
@@ -208,15 +207,14 @@ static void coroutine_fn mirror_write_complete(MirrorOp
*op, int ret)
s->ret = ret;
}
}
+
mirror_iteration_done(op, ret);
- aio_context_release(blk_get_aio_context(s->common.blk));
}
static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret)
{
MirrorBlockJob *s = op->s;
- aio_context_acquire(blk_get_aio_context(s->common.blk));
if (ret < 0) {
BlockErrorAction action;
@@ -227,12 +225,11 @@ static void coroutine_fn mirror_read_complete(MirrorOp
*op, int ret)
}
mirror_iteration_done(op, ret);
- } else {
- ret = blk_co_pwritev(s->target, op->offset,
- op->qiov.size, &op->qiov, 0);
- mirror_write_complete(op, ret);
+ return;
}
- aio_context_release(blk_get_aio_context(s->common.blk));
+
+ ret = blk_co_pwritev(s->target, op->offset, op->qiov.size, &op->qiov, 0);
+ mirror_write_complete(op, ret);
}
/* Clip bytes relative to offset to not exceed end-of-file */
@@ -1499,6 +1496,11 @@ static void mirror_start_job(const char *job_id,
BlockDriverState *bs,
buf_size = DEFAULT_MIRROR_BUF_SIZE;
}
+ if (bs == target) {
+ error_setg(errp, "Can't mirror node into itself");
+ return;
+ }
+
/* In the case of active commit, add dummy driver to provide consistent
* reads on the top, while disabling it in the intermediate nodes, and make
* the backing chain writable. */
diff --git a/block/nbd-client.c b/block/nbd-client.c
index 9686ecbd5e..1b7b5b0a88 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -992,11 +992,18 @@ int nbd_client_init(BlockDriverState *bs,
logout("Failed to negotiate with the NBD server\n");
return ret;
}
+ if (x_dirty_bitmap && !client->info.base_allocation) {
+ error_setg(errp, "requested x-dirty-bitmap %s not found",
+ x_dirty_bitmap);
+ ret = -EINVAL;
+ goto fail;
+ }
if (client->info.flags & NBD_FLAG_READ_ONLY &&
!bdrv_is_read_only(bs)) {
error_setg(errp,
"request for write access conflicts with read-only export");
- return -EACCES;
+ ret = -EACCES;
+ goto fail;
}
if (client->info.flags & NBD_FLAG_SEND_FUA) {
bs->supported_write_flags = BDRV_REQ_FUA;
@@ -1024,4 +1031,17 @@ int nbd_client_init(BlockDriverState *bs,
logout("Established connection with NBD server\n");
return 0;
+
+ fail:
+ /*
+ * We have connected, but must fail for other reasons. The
+ * connection is still blocking; send NBD_CMD_DISC as a courtesy
+ * to the server.
+ */
+ {
+ NBDRequest request = { .type = NBD_CMD_DISC };
+
+ nbd_send_request(client->ioc ?: QIO_CHANNEL(sioc), &request);
+ return ret;
+ }
}
diff --git a/block/nvme.c b/block/nvme.c
index 6f71122bf5..37805e8890 100644
--- a/block/nvme.c
+++ b/block/nvme.c
@@ -569,13 +569,13 @@ static int nvme_init(BlockDriverState *bs, const char
*device, int namespace,
s->vfio = qemu_vfio_open_pci(device, errp);
if (!s->vfio) {
ret = -EINVAL;
- goto fail;
+ goto out;
}
s->regs = qemu_vfio_pci_map_bar(s->vfio, 0, 0, NVME_BAR_SIZE, errp);
if (!s->regs) {
ret = -EINVAL;
- goto fail;
+ goto out;
}
/* Perform initialize sequence as described in NVMe spec "7.6.1
@@ -585,7 +585,7 @@ static int nvme_init(BlockDriverState *bs, const char
*device, int namespace,
if (!(cap & (1ULL << 37))) {
error_setg(errp, "Device doesn't support NVMe command set");
ret = -EINVAL;
- goto fail;
+ goto out;
}
s->page_size = MAX(4096, 1 << (12 + ((cap >> 48) & 0xF)));
@@ -603,7 +603,7 @@ static int nvme_init(BlockDriverState *bs, const char
*device, int namespace,
PRId64 " ms)",
timeout_ms);
ret = -ETIMEDOUT;
- goto fail;
+ goto out;
}
}
@@ -613,7 +613,7 @@ static int nvme_init(BlockDriverState *bs, const char
*device, int namespace,
s->queues[0] = nvme_create_queue_pair(bs, 0, NVME_QUEUE_SIZE, errp);
if (!s->queues[0]) {
ret = -EINVAL;
- goto fail;
+ goto out;
}
QEMU_BUILD_BUG_ON(NVME_QUEUE_SIZE & 0xF000);
s->regs->aqa = cpu_to_le32((NVME_QUEUE_SIZE << 16) | NVME_QUEUE_SIZE);
@@ -633,14 +633,14 @@ static int nvme_init(BlockDriverState *bs, const char
*device, int namespace,
PRId64 " ms)",
timeout_ms);
ret = -ETIMEDOUT;
- goto fail_queue;
+ goto out;
}
}
ret = qemu_vfio_pci_init_irq(s->vfio, &s->irq_notifier,
VFIO_PCI_MSIX_IRQ_INDEX, errp);
if (ret) {
- goto fail_queue;
+ goto out;
}
aio_set_event_notifier(bdrv_get_aio_context(bs), &s->irq_notifier,
false, nvme_handle_event, nvme_poll_cb);
@@ -649,30 +649,15 @@ static int nvme_init(BlockDriverState *bs, const char
*device, int namespace,
if (local_err) {
error_propagate(errp, local_err);
ret = -EIO;
- goto fail_handler;
+ goto out;
}
/* Set up command queues. */
if (!nvme_add_io_queue(bs, errp)) {
ret = -EIO;
- goto fail_handler;
}
- return 0;
-
-fail_handler:
- aio_set_event_notifier(bdrv_get_aio_context(bs), &s->irq_notifier,
- false, NULL, NULL);
-fail_queue:
- nvme_free_queue_pair(bs, s->queues[0]);
-fail:
- g_free(s->queues);
- if (s->regs) {
- qemu_vfio_pci_unmap_bar(s->vfio, 0, (void *)s->regs, 0, NVME_BAR_SIZE);
- }
- if (s->vfio) {
- qemu_vfio_close(s->vfio);
- }
- event_notifier_cleanup(&s->irq_notifier);
+out:
+ /* Cleaning up is done in nvme_file_open() upon error. */
return ret;
}
@@ -739,8 +724,10 @@ static void nvme_close(BlockDriverState *bs)
for (i = 0; i < s->nr_queues; ++i) {
nvme_free_queue_pair(bs, s->queues[i]);
}
+ g_free(s->queues);
aio_set_event_notifier(bdrv_get_aio_context(bs), &s->irq_notifier,
false, NULL, NULL);
+ event_notifier_cleanup(&s->irq_notifier);
qemu_vfio_pci_unmap_bar(s->vfio, 0, (void *)s->regs, 0, NVME_BAR_SIZE);
qemu_vfio_close(s->vfio);
}
diff --git a/block/qapi.c b/block/qapi.c
index 339727f0f4..c66f949db8 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -594,7 +594,7 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
}
} else {
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
- BlockStatsList *info = g_malloc0(sizeof(*info));
+ BlockStatsList *info;
AioContext *ctx = blk_get_aio_context(blk);
BlockStats *s;
char *qdev;
@@ -619,6 +619,7 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
bdrv_query_blk_stats(s->stats, blk);
aio_context_release(ctx);
+ info = g_malloc0(sizeof(*info));
info->value = s;
*p_next = info;
p_next = &info->next;
diff --git a/block/rbd.c b/block/rbd.c
index ca8e5bbace..014c68d629 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -655,12 +655,61 @@ failed_opts:
return r;
}
+static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts,
+ Error **errp)
+{
+ Visitor *v;
+ Error *local_err = NULL;
+
+ /* Convert the remaining options into a QAPI object */
+ v = qobject_input_visitor_new_flat_confused(options, errp);
+ if (!v) {
+ return -EINVAL;
+ }
+
+ visit_type_BlockdevOptionsRbd(v, NULL, opts, &local_err);
+ visit_free(v);
+
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int qemu_rbd_attempt_legacy_options(QDict *options,
+ BlockdevOptionsRbd **opts,
+ char **keypairs)
+{
+ char *filename;
+ int r;
+
+ filename = g_strdup(qdict_get_try_str(options, "filename"));
+ if (!filename) {
+ return -EINVAL;
+ }
+ qdict_del(options, "filename");
+
+ qemu_rbd_parse_filename(filename, options, NULL);
+
+ /* keypairs freed by caller */
+ *keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs"));
+ if (*keypairs) {
+ qdict_del(options, "=keyvalue-pairs");
+ }
+
+ r = qemu_rbd_convert_options(options, opts, NULL);
+
+ g_free(filename);
+ return r;
+}
+
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
BDRVRBDState *s = bs->opaque;
BlockdevOptionsRbd *opts = NULL;
- Visitor *v;
const QDictEntry *e;
Error *local_err = NULL;
char *keypairs, *secretid;
@@ -676,20 +725,33 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict
*options, int flags,
qdict_del(options, "password-secret");
}
- /* Convert the remaining options into a QAPI object */
- v = qobject_input_visitor_new_flat_confused(options, errp);
- if (!v) {
- r = -EINVAL;
- goto out;
- }
-
- visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err);
- visit_free(v);
-
+ r = qemu_rbd_convert_options(options, &opts, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- r = -EINVAL;
- goto out;
+ /* If keypairs are present, that means some options are present in
+ * the modern option format. Don't attempt to parse legacy option
+ * formats, as we won't support mixed usage. */
+ if (keypairs) {
+ error_propagate(errp, local_err);
+ goto out;
+ }
+
+ /* If the initial attempt to convert and process the options failed,
+ * we may be attempting to open an image file that has the rbd options
+ * specified in the older format consisting of all key/value pairs
+ * encoded in the filename. Go ahead and attempt to parse the
+ * filename, and see if we can pull out the required options. */
+ r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs);
+ if (r < 0) {
+ /* Propagate the original error, not the legacy parsing fallback
+ * error, as the latter was just a best-effort attempt. */
+ error_propagate(errp, local_err);
+ goto out;
+ }
+ /* Take care whenever deciding to actually deprecate; once this ability
+ * is removed, we will not be able to open any images with
legacy-styled
+ * backing image strings. */
+ error_report("RBD options encoded in the filename as keyvalue pairs "
+ "is deprecated");
}
/* Remove the processed options from the QDict (the visitor processes
diff --git a/configure b/configure
index a8b707a670..98870f56ec 100755
--- a/configure
+++ b/configure
@@ -2224,13 +2224,10 @@ fi
##########################################
# libseccomp check
+libseccomp_minver="2.2.0"
if test "$seccomp" != "no" ; then
case "$cpu" in
- i386|x86_64)
- libseccomp_minver="2.1.0"
- ;;
- mips)
- libseccomp_minver="2.2.0"
+ i386|x86_64|mips)
;;
arm|aarch64)
libseccomp_minver="2.2.3"
diff --git a/exec.c b/exec.c
index 4f5df07b6a..9bafcb155a 100644
--- a/exec.c
+++ b/exec.c
@@ -690,7 +690,7 @@ static void tcg_register_iommu_notifier(CPUState *cpu,
int i;
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
if (notifier->mr == mr && notifier->iommu_idx == iommu_idx) {
break;
}
@@ -698,7 +698,8 @@ static void tcg_register_iommu_notifier(CPUState *cpu,
if (i == cpu->iommu_notifiers->len) {
/* Not found, add a new entry at the end of the array */
cpu->iommu_notifiers = g_array_set_size(cpu->iommu_notifiers, i + 1);
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
+ notifier = g_new0(TCGIOMMUNotifier, 1);
+ g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i) = notifier;
notifier->mr = mr;
notifier->iommu_idx = iommu_idx;
@@ -730,8 +731,9 @@ static void tcg_iommu_free_notifier_list(CPUState *cpu)
TCGIOMMUNotifier *notifier;
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
memory_region_unregister_iommu_notifier(notifier->mr, ¬ifier->n);
+ g_free(notifier);
}
g_array_free(cpu->iommu_notifiers, true);
}
@@ -1000,7 +1002,7 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
}
- cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier));
+ cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier
*));
#endif
}
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 6404af5f33..7ae6d14b46 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -173,6 +173,7 @@ static int vmstate_acpi_post_load(void *opaque, int
version_id)
PIIX4PMState *s = opaque;
pm_io_space_update(s);
+ smbus_io_space_update(s);
return 0;
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 281ddcdf6e..7f234ff6e8 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1881,6 +1881,8 @@ static void virt_machine_2_10_options(MachineClass *mc)
{
virt_machine_2_11_options(mc);
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_10);
+ /* before 2.11 we never faulted accesses to bad addresses */
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_VIRT_MACHINE(2, 10)
diff --git a/hw/audio/fmopl.h b/hw/audio/fmopl.h
index e7e578a48e..e008e72d7a 100644
--- a/hw/audio/fmopl.h
+++ b/hw/audio/fmopl.h
@@ -72,8 +72,8 @@ typedef struct fm_opl_f {
/* Rhythm sention */
uint8_t rhythm; /* Rhythm mode , key flag */
/* time tables */
- int32_t AR_TABLE[75]; /* atttack rate tables */
- int32_t DR_TABLE[75]; /* decay rate tables */
+ int32_t AR_TABLE[76]; /* attack rate tables */
+ int32_t DR_TABLE[76]; /* decay rate tables */
uint32_t FN_TABLE[1024]; /* fnumber -> increment counter */
/* LFO */
int32_t *ams_table;
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 2e9c1e1e2f..6f19f127a5 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1617,7 +1617,7 @@ static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t
status0,
fdctrl->fifo[5] = cur_drv->sect;
fdctrl->fifo[6] = FD_SECTOR_SC;
fdctrl->data_dir = FD_DIR_READ;
- if (!(fdctrl->msr & FD_MSR_NONDMA)) {
+ if (fdctrl->dma_chann != -1 && !(fdctrl->msr & FD_MSR_NONDMA)) {
IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
k->release_DREQ(fdctrl->dma, fdctrl->dma_chann);
}
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index d2dd8ab502..04e3ebe352 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -667,9 +667,9 @@ static void virtio_serial_save_device(VirtIODevice *vdev,
QEMUFile *f)
/* The config space (ignored on the far end in current versions) */
get_config(vdev, (uint8_t *)&config);
- qemu_put_be16s(f, &config.cols);
- qemu_put_be16s(f, &config.rows);
- qemu_put_be32s(f, &config.max_nr_ports);
+ qemu_put_be16(f, config.cols);
+ qemu_put_be16(f, config.rows);
+ qemu_put_be32(f, config.max_nr_ports);
/* The ports map */
max_nr_ports = s->serial.max_virtserial_ports;
diff --git a/hw/i2c/bitbang_i2c.h b/hw/i2c/bitbang_i2c.h
index 3a7126d5de..9443021710 100644
--- a/hw/i2c/bitbang_i2c.h
+++ b/hw/i2c/bitbang_i2c.h
@@ -3,8 +3,6 @@
#include "hw/i2c/i2c.h"
-typedef struct bitbang_i2c_interface bitbang_i2c_interface;
-
#define BITBANG_I2C_SDA 0
#define BITBANG_I2C_SCL 1
diff --git a/hw/i2c/smbus.c b/hw/i2c/smbus.c
index 587ce1ab7f..639ff90b65 100644
--- a/hw/i2c/smbus.c
+++ b/hw/i2c/smbus.c
@@ -193,7 +193,11 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)
switch (dev->mode) {
case SMBUS_WRITE_DATA:
DPRINTF("Write data %02x\n", data);
- dev->data_buf[dev->data_len++] = data;
+ if (dev->data_len >= sizeof(dev->data_buf)) {
+ BADF("Too many bytes sent\n");
+ } else {
+ dev->data_buf[dev->data_len++] = data;
+ }
break;
default:
BADF("Unexpected write in state %d\n", dev->mode);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index e1ee8ae9e0..31ed0e16a2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2134,8 +2134,16 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
if (TPM_IS_TIS(tpm_find())) {
- dev = aml_device("ISA.TPM");
- aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C31")));
+ if (misc->tpm_version == TPM_VERSION_2_0) {
+ dev = aml_device("TPM");
+ aml_append(dev, aml_name_decl("_HID",
+ aml_string("MSFT0101")));
+ } else {
+ dev = aml_device("ISA.TPM");
+ aml_append(dev, aml_name_decl("_HID",
+ aml_eisaid("PNP0C31")));
+ }
+
aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));
crs = aml_resource_template();
aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
@@ -2251,64 +2259,6 @@ build_tpm2(GArray *table_data, BIOSLinker *linker,
GArray *tcpalog)
#define HOLE_640K_START (640 * KiB)
#define HOLE_640K_END (1 * MiB)
-static void build_srat_hotpluggable_memory(GArray *table_data, uint64_t base,
- uint64_t len, int default_node)
-{
- MemoryDeviceInfoList *info_list = qmp_memory_device_list();
- MemoryDeviceInfoList *info;
- MemoryDeviceInfo *mi;
- PCDIMMDeviceInfo *di;
- uint64_t end = base + len, cur, size;
- bool is_nvdimm;
- AcpiSratMemoryAffinity *numamem;
- MemoryAffinityFlags flags;
-
- for (cur = base, info = info_list;
- cur < end;
- cur += size, info = info->next) {
- numamem = acpi_data_push(table_data, sizeof *numamem);
-
- if (!info) {
- /*
- * Entry is required for Windows to enable memory hotplug in OS
- * and for Linux to enable SWIOTLB when booted with less than
- * 4G of RAM. Windows works better if the entry sets proximity
- * to the highest NUMA node in the machine at the end of the
- * reserved space.
- * Memory devices may override proximity set by this entry,
- * providing _PXM method if necessary.
- */
- build_srat_memory(numamem, end - 1, 1, default_node,
- MEM_AFFINITY_HOTPLUGGABLE |
MEM_AFFINITY_ENABLED);
- break;
- }
-
- mi = info->value;
- is_nvdimm = (mi->type == MEMORY_DEVICE_INFO_KIND_NVDIMM);
- di = !is_nvdimm ? mi->u.dimm.data : mi->u.nvdimm.data;
-
- if (cur < di->addr) {
- build_srat_memory(numamem, cur, di->addr - cur, default_node,
- MEM_AFFINITY_HOTPLUGGABLE |
MEM_AFFINITY_ENABLED);
- numamem = acpi_data_push(table_data, sizeof *numamem);
- }
-
- size = di->size;
-
- flags = MEM_AFFINITY_ENABLED;
- if (di->hotpluggable) {
- flags |= MEM_AFFINITY_HOTPLUGGABLE;
- }
- if (is_nvdimm) {
- flags |= MEM_AFFINITY_NON_VOLATILE;
- }
-
- build_srat_memory(numamem, di->addr, size, di->node, flags);
- }
-
- qapi_free_MemoryDeviceInfoList(info_list);
-}
-
static void
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{
@@ -2414,10 +2364,19 @@ build_srat(GArray *table_data, BIOSLinker *linker,
MachineState *machine)
build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
}
+ /*
+ * Entry is required for Windows to enable memory hotplug in OS
+ * and for Linux to enable SWIOTLB when booted with less than
+ * 4G of RAM. Windows works better if the entry sets proximity
+ * to the highest NUMA node in the machine.
+ * Memory devices may override proximity set by this entry,
+ * providing _PXM method if necessary.
+ */
if (hotplugabble_address_space_size) {
- build_srat_hotpluggable_memory(table_data,
machine->device_memory->base,
- hotplugabble_address_space_size,
- pcms->numa_nodes - 1);
+ numamem = acpi_data_push(table_data, sizeof *numamem);
+ build_srat_memory(numamem, machine->device_memory->base,
+ hotplugabble_address_space_size, pcms->numa_nodes -
1,
+ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
}
build_header(linker, table_data,
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 0a8cd4e9cc..4dfa9d5e2b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -37,6 +37,8 @@
#include "kvm_i386.h"
#include "trace.h"
+static void vtd_address_space_refresh_all(IntelIOMMUState *s);
+
static void vtd_define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val,
uint64_t wmask, uint64_t w1cmask)
{
@@ -227,6 +229,14 @@ static void vtd_reset_iotlb(IntelIOMMUState *s)
vtd_iommu_unlock(s);
}
+static void vtd_reset_caches(IntelIOMMUState *s)
+{
+ vtd_iommu_lock(s);
+ vtd_reset_iotlb_locked(s);
+ vtd_reset_context_cache_locked(s);
+ vtd_iommu_unlock(s);
+}
+
static uint64_t vtd_get_iotlb_key(uint64_t gfn, uint16_t source_id,
uint32_t level)
{
@@ -1418,7 +1428,7 @@ static void vtd_context_global_invalidate(IntelIOMMUState
*s)
vtd_reset_context_cache_locked(s);
}
vtd_iommu_unlock(s);
- vtd_switch_address_space_all(s);
+ vtd_address_space_refresh_all(s);
/*
* From VT-d spec 6.5.2.1, a global context entry invalidation
* should be followed by a IOTLB global invalidation, so we should
@@ -1703,6 +1713,8 @@ static void vtd_handle_gcmd_srtp(IntelIOMMUState *s)
vtd_root_table_setup(s);
/* Ok - report back to driver */
vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_RTPS);
+ vtd_reset_caches(s);
+ vtd_address_space_refresh_all(s);
}
/* Set Interrupt Remap Table Pointer */
@@ -1735,7 +1747,8 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool
en)
vtd_set_clear_mask_long(s, DMAR_GSTS_REG, VTD_GSTS_TES, 0);
}
- vtd_switch_address_space_all(s);
+ vtd_reset_caches(s);
+ vtd_address_space_refresh_all(s);
}
/* Handle Interrupt Remap Enable/Disable */
@@ -3014,6 +3027,12 @@ static void vtd_address_space_unmap_all(IntelIOMMUState
*s)
}
}
+static void vtd_address_space_refresh_all(IntelIOMMUState *s)
+{
+ vtd_address_space_unmap_all(s);
+ vtd_switch_address_space_all(s);
+}
+
static int vtd_replay_hook(IOMMUTLBEntry *entry, void *private)
{
memory_region_notify_one((IOMMUNotifier *)private, entry);
@@ -3123,10 +3142,7 @@ static void vtd_init(IntelIOMMUState *s)
s->cap |= VTD_CAP_CM;
}
- vtd_iommu_lock(s);
- vtd_reset_context_cache_locked(s);
- vtd_reset_iotlb_locked(s);
- vtd_iommu_unlock(s);
+ vtd_reset_caches(s);
/* Define registers with default values and bit semantics */
vtd_define_long(s, DMAR_VER_REG, 0x10UL, 0, 0);
@@ -3189,11 +3205,7 @@ static void vtd_reset(DeviceState *dev)
IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
vtd_init(s);
-
- /*
- * When device reset, throw away all mappings and external caches
- */
- vtd_address_space_unmap_all(s);
+ vtd_address_space_refresh_all(s);
}
static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 07d79e317f..869518ee06 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -174,7 +174,7 @@ static int ne2000_buffer_full(NE2000State *s)
ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
{
NE2000State *s = qemu_get_nic_opaque(nc);
- int size = size_;
+ size_t size = size_;
uint8_t *p;
unsigned int total_len, next, avail, len, index, mcast_idx;
uint8_t buf1[60];
@@ -182,7 +182,7 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t
*buf, size_t size_)
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#if defined(DEBUG_NE2000)
- printf("NE2000: received len=%d\n", size);
+ printf("NE2000: received len=%zu\n", size);
#endif
if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 0c44554168..d9ba04bdfc 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -988,14 +988,14 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t
*buf, size_t size_)
uint8_t buf1[60];
int remaining;
int crc_err = 0;
- int size = size_;
+ size_t size = size_;
if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size ||
(CSR_LOOP(s) && !s->looptest)) {
return -1;
}
#ifdef PCNET_DEBUG
- printf("pcnet_receive size=%d\n", size);
+ printf("pcnet_receive size=%zu\n", size);
#endif
/* if too small buffer, then expand it */
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 46daa16202..2342a095e3 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -817,7 +817,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const
uint8_t *buf, size_t
RTL8139State *s = qemu_get_nic_opaque(nc);
PCIDevice *d = PCI_DEVICE(s);
/* size is the length of the buffer passed to the driver */
- int size = size_;
+ size_t size = size_;
const uint8_t *dot1q_buf = NULL;
uint32_t packet_header = 0;
@@ -826,7 +826,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const
uint8_t *buf, size_t
static const uint8_t broadcast_macaddr[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- DPRINTF(">>> received len=%d\n", size);
+ DPRINTF(">>> received len=%zu\n", size);
/* test if board clock is stopped */
if (!s->clock_enabled)
@@ -1035,7 +1035,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc,
const uint8_t *buf, size_t
if (size+4 > rx_space)
{
- DPRINTF("C+ Rx mode : descriptor %d size %d received %d + 4\n",
+ DPRINTF("C+ Rx mode : descriptor %d size %d received %zu + 4\n",
descriptor, rx_space, size);
s->IntrStatus |= RxOverflow;
@@ -1148,7 +1148,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc,
const uint8_t *buf, size_t
if (avail != 0 && RX_ALIGN(size + 8) >= avail)
{
DPRINTF("rx overflow: rx buffer length %d head 0x%04x "
- "read 0x%04x === available 0x%04x need 0x%04x\n",
+ "read 0x%04x === available 0x%04x need 0x%04zx\n",
s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8);
s->IntrStatus |= RxOverflow;
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 6c91bd44a0..66b73b87c8 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -345,6 +345,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev,
if (!dev->hotplugged) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
+ if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
+ pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
+ PCI_EXP_LNKSTA_DLLLA);
+ }
return;
}
@@ -355,6 +359,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev,
if (pci_get_function_0(pci_dev)) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
+ if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
+ pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
+ PCI_EXP_LNKSTA_DLLLA);
+ }
pcie_cap_slot_event(PCI_DEVICE(hotplug_dev),
PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
}
@@ -531,6 +539,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
+ if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
+ pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
+ PCI_EXP_LNKSTA_DLLLA);
+ }
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDC);
}
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index d7721320a2..172a915cfc 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -155,9 +155,15 @@ static void pnv_lpc_do_eccb(PnvLpcController *lpc,
uint64_t cmd)
/* XXX Check for magic bits at the top, addr size etc... */
unsigned int sz = (cmd & ECCB_CTL_SZ_MASK) >> ECCB_CTL_SZ_LSH;
uint32_t opb_addr = cmd & ECCB_CTL_ADDR_MASK;
- uint8_t data[4];
+ uint8_t data[8];
bool success;
+ if (sz > sizeof(data)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ECCB: invalid operation at @0x%08x size %d\n", opb_addr, sz);
+ return;
+ }
+
if (cmd & ECCB_CTL_READ) {
success = opb_read(lpc, opb_addr, data, sz);
if (success) {
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 993759db47..bb88a3ce4e 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -113,26 +113,6 @@ const char *spapr_get_cpu_core_type(const char *cpu_type)
return object_class_get_name(oc);
}
-static void spapr_unrealize_vcpu(PowerPCCPU *cpu)
-{
- qemu_unregister_reset(spapr_cpu_reset, cpu);
- object_unparent(cpu->intc);
- cpu_remove_sync(CPU(cpu));
- object_unparent(OBJECT(cpu));
-}
-
-static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
-{
- sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
- CPUCore *cc = CPU_CORE(dev);
- int i;
-
- for (i = 0; i < cc->nr_threads; i++) {
- spapr_unrealize_vcpu(sc->threads[i]);
- }
- g_free(sc->threads);
-}
-
static bool slb_shadow_needed(void *opaque)
{
sPAPRCPUState *spapr_cpu = opaque;
@@ -207,10 +187,34 @@ static const VMStateDescription vmstate_spapr_cpu_state =
{
}
};
+static void spapr_unrealize_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
+{
+ if (!sc->pre_3_0_migration) {
+ vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
+ }
+ qemu_unregister_reset(spapr_cpu_reset, cpu);
+ object_unparent(cpu->intc);
+ cpu_remove_sync(CPU(cpu));
+ object_unparent(OBJECT(cpu));
+}
+
+static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
+{
+ sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
+ CPUCore *cc = CPU_CORE(dev);
+ int i;
+
+ for (i = 0; i < cc->nr_threads; i++) {
+ spapr_unrealize_vcpu(sc->threads[i], sc);
+ }
+ g_free(sc->threads);
+}
+
static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr,
- Error **errp)
+ sPAPRCPUCore *sc, Error **errp)
{
CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
Error *local_err = NULL;
object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
@@ -233,6 +237,11 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
goto error_unregister;
}
+ if (!sc->pre_3_0_migration) {
+ vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state,
+ cpu->machine_data);
+ }
+
return;
error_unregister:
@@ -272,10 +281,6 @@ static PowerPCCPU *spapr_create_vcpu(sPAPRCPUCore *sc, int
i, Error **errp)
}
cpu->machine_data = g_new0(sPAPRCPUState, 1);
- if (!sc->pre_3_0_migration) {
- vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state,
- cpu->machine_data);
- }
object_unref(obj);
return cpu;
@@ -290,9 +295,6 @@ static void spapr_delete_vcpu(PowerPCCPU *cpu, sPAPRCPUCore
*sc)
{
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
- if (!sc->pre_3_0_migration) {
- vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
- }
cpu->machine_data = NULL;
g_free(spapr_cpu);
object_unparent(OBJECT(cpu));
@@ -325,7 +327,7 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error
**errp)
}
for (j = 0; j < cc->nr_threads; j++) {
- spapr_realize_vcpu(sc->threads[j], spapr, &local_err);
+ spapr_realize_vcpu(sc->threads[j], spapr, sc, &local_err);
if (local_err) {
goto err_unrealize;
}
@@ -334,7 +336,7 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error
**errp)
err_unrealize:
while (--j >= 0) {
- spapr_unrealize_vcpu(sc->threads[j]);
+ spapr_unrealize_vcpu(sc->threads[j], sc);
}
err:
while (--i >= 0) {
diff --git a/hw/rdma/rdma_rm_defs.h b/hw/rdma/rdma_rm_defs.h
index 226011176d..f098d91813 100644
--- a/hw/rdma/rdma_rm_defs.h
+++ b/hw/rdma/rdma_rm_defs.h
@@ -89,7 +89,7 @@ typedef struct RdmaRmPort {
enum ibv_port_state state;
} RdmaRmPort;
-typedef struct RdmaDeviceResources {
+struct RdmaDeviceResources {
RdmaRmPort ports[MAX_PORTS];
RdmaRmResTbl pd_tbl;
RdmaRmResTbl mr_tbl;
@@ -98,6 +98,6 @@ typedef struct RdmaDeviceResources {
RdmaRmResTbl cq_tbl;
RdmaRmResTbl cqe_ctx_tbl;
GHashTable *qp_hash; /* Keeps mapping between real and emulated */
-} RdmaDeviceResources;
+};
#endif
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 160657f4b9..3758635665 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -865,10 +865,11 @@ static void lsi_do_status(LSIState *s)
static void lsi_do_msgin(LSIState *s)
{
- int len;
+ uint8_t len;
DPRINTF("Message in len=%d/%d\n", s->dbc, s->msg_len);
s->sfbr = s->msg[0];
len = s->msg_len;
+ assert(len > 0 && len <= LSI_MAX_MSGIN_LEN);
if (len > s->dbc)
len = s->dbc;
pci_dma_write(PCI_DEVICE(s), s->dnad, s->msg, len);
@@ -1703,8 +1704,10 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
break;
case 0x58: /* SBDL */
/* Some drivers peek at the data bus during the MSG IN phase. */
- if ((s->sstat1 & PHASE_MASK) == PHASE_MI)
+ if ((s->sstat1 & PHASE_MASK) == PHASE_MI) {
+ assert(s->msg_len > 0);
return s->msg[0];
+ }
ret = 0;
break;
case 0x59: /* SBDL high */
@@ -2096,11 +2099,23 @@ static int lsi_pre_save(void *opaque)
return 0;
}
+static int lsi_post_load(void *opaque, int version_id)
+{
+ LSIState *s = opaque;
+
+ if (s->msg_len < 0 || s->msg_len > LSI_MAX_MSGIN_LEN) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const VMStateDescription vmstate_lsi_scsi = {
.name = "lsiscsi",
.version_id = 0,
.minimum_version_id = 0,
.pre_save = lsi_pre_save,
+ .post_load = lsi_post_load,
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(parent_obj, LSIState),
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 9c1bea8ff3..a5eb2800a2 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -183,7 +183,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error
**errp)
}
vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
- vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
+ vsc->dev.vqs = g_new0(struct vhost_virtqueue, vsc->dev.nvqs);
vsc->dev.vq_index = 0;
vsc->dev.backend_features = 0;
diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 10bc20dbec..70f4b10284 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -166,6 +166,7 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu,
uint8_t locty_number,
trace_tpm_emulator_set_locality(locty_number);
+ memset(&loc, 0, sizeof(loc));
loc.u.req.loc = locty_number;
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
sizeof(loc), sizeof(loc)) < 0) {
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 12f5c9a759..fb08b483bc 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -263,7 +263,9 @@ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty,
uint8_t newlocty)
{
uint8_t busy_locty;
- s->aborting_locty = locty;
+ assert(TPM_TIS_IS_VALID_LOCTY(newlocty));
+
+ s->aborting_locty = locty; /* may also be TPM_TIS_NO_LOCALITY */
s->next_locty = newlocty; /* locality after successful abort */
/*
@@ -293,9 +295,11 @@ static void tpm_tis_request_completed(TPMIf *ti, int ret)
uint8_t locty = s->cmd.locty;
uint8_t l;
+ assert(TPM_TIS_IS_VALID_LOCTY(locty));
+
if (s->cmd.selftest_done) {
for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
- s->loc[locty].sts |= TPM_TIS_STS_SELFTEST_DONE;
+ s->loc[l].sts |= TPM_TIS_STS_SELFTEST_DONE;
}
}
@@ -616,7 +620,7 @@ static void tpm_tis_mmio_write(void *opaque, hwaddr addr,
}
/* cancel any seize by a lower locality */
- for (l = 0; l < locty - 1; l++) {
+ for (l = 0; l < locty; l++) {
s->loc[l].access &= ~TPM_TIS_ACCESS_SEIZE;
}
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 1ded7ac9a3..f4223fb9de 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -649,13 +649,18 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject
*o)
{
struct dirent *entry;
DIR *dir;
+ int fd;
if (o->have_children) {
return;
}
o->have_children = true;
- dir = opendir(o->path);
+ fd = open(o->path, O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
+ if (fd < 0) {
+ return;
+ }
+ dir = fdopendir(fd);
if (!dir) {
return;
}
@@ -1003,7 +1008,7 @@ static MTPData *usb_mtp_get_object(MTPState *s,
MTPControl *c,
trace_usb_mtp_op_get_object(s->dev.addr, o->handle, o->path);
- d->fd = open(o->path, O_RDONLY);
+ d->fd = open(o->path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
if (d->fd == -1) {
usb_mtp_data_free(d);
return NULL;
@@ -1027,7 +1032,7 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s,
MTPControl *c,
c->argv[1], c->argv[2]);
d = usb_mtp_data_alloc(c);
- d->fd = open(o->path, O_RDONLY);
+ d->fd = open(o->path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
if (d->fd == -1) {
usb_mtp_data_free(d);
return NULL;
@@ -1608,7 +1613,7 @@ static void usb_mtp_write_data(MTPState *s)
0, 0, 0, 0);
goto done;
}
- d->fd = open(path, O_CREAT | O_WRONLY, mask);
+ d->fd = open(path, O_CREAT | O_WRONLY | O_CLOEXEC | O_NOFOLLOW, mask);
if (d->fd == -1) {
usb_mtp_queue_result(s, RES_STORE_FULL, d->trans,
0, 0, 0, 0);
@@ -1667,6 +1672,12 @@ static void usb_mtp_write_metadata(MTPState *s)
utf16_to_str(dataset->length, dataset->filename, filename);
+ if (strchr(filename, '/')) {
+ usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans,
+ 0, 0, 0, 0);
+ return;
+ }
+
o = usb_mtp_object_lookup_name(p, filename, dataset->length);
if (o != NULL) {
next_handle = o->handle;
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index b041343632..e09bed0e4a 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -374,8 +374,6 @@ static int vhost_user_set_mem_table_postcopy(struct
vhost_dev *dev,
int fds[VHOST_MEMORY_MAX_NREGIONS];
int i, fd;
size_t fd_num = 0;
- bool reply_supported = virtio_has_feature(dev->protocol_features,
- VHOST_USER_PROTOCOL_F_REPLY_ACK);
VhostUserMsg msg_reply;
int region_i, msg_i;
@@ -384,10 +382,6 @@ static int vhost_user_set_mem_table_postcopy(struct
vhost_dev *dev,
.hdr.flags = VHOST_USER_VERSION,
};
- if (reply_supported) {
- msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
- }
-
if (u->region_rb_len < dev->mem->nregions) {
u->region_rb = g_renew(RAMBlock*, u->region_rb, dev->mem->nregions);
u->region_rb_offset = g_renew(ram_addr_t, u->region_rb_offset,
@@ -503,10 +497,6 @@ static int vhost_user_set_mem_table_postcopy(struct
vhost_dev *dev,
return -1;
}
- if (reply_supported) {
- return process_message_reply(dev, &msg);
- }
-
return 0;
}
@@ -519,8 +509,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
size_t fd_num = 0;
bool do_postcopy = u->postcopy_listen && u->postcopy_fd.handler;
bool reply_supported = virtio_has_feature(dev->protocol_features,
- VHOST_USER_PROTOCOL_F_REPLY_ACK) &&
- !do_postcopy;
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
if (do_postcopy) {
/* Postcopy has enough differences that it's best done in it's own
@@ -1291,6 +1280,7 @@ static int vhost_user_postcopy_end(struct vhost_dev *dev,
Error **errp)
return ret;
}
postcopy_unregister_shared_ufd(&u->postcopy_fd);
+ close(u->postcopy_fd.fd);
u->postcopy_fd.handler = NULL;
trace_vhost_user_postcopy_end_exit();
@@ -1430,6 +1420,12 @@ static int vhost_user_backend_cleanup(struct vhost_dev
*dev)
postcopy_remove_notifier(&u->postcopy_notifier);
u->postcopy_notifier.notify = NULL;
}
+ u->postcopy_listen = false;
+ if (u->postcopy_fd.handler) {
+ postcopy_unregister_shared_ufd(&u->postcopy_fd);
+ close(u->postcopy_fd.fd);
+ u->postcopy_fd.handler = NULL;
+ }
if (u->slave_fd >= 0) {
qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
close(u->slave_fd);
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index d4cb5894a8..569c4053ea 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1073,10 +1073,8 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
.index = vhost_vq_index,
};
int r;
- int a;
- a = virtio_queue_get_desc_addr(vdev, idx);
- if (a == 0) {
+ if (virtio_queue_get_desc_addr(vdev, idx) == 0) {
/* Don't stop the virtqueue which might have not been started */
return;
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index d4e4d98b59..57a603a65b 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1604,6 +1604,8 @@ void virtio_del_queue(VirtIODevice *vdev, int n)
vdev->vq[n].vring.num = 0;
vdev->vq[n].vring.num_default = 0;
+ vdev->vq[n].handle_output = NULL;
+ vdev->vq[n].handle_aio_output = NULL;
}
static void virtio_set_isr(VirtIODevice *vdev, int value)
@@ -2006,14 +2008,25 @@ static int virtio_set_features_nocheck(VirtIODevice
*vdev, uint64_t val)
int virtio_set_features(VirtIODevice *vdev, uint64_t val)
{
- /*
+ int ret;
+ /*
* The driver must not attempt to set features after feature negotiation
* has finished.
*/
if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
return -EINVAL;
}
- return virtio_set_features_nocheck(vdev, val);
+ ret = virtio_set_features_nocheck(vdev, val);
+ if (!ret && virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
+ /* VIRTIO_RING_F_EVENT_IDX changes the size of the caches. */
+ int i;
+ for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
+ if (vdev->vq[i].vring.num != 0) {
+ virtio_init_region_cache(vdev, i);
+ }
+ }
+ }
+ return ret;
}
int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4638c839f5..a53b0cfae0 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -135,7 +135,9 @@ typedef struct NBDExtent {
#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */
#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */
#define NBD_FLAG_SEND_DF (1 << 7) /* Send DF (Do not Fragment) */
-#define NBD_FLAG_SEND_CACHE (1 << 8) /* Send CACHE (prefetch) */
+#define NBD_FLAG_CAN_MULTI_CONN (1 << 8) /* Multi-client cache consistent */
+#define NBD_FLAG_SEND_RESIZE (1 << 9) /* Send resize */
+#define NBD_FLAG_SEND_CACHE (1 << 10) /* Send CACHE (prefetch) */
/* New-style handshake (global) flags, sent from server to client, and
control what will happen during handshake phase. */
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 5dc166158b..cf4c45a98f 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -82,6 +82,8 @@ int i2c_recv(I2CBus *bus);
DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr);
+typedef struct bitbang_i2c_interface bitbang_i2c_interface;
+
/* lm832x.c */
void lm832x_key_event(DeviceState *dev, int key, int state);
diff --git a/include/hw/i2c/ppc4xx_i2c.h b/include/hw/i2c/ppc4xx_i2c.h
index 0891a9c948..b3450bacf7 100644
--- a/include/hw/i2c/ppc4xx_i2c.h
+++ b/include/hw/i2c/ppc4xx_i2c.h
@@ -31,9 +31,6 @@
#include "hw/sysbus.h"
#include "hw/i2c/i2c.h"
-/* from hw/i2c/bitbang_i2c.h */
-typedef struct bitbang_i2c_interface bitbang_i2c_interface;
-
#define TYPE_PPC4xx_I2C "ppc4xx-i2c"
#define PPC4xx_I2C(obj) OBJECT_CHECK(PPC4xxI2CState, (obj), TYPE_PPC4xx_I2C)
diff --git a/include/hw/s390x/tod.h b/include/hw/s390x/tod.h
index 413c0d7c02..442f45b2f5 100644
--- a/include/hw/s390x/tod.h
+++ b/include/hw/s390x/tod.h
@@ -50,7 +50,7 @@ typedef struct S390TODClass {
/* Converts ns to s390's clock format */
static inline uint64_t time2tod(uint64_t ns)
{
- return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9);
+ return (ns << 9) / 125 + (((ns & 0xff80000000000000ull) / 125) << 9);
}
/* Converts s390's clock format to ns */
diff --git a/job.c b/job.c
index fa671b431a..a3bec7fb22 100644
--- a/job.c
+++ b/job.c
@@ -136,21 +136,13 @@ static void job_txn_del_job(Job *job)
}
}
-static int job_txn_apply(JobTxn *txn, int fn(Job *), bool lock)
+static int job_txn_apply(JobTxn *txn, int fn(Job *))
{
- AioContext *ctx;
Job *job, *next;
int rc = 0;
QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
- if (lock) {
- ctx = job->aio_context;
- aio_context_acquire(ctx);
- }
rc = fn(job);
- if (lock) {
- aio_context_release(ctx);
- }
if (rc) {
break;
}
@@ -732,10 +724,10 @@ static void job_cancel_async(Job *job, bool force)
{
if (job->user_paused) {
/* Do not call job_enter here, the caller will handle it. */
- job->user_paused = false;
if (job->driver->user_resume) {
job->driver->user_resume(job);
}
+ job->user_paused = false;
assert(job->pause_count > 0);
job->pause_count--;
}
@@ -807,11 +799,11 @@ static void job_do_finalize(Job *job)
assert(job && job->txn);
/* prepare the transaction to complete */
- rc = job_txn_apply(job->txn, job_prepare, true);
+ rc = job_txn_apply(job->txn, job_prepare);
if (rc) {
job_completed_txn_abort(job);
} else {
- job_txn_apply(job->txn, job_finalize_single, true);
+ job_txn_apply(job->txn, job_finalize_single);
}
}
@@ -857,10 +849,10 @@ static void job_completed_txn_success(Job *job)
assert(other_job->ret == 0);
}
- job_txn_apply(txn, job_transition_to_pending, false);
+ job_txn_apply(txn, job_transition_to_pending);
/* If no jobs need manual finalization, automatically do so */
- if (job_txn_apply(txn, job_needs_finalize, false) == 0) {
+ if (job_txn_apply(txn, job_needs_finalize) == 0) {
job_do_finalize(job);
}
}
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dfc851cc35..0859739e9d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8077,6 +8077,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
case TARGET_NR_write:
+ if (arg2 == 0 && arg3 == 0) {
+ return get_errno(safe_write(arg1, 0, 0));
+ }
if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
goto efault;
if (fd_trans_target_to_host_data(arg1)) {
@@ -10848,15 +10851,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
arg1,
#endif
#ifdef TARGET_AARCH64
case TARGET_PR_SVE_SET_VL:
- /* We cannot support either PR_SVE_SET_VL_ONEXEC
- or PR_SVE_VL_INHERIT. Therefore, anything above
- ARM_MAX_VQ results in EINVAL. */
+ /*
+ * We cannot support either PR_SVE_SET_VL_ONEXEC or
+ * PR_SVE_VL_INHERIT. Note the kernel definition
+ * of sve_vl_valid allows for VQ=512, i.e. VL=8192,
+ * even though the current architectural maximum is VQ=16.
+ */
ret = -TARGET_EINVAL;
if (arm_feature(cpu_env, ARM_FEATURE_SVE)
- && arg2 >= 0 && arg2 <= ARM_MAX_VQ * 16 && !(arg2 & 15)) {
+ && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
CPUARMState *env = cpu_env;
- int old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
- int vq = MAX(arg2 / 16, 1);
+ ARMCPU *cpu = arm_env_get_cpu(env);
+ uint32_t vq, old_vq;
+
+ old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
+ vq = MAX(arg2 / 16, 1);
+ vq = MIN(vq, cpu->sve_max_vq);
if (vq < old_vq) {
aarch64_sve_narrow_vq(env, vq);
@@ -10900,8 +10910,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
arg1,
arg4 = arg5;
arg5 = arg6;
}
- if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
- goto efault;
+ if (arg2 == 0 && arg3 == 0) {
+ /* Special-case NULL buffer and zero length, which should succeed
*/
+ p = 0;
+ } else {
+ p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+ if (!p) {
+ goto efault;
+ }
+ }
ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
unlock_user(p, arg2, ret);
break;
@@ -10910,8 +10927,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
arg1,
arg4 = arg5;
arg5 = arg6;
}
- if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
- goto efault;
+ if (arg2 == 0 && arg3 == 0) {
+ /* Special-case NULL buffer and zero length, which should succeed
*/
+ p = 0;
+ } else {
+ p = lock_user(VERIFY_READ, arg2, arg3, 1);
+ if (!p) {
+ goto efault;
+ }
+ }
ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
unlock_user(p, arg2, 0);
break;
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 932f188949..d6cc99fee1 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -519,6 +519,12 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState
*mis)
if (mis->have_fault_thread) {
Error *local_err = NULL;
+ /* Let the fault thread quit */
+ atomic_set(&mis->fault_thread_quit, 1);
+ postcopy_fault_thread_notify(mis);
+ trace_postcopy_ram_incoming_cleanup_join();
+ qemu_thread_join(&mis->fault_thread);
+
if (postcopy_notify(POSTCOPY_NOTIFY_INBOUND_END, &local_err)) {
error_report_err(local_err);
return -1;
@@ -527,11 +533,6 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState
*mis)
if (qemu_ram_foreach_migratable_block(cleanup_range, mis)) {
return -1;
}
- /* Let the fault thread quit */
- atomic_set(&mis->fault_thread_quit, 1);
- postcopy_fault_thread_notify(mis);
- trace_postcopy_ram_incoming_cleanup_join();
- qemu_thread_join(&mis->fault_thread);
trace_postcopy_ram_incoming_cleanup_closeuf();
close(mis->userfault_fd);
diff --git a/monitor.c b/monitor.c
index 77861e96af..a1999e396c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4277,6 +4277,8 @@ static void handle_qmp_command(JSONMessageParser *parser,
GQueue *tokens)
trace_monitor_qmp_cmd_out_of_band(qobject_get_try_str(id)
?: "");
monitor_qmp_dispatch(mon, req, id);
+ qobject_unref(req);
+ qobject_unref(id);
return;
}
diff --git a/nbd/server.c b/nbd/server.c
index ea5fe0eb33..2193e16c68 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -978,6 +978,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
if (client->opt == NBD_OPT_LIST_META_CONTEXT && !nb_queries) {
/* enable all known contexts */
meta->base_allocation = true;
+ meta->bitmap = !!meta->exp->export_bitmap;
} else {
for (i = 0; i < nb_queries; ++i) {
ret = nbd_negotiate_meta_query(client, meta, errp);
@@ -1951,6 +1952,8 @@ static unsigned int bitmap_to_extents(BdrvDirtyBitmap
*bitmap, uint64_t offset,
assert(begin < overall_end && nb_extents);
while (begin < overall_end && i < nb_extents) {
+ bool next_dirty = !dirty;
+
if (dirty) {
end = bdrv_dirty_bitmap_next_zero(bitmap, begin);
} else {
@@ -1962,6 +1965,7 @@ static unsigned int bitmap_to_extents(BdrvDirtyBitmap
*bitmap, uint64_t offset,
end = MIN(bdrv_dirty_bitmap_size(bitmap),
begin + UINT32_MAX + 1 -
bdrv_dirty_bitmap_granularity(bitmap));
+ next_dirty = dirty;
}
if (dont_fragment && end > overall_end) {
end = overall_end;
@@ -1971,7 +1975,7 @@ static unsigned int bitmap_to_extents(BdrvDirtyBitmap
*bitmap, uint64_t offset,
extents[i].flags = cpu_to_be32(dirty ? NBD_STATE_DIRTY : 0);
i++;
begin = end;
- dirty = !dirty;
+ dirty = next_dirty;
}
bdrv_dirty_iter_free(it);
@@ -2135,7 +2139,8 @@ static coroutine_fn int nbd_do_cmd_read(NBDClient
*client, NBDRequest *request,
}
if (client->structured_reply && !(request->flags & NBD_CMD_FLAG_DF) &&
- request->len) {
+ request->len && request->type != NBD_CMD_CACHE)
+ {
return nbd_co_send_sparse_read(client, request->handle, request->from,
data, request->len, errp);
}
diff --git a/net/slirp.c b/net/slirp.c
index 1e14318b4d..fd21dc728c 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -365,6 +365,15 @@ static int net_slirp_init(NetClientState *peer, const char
*model,
return -1;
}
+ if (vdomainname && strlen(vdomainname) > 255) {
+ error_setg(errp, "'domainname' parameter cannot exceed 255 bytes");
+ return -1;
+ }
+
+ if (vhostname && strlen(vhostname) > 255) {
+ error_setg(errp, "'vhostname' parameter cannot exceed 255 bytes");
+ return -1;
+ }
nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
index 9920a85adc..cff0e8b309 100644
--- a/qemu-deprecated.texi
+++ b/qemu-deprecated.texi
@@ -227,6 +227,21 @@ from old QEMU versions anymore. A newer machine type
should be used instead.
In order to prevent QEMU from automatically opening an image's backing
chain, use ``"backing": null'' instead.
+@subsubsection rbd keyvalue pair encoded filenames: "" (since 3.1.0)
+
+Options for ``rbd'' should be specified according to its runtime options,
+like other block drivers. Legacy parsing of keyvalue pair encoded
+filenames is useful to open images with the old format for backing files;
+These image files should be updated to use the current format.
+
+Example of legacy encoding:
+
+@code{json:@{"file.driver":"rbd", "file.filename":"rbd:rbd/name"@}}
+
+The above, converted to the current supported format:
+
+@code{json:@{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"@}}
+
@subsection vio-spapr-device device options
@subsubsection "irq": "" (since 3.0.0)
diff --git a/qemu-img.c b/qemu-img.c
index 1acddf693c..4799e097dc 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -261,8 +261,9 @@ static int print_block_option_help(const char *filename,
const char *fmt)
return 1;
}
if (!proto_drv->create_opts) {
- error_report("Protocal driver '%s' does not support image
creation",
+ error_report("Protocol driver '%s' does not support image
creation",
proto_drv->format_name);
+ qemu_opts_free(create_opts);
return 1;
}
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
@@ -345,21 +346,6 @@ static int img_add_key_secrets(void *opaque,
return 0;
}
-static BlockBackend *img_open_new_file(const char *filename,
- QemuOpts *create_opts,
- const char *fmt, int flags,
- bool writethrough, bool quiet,
- bool force_share)
-{
- QDict *options = NULL;
-
- options = qdict_new();
- qemu_opt_foreach(create_opts, img_add_key_secrets, options, &error_abort);
-
- return img_open_file(filename, options, fmt, flags, writethrough, quiet,
- force_share);
-}
-
static BlockBackend *img_open(bool image_opts,
const char *filename,
@@ -2018,6 +2004,7 @@ static int img_convert(int argc, char **argv)
BlockDriverState *out_bs;
QemuOpts *opts = NULL, *sn_opts = NULL;
QemuOptsList *create_opts = NULL;
+ QDict *open_opts = NULL;
char *options = NULL;
Error *local_err = NULL;
bool writethrough, src_writethrough, quiet = false, image_opts = false,
@@ -2362,6 +2349,16 @@ static int img_convert(int argc, char **argv)
}
}
+ /*
+ * The later open call will need any decryption secrets, and
+ * bdrv_create() will purge "opts", so extract them now before
+ * they are lost.
+ */
+ if (!skip_create) {
+ open_opts = qdict_new();
+ qemu_opt_foreach(opts, img_add_key_secrets, open_opts, &error_abort);
+ }
+
if (!skip_create) {
/* Create the new image */
ret = bdrv_create(drv, out_filename, opts, &local_err);
@@ -2388,8 +2385,9 @@ static int img_convert(int argc, char **argv)
* That has to wait for bdrv_create to be improved
* to allow filenames in option syntax
*/
- s.target = img_open_new_file(out_filename, opts, out_fmt,
- flags, writethrough, quiet, false);
+ s.target = img_open_file(out_filename, open_opts, out_fmt,
+ flags, writethrough, quiet, false);
+ open_opts = NULL; /* blk_new_open will have freed it */
}
if (!s.target) {
ret = -1;
@@ -2464,6 +2462,7 @@ out:
qemu_opts_del(opts);
qemu_opts_free(create_opts);
qemu_opts_del(sn_opts);
+ qobject_unref(open_opts);
blk_unref(s.target);
if (s.src) {
for (bs_i = 0; bs_i < s.src_num; bs_i++) {
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index 9cd8eb9499..4729eb107f 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -20,6 +20,7 @@
#include <sys/prctl.h>
#include <seccomp.h>
#include "sysemu/seccomp.h"
+#include <linux/seccomp.h>
/* For some architectures (notably ARM) cacheflush is not supported until
* libseccomp 2.2.3, but configure enforces that we are using a more recent
@@ -107,12 +108,40 @@ static const struct QemuSeccompSyscall blacklist[] = {
{ SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL },
};
+static inline __attribute__((unused)) int
+qemu_seccomp(unsigned int operation, unsigned int flags, void *args)
+{
+#ifdef __NR_seccomp
+ return syscall(__NR_seccomp, operation, flags, args);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static uint32_t qemu_seccomp_get_kill_action(void)
+{
+#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \
+ defined(SECCOMP_RET_KILL_PROCESS)
+ {
+ uint32_t action = SECCOMP_RET_KILL_PROCESS;
+
+ if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
+ return SCMP_ACT_KILL_PROCESS;
+ }
+ }
+#endif
+
+ return SCMP_ACT_TRAP;
+}
+
static int seccomp_start(uint32_t seccomp_opts)
{
int rc = 0;
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) {
@@ -120,12 +149,17 @@ static int seccomp_start(uint32_t seccomp_opts)
goto seccomp_return;
}
+ rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1);
+ if (rc != 0) {
+ goto seccomp_return;
+ }
+
for (i = 0; i < ARRAY_SIZE(blacklist); i++) {
if (!(seccomp_opts & blacklist[i].set)) {
continue;
}
- rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num,
+ rc = seccomp_rule_add_array(ctx, action, blacklist[i].num,
blacklist[i].narg, blacklist[i].arg_cmp);
if (rc < 0) {
goto seccomp_return;
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index dfbc4a5e32..6a472476a2 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -532,12 +532,12 @@
#
# Suspend guest to disk.
#
-# This command tries to execute the scripts provided by the pm-utils package.
-# If it's not available, the suspend operation will be performed by manually
-# writing to a sysfs file.
+# This command attempts to suspend the guest using three strategies, in this
+# order:
#
-# For the best results it's strongly recommended to have the pm-utils
-# package installed in the guest.
+# - systemd hibernate
+# - pm-utils (via pm-hibernate)
+# - manual write into sysfs
#
# This command does NOT return a response on success. There is a high chance
# the command succeeded if the VM exits with a zero exit status or, when
@@ -560,12 +560,12 @@
#
# Suspend guest to ram.
#
-# This command tries to execute the scripts provided by the pm-utils package.
-# If it's not available, the suspend operation will be performed by manually
-# writing to a sysfs file.
+# This command attempts to suspend the guest using three strategies, in this
+# order:
#
-# For the best results it's strongly recommended to have the pm-utils
-# package installed in the guest.
+# - systemd suspend
+# - pm-utils (via pm-suspend)
+# - manual write into sysfs
#
# IMPORTANT: guest-suspend-ram requires QEMU to support the 'system_wakeup'
# command. Thus, it's *required* to query QEMU for the presence of the
@@ -592,7 +592,10 @@
#
# Save guest state to disk and suspend to ram.
#
-# This command requires the pm-utils package to be installed in the guest.
+# This command attempts to suspend the guest by executing, in this order:
+#
+# - systemd hybrid-sleep
+# - pm-utils (via pm-suspend-hybrid)
#
# IMPORTANT: guest-suspend-hybrid requires QEMU to support the 'system_wakeup'
# command. Thus, it's *required* to query QEMU for the presence of the
diff --git a/scripts/make-release b/scripts/make-release
index 04fa9defdc..c14f75b12c 100755
--- a/scripts/make-release
+++ b/scripts/make-release
@@ -19,6 +19,7 @@ pushd ${destination}
git checkout "v${version}"
git submodule update --init
(cd roms/seabios && git describe --tags --long --dirty > .version)
+(cd roms/skiboot && ./make_version.sh > .version)
# FIXME: The following line is a workaround for avoiding filename collisions
# when unpacking u-boot sources on case-insensitive filesystems. Once we
# update to something with u-boot commit 610eec7f0 we can drop this line.
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 9e7b53ba94..1e8185f0ec 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -159,6 +159,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t
*bp)
struct in_addr preq_addr;
int dhcp_msg_type, val;
uint8_t *q;
+ uint8_t *end;
uint8_t client_ethaddr[ETH_ALEN];
/* extract exact DHCP msg type */
@@ -240,6 +241,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t
*bp)
rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
q = rbp->bp_vend;
+ end = (uint8_t *)&rbp[1];
memcpy(q, rfc1533_cookie, 4);
q += 4;
@@ -292,24 +294,33 @@ static void bootp_reply(Slirp *slirp, const struct
bootp_t *bp)
if (*slirp->client_hostname) {
val = strlen(slirp->client_hostname);
- *q++ = RFC1533_HOSTNAME;
- *q++ = val;
- memcpy(q, slirp->client_hostname, val);
- q += val;
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting host name option.");
+ } else {
+ *q++ = RFC1533_HOSTNAME;
+ *q++ = val;
+ memcpy(q, slirp->client_hostname, val);
+ q += val;
+ }
}
if (slirp->vdomainname) {
val = strlen(slirp->vdomainname);
- *q++ = RFC1533_DOMAINNAME;
- *q++ = val;
- memcpy(q, slirp->vdomainname, val);
- q += val;
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting domain name option.");
+ } else {
+ *q++ = RFC1533_DOMAINNAME;
+ *q++ = val;
+ memcpy(q, slirp->vdomainname, val);
+ q += val;
+ }
}
if (slirp->vdnssearch) {
- size_t spaceleft = sizeof(rbp->bp_vend) - (q - rbp->bp_vend);
val = slirp->vdnssearch_len;
- if (val + 1 > spaceleft) {
+ if (q + val >= end) {
g_warning("DHCP packet size exceeded, "
"omitting domain-search option.");
} else {
@@ -331,6 +342,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t
*bp)
memcpy(q, nak_msg, sizeof(nak_msg) - 1);
q += sizeof(nak_msg) - 1;
}
+ assert(q < end);
*q = RFC1533_END;
daddr.sin_addr.s_addr = 0xffffffffu;
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 8d0f94b75f..aa88de854a 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -640,6 +640,11 @@ tcp_emu(struct socket *so, struct mbuf *m)
socklen_t addrlen = sizeof(struct sockaddr_in);
struct sbuf *so_rcv = &so->so_rcv;
+ if (m->m_len > so_rcv->sb_datalen
+ - (so_rcv->sb_wptr - so_rcv->sb_data)) {
+ return 1;
+ }
+
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_wptr += m->m_len;
so_rcv->sb_rptr += m->m_len;
@@ -662,12 +667,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
break;
}
}
+ so_rcv->sb_cc =
snprintf(so_rcv->sb_data,
+
so_rcv->sb_datalen,
+ "%d,%d\r\n",
n1, n2);
+ so_rcv->sb_rptr = so_rcv->sb_data;
+ so_rcv->sb_wptr = so_rcv->sb_data +
so_rcv->sb_cc;
}
- so_rcv->sb_cc = snprintf(so_rcv->sb_data,
- so_rcv->sb_datalen,
- "%d,%d\r\n", n1, n2);
- so_rcv->sb_rptr = so_rcv->sb_data;
- so_rcv->sb_wptr = so_rcv->sb_data +
so_rcv->sb_cc;
}
m_free(m);
return 0;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 64a8005a4b..b25898ed4c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -168,9 +168,9 @@ static void arm_cpu_reset(CPUState *s)
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
env->cp15.cptr_el[3] |= CPTR_EZ;
/* with maximum vector length */
- env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
- env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
- env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
+ env->vfp.zcr_el[1] = cpu->sve_max_vq - 1;
+ env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
+ env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
#else
/* Reset into the highest available EL */
if (arm_feature(env, ARM_FEATURE_EL3)) {
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e310ffc29d..0dce472aae 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -857,6 +857,9 @@ struct ARMCPU {
/* Used to synchronize KVM and QEMU in-kernel device levels */
uint8_t device_irq_level;
+
+ /* Used to set the maximum vector length the cpu will support. */
+ uint32_t sve_max_vq;
};
static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
@@ -1260,7 +1263,7 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
* we store the underlying state in fpscr and just mask on read/write.
*/
#define FPSR_MASK 0xf800009f
-#define FPCR_MASK 0x07f79f00
+#define FPCR_MASK 0x07ff9f00
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index d0581d59d8..800bff780e 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -29,6 +29,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "kvm_arm.h"
+#include "qapi/visitor.h"
static inline void set_feature(CPUARMState *env, int feature)
{
@@ -217,6 +218,29 @@ static void aarch64_a53_initfn(Object *obj)
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
}
+static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+ visit_type_uint32(v, name, &cpu->sve_max_vq, errp);
+}
+
+static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+ Error *err = NULL;
+
+ visit_type_uint32(v, name, &cpu->sve_max_vq, &err);
+
+ if (!err && (cpu->sve_max_vq == 0 || cpu->sve_max_vq > ARM_MAX_VQ)) {
+ error_setg(&err, "unsupported SVE vector length");
+ error_append_hint(&err, "Valid sve-max-vq in range [1-%d]\n",
+ ARM_MAX_VQ);
+ }
+ error_propagate(errp, err);
+}
+
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
* otherwise, a CPU with as many features enabled as our emulation supports.
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
@@ -253,6 +277,10 @@ static void aarch64_max_initfn(Object *obj)
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache
*/
cpu->dcz_blocksize = 7; /* 512 bytes */
#endif
+
+ cpu->sve_max_vq = ARM_MAX_VQ;
+ object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
+ cpu_max_set_sve_vq, NULL, NULL, &error_fatal);
}
}
@@ -405,6 +433,7 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
uint64_t pmask;
assert(vq >= 1 && vq <= ARM_MAX_VQ);
+ assert(vq <= arm_env_get_cpu(env)->sve_max_vq);
/* Zap the high bits of the zregs. */
for (i = 0; i < 32; i++) {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 66afb08ee0..cae2b2649d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6858,7 +6858,7 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr,
bool dotailchain,
* not already saved.
*/
if (lr & R_V7M_EXCRET_DCRS_MASK &&
- !(dotailchain && (lr & R_V7M_EXCRET_ES_MASK))) {
+ !(dotailchain && !(lr & R_V7M_EXCRET_ES_MASK))) {
push_failed = v7m_push_callee_stack(cpu, lr, dotailchain,
ignore_stackfaults);
}
@@ -11283,9 +11283,13 @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
| (env->vfp.vec_len << 16)
| (env->vfp.vec_stride << 20);
+
i = get_float_exception_flags(&env->vfp.fp_status);
i |= get_float_exception_flags(&env->vfp.standard_fp_status);
- i |= get_float_exception_flags(&env->vfp.fp_status_f16);
+ /* FZ16 does not generate an input denormal exception. */
+ i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
+ & ~float_flag_input_denormal);
+
fpscr |= vfp_exceptbits_from_host(i);
return fpscr;
}
@@ -11320,6 +11324,11 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t
val)
int i;
uint32_t changed;
+ /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
+ if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
+ val &= ~FPCR_FZ16;
+ }
+
changed = env->vfp.xregs[ARM_VFP_FPSCR];
env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
env->vfp.vec_len = (val >> 16) & 7;
@@ -12392,33 +12401,39 @@ void cpu_get_tb_cpu_state(CPUARMState *env,
target_ulong *pc,
uint32_t flags;
if (is_a64(env)) {
- int sve_el = sve_exception_el(env);
- uint32_t zcr_len;
-
*pc = env->pc;
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
/* Get control bits for tagged addresses */
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
- flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
- /* If SVE is disabled, but FP is enabled,
- then the effective len is 0. */
- if (sve_el != 0 && fp_el == 0) {
- zcr_len = 0;
- } else {
- int current_el = arm_current_el(env);
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
+ int sve_el = sve_exception_el(env);
+ uint32_t zcr_len;
- zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
- zcr_len &= 0xf;
- if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
- }
- if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+ /* If SVE is disabled, but FP is enabled,
+ * then the effective len is 0.
+ */
+ if (sve_el != 0 && fp_el == 0) {
+ zcr_len = 0;
+ } else {
+ int current_el = arm_current_el(env);
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
+ zcr_len = cpu->sve_max_vq - 1;
+ if (current_el <= 1) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
+ }
+ if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
+ }
+ if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+ }
}
+ flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
+ flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
}
- flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
} else {
*pc = env->regs[15];
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 54795c9194..0f98097253 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -1042,7 +1042,7 @@ void HELPER(sve_movz_d)(void *vd, void *vn, void *vg,
uint32_t desc)
uint64_t *d = vd, *n = vn;
uint8_t *pg = vg;
for (i = 0; i < opr_sz; i += 1) {
- d[i] = n[1] & -(uint64_t)(pg[H1(i)] & 1);
+ d[i] = n[i] & -(uint64_t)(pg[H1(i)] & 1);
}
}
@@ -2436,13 +2436,13 @@ uint32_t HELPER(NAME)(void *vd, void *vn, void *vm,
void *vg, uint32_t desc) \
#define DO_CMP_PPZW_S(NAME, TYPE, TYPEW, OP) \
DO_CMP_PPZW(NAME, TYPE, TYPEW, OP, H1_4, 0x1111111111111111ull)
-DO_CMP_PPZW_B(sve_cmpeq_ppzw_b, uint8_t, uint64_t, ==)
-DO_CMP_PPZW_H(sve_cmpeq_ppzw_h, uint16_t, uint64_t, ==)
-DO_CMP_PPZW_S(sve_cmpeq_ppzw_s, uint32_t, uint64_t, ==)
+DO_CMP_PPZW_B(sve_cmpeq_ppzw_b, int8_t, uint64_t, ==)
+DO_CMP_PPZW_H(sve_cmpeq_ppzw_h, int16_t, uint64_t, ==)
+DO_CMP_PPZW_S(sve_cmpeq_ppzw_s, int32_t, uint64_t, ==)
-DO_CMP_PPZW_B(sve_cmpne_ppzw_b, uint8_t, uint64_t, !=)
-DO_CMP_PPZW_H(sve_cmpne_ppzw_h, uint16_t, uint64_t, !=)
-DO_CMP_PPZW_S(sve_cmpne_ppzw_s, uint32_t, uint64_t, !=)
+DO_CMP_PPZW_B(sve_cmpne_ppzw_b, int8_t, uint64_t, !=)
+DO_CMP_PPZW_H(sve_cmpne_ppzw_h, int16_t, uint64_t, !=)
+DO_CMP_PPZW_S(sve_cmpne_ppzw_s, int32_t, uint64_t, !=)
DO_CMP_PPZW_B(sve_cmpgt_ppzw_b, int8_t, int64_t, >)
DO_CMP_PPZW_H(sve_cmpgt_ppzw_h, int16_t, int64_t, >)
@@ -2846,11 +2846,6 @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count,
uint32_t pred_desc)
return flags;
}
- /* Scale from predicate element count to bits. */
- count <<= esz;
- /* Bound to the bits in the predicate. */
- count = MIN(count, oprsz * 8);
-
/* Set all of the requested bits. */
for (i = 0; i < count / 64; ++i) {
d->p[i] = esz_mask;
@@ -3363,7 +3358,7 @@ static void do_fmla_zpzzz_h(CPUARMState *env, void *vg,
uint32_t desc,
e1 = *(uint16_t *)(vn + H1_2(i)) ^ neg1;
e2 = *(uint16_t *)(vm + H1_2(i));
e3 = *(uint16_t *)(va + H1_2(i)) ^ neg3;
- r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
+ r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status_f16);
*(uint16_t *)(vd + H1_2(i)) = r;
}
} while (i & 63);
@@ -4050,7 +4045,7 @@ DO_LD1(sve_ld1bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t,
)
DO_LD1(sve_ld1bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
DO_LD1(sve_ld1hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
-DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
+DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int16_t, H1_4)
DO_LD1(sve_ld1hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
DO_LD1(sve_ld1hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 45a6c2a3aa..b29dc49c4f 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -137,14 +137,13 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
int el = arm_current_el(env);
const char *ns_status;
- cpu_fprintf(f, "PC=%016"PRIx64" SP=%016"PRIx64"\n",
- env->pc, env->xregs[31]);
- for (i = 0; i < 31; i++) {
- cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
- if ((i % 4) == 3) {
- cpu_fprintf(f, "\n");
+ cpu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
+ for (i = 0; i < 32; i++) {
+ if (i == 31) {
+ cpu_fprintf(f, " SP=%016" PRIx64 "\n", env->xregs[i]);
} else {
- cpu_fprintf(f, " ");
+ cpu_fprintf(f, "X%02d=%016" PRIx64 "%s", i, env->xregs[i],
+ (i + 2) % 3 ? " " : "\n");
}
}
@@ -153,8 +152,7 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
} else {
ns_status = "";
}
-
- cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
+ cpu_fprintf(f, "PSTATE=%08x %c%c%c%c %sEL%d%c",
psr,
psr & PSTATE_N ? 'N' : '-',
psr & PSTATE_Z ? 'Z' : '-',
@@ -164,17 +162,89 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
el,
psr & PSTATE_SP ? 'h' : 't');
- if (flags & CPU_DUMP_FPU) {
- int numvfpregs = 32;
- for (i = 0; i < numvfpregs; i++) {
+ if (!(flags & CPU_DUMP_FPU)) {
+ cpu_fprintf(f, "\n");
+ return;
+ }
+ cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
+ vfp_get_fpcr(env), vfp_get_fpsr(env));
+
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
+ int j, zcr_len = env->vfp.zcr_el[1] & 0xf; /* fix for system mode */
+
+ for (i = 0; i <= FFR_PRED_NUM; i++) {
+ bool eol;
+ if (i == FFR_PRED_NUM) {
+ cpu_fprintf(f, "FFR=");
+ /* It's last, so end the line. */
+ eol = true;
+ } else {
+ cpu_fprintf(f, "P%02d=", i);
+ switch (zcr_len) {
+ case 0:
+ eol = i % 8 == 7;
+ break;
+ case 1:
+ eol = i % 6 == 5;
+ break;
+ case 2:
+ case 3:
+ eol = i % 3 == 2;
+ break;
+ default:
+ /* More than one quadword per predicate. */
+ eol = true;
+ break;
+ }
+ }
+ for (j = zcr_len / 4; j >= 0; j--) {
+ int digits;
+ if (j * 4 + 4 <= zcr_len + 1) {
+ digits = 16;
+ } else {
+ digits = (zcr_len % 4 + 1) * 4;
+ }
+ cpu_fprintf(f, "%0*" PRIx64 "%s", digits,
+ env->vfp.pregs[i].p[j],
+ j ? ":" : eol ? "\n" : " ");
+ }
+ }
+
+ for (i = 0; i < 32; i++) {
+ if (zcr_len == 0) {
+ cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
+ i, env->vfp.zregs[i].d[1],
+ env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
+ } else if (zcr_len == 1) {
+ cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
+ ":%016" PRIx64 ":%016" PRIx64 "\n",
+ i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
+ env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
+ } else {
+ for (j = zcr_len; j >= 0; j--) {
+ bool odd = (zcr_len - j) % 2 != 0;
+ if (j == zcr_len) {
+ cpu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
+ } else if (!odd) {
+ if (j > 0) {
+ cpu_fprintf(f, " [%x-%x]=", j, j - 1);
+ } else {
+ cpu_fprintf(f, " [%x]=", j);
+ }
+ }
+ cpu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
+ env->vfp.zregs[i].d[j * 2 + 1],
+ env->vfp.zregs[i].d[j * 2],
+ odd || j == 0 ? "\n" : ":");
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < 32; i++) {
uint64_t *q = aa64_vfp_qreg(env, i);
- uint64_t vlo = q[0];
- uint64_t vhi = q[1];
- cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "%c",
- i, vhi, vlo, (i & 1 ? '\n' : ' '));
+ cpu_fprintf(f, "Q%02d=%016" PRIx64 ":%016" PRIx64 "%s",
+ i, q[1], q[0], (i & 1 ? "\n" : " "));
}
- cpu_fprintf(f, "FPCR: %08x FPSR: %08x\n",
- vfp_get_fpcr(env), vfp_get_fpsr(env));
}
}
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 374051cd20..667879564f 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1625,7 +1625,7 @@ static void do_sat_addsub_64(TCGv_i64 reg, TCGv_i64 val,
bool u, bool d)
/* Detect signed overflow for subtraction. */
tcg_gen_xor_i64(t0, reg, val);
tcg_gen_sub_i64(t1, reg, val);
- tcg_gen_xor_i64(reg, reg, t0);
+ tcg_gen_xor_i64(reg, reg, t1);
tcg_gen_and_i64(t0, t0, reg);
/* Bound the result. */
@@ -3173,19 +3173,19 @@ static bool trans_CTERM(DisasContext *s, arg_CTERM *a,
uint32_t insn)
static bool trans_WHILE(DisasContext *s, arg_WHILE *a, uint32_t insn)
{
- if (!sve_access_check(s)) {
- return true;
- }
-
- TCGv_i64 op0 = read_cpu_reg(s, a->rn, 1);
- TCGv_i64 op1 = read_cpu_reg(s, a->rm, 1);
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 op0, op1, t0, t1, tmax;
TCGv_i32 t2, t3;
TCGv_ptr ptr;
unsigned desc, vsz = vec_full_reg_size(s);
TCGCond cond;
+ if (!sve_access_check(s)) {
+ return true;
+ }
+
+ op0 = read_cpu_reg(s, a->rn, 1);
+ op1 = read_cpu_reg(s, a->rm, 1);
+
if (!a->sf) {
if (a->u) {
tcg_gen_ext32u_i64(op0, op0);
@@ -3198,32 +3198,47 @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a,
uint32_t insn)
/* For the helper, compress the different conditions into a computation
* of how many iterations for which the condition is true.
- *
- * This is slightly complicated by 0 <= UINT64_MAX, which is nominally
- * 2**64 iterations, overflowing to 0. Of course, predicate registers
- * aren't that large, so any value >= predicate size is sufficient.
*/
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
tcg_gen_sub_i64(t0, op1, op0);
- /* t0 = MIN(op1 - op0, vsz). */
- tcg_gen_movi_i64(t1, vsz);
- tcg_gen_umin_i64(t0, t0, t1);
+ tmax = tcg_const_i64(vsz >> a->esz);
if (a->eq) {
/* Equality means one more iteration. */
tcg_gen_addi_i64(t0, t0, 1);
+
+ /* If op1 is max (un)signed integer (and the only time the addition
+ * above could overflow), then we produce an all-true predicate by
+ * setting the count to the vector length. This is because the
+ * pseudocode is described as an increment + compare loop, and the
+ * max integer would always compare true.
+ */
+ tcg_gen_movi_i64(t1, (a->sf
+ ? (a->u ? UINT64_MAX : INT64_MAX)
+ : (a->u ? UINT32_MAX : INT32_MAX)));
+ tcg_gen_movcond_i64(TCG_COND_EQ, t0, op1, t1, tmax, t0);
}
- /* t0 = (condition true ? t0 : 0). */
+ /* Bound to the maximum. */
+ tcg_gen_umin_i64(t0, t0, tmax);
+ tcg_temp_free_i64(tmax);
+
+ /* Set the count to zero if the condition is false. */
cond = (a->u
? (a->eq ? TCG_COND_LEU : TCG_COND_LTU)
: (a->eq ? TCG_COND_LE : TCG_COND_LT));
tcg_gen_movi_i64(t1, 0);
tcg_gen_movcond_i64(cond, t0, op0, op1, t0, t1);
+ tcg_temp_free_i64(t1);
+ /* Since we're bounded, pass as a 32-bit type. */
t2 = tcg_temp_new_i32();
tcg_gen_extrl_i64_i32(t2, t0);
tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
+
+ /* Scale elements to bits. */
+ tcg_gen_shli_i32(t2, t2, a->esz);
desc = (vsz / 8) - 2;
desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
@@ -4078,7 +4093,7 @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn,
int pg,
static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
{
- return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_sh);
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sh);
}
static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
@@ -4088,7 +4103,7 @@ static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz
*a, uint32_t insn)
static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
{
- return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_dh);
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_dh);
}
static bool trans_FCVT_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
@@ -4357,12 +4372,11 @@ static bool trans_UCVTF_dd(DisasContext *s, arg_rpr_esz
*a, uint32_t insn)
* The load should begin at the address Rn + IMM.
*/
-static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
- int rn, int imm)
+static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
{
- uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
- uint32_t len_remain = len % 8;
- uint32_t nparts = len / 8 + ctpop8(len_remain);
+ int len_align = QEMU_ALIGN_DOWN(len, 8);
+ int len_remain = len % 8;
+ int nparts = len / 8 + ctpop8(len_remain);
int midx = get_mem_index(s);
TCGv_i64 addr, t0, t1;
@@ -4443,12 +4457,11 @@ static void do_ldr(DisasContext *s, uint32_t vofs,
uint32_t len,
}
/* Similarly for stores. */
-static void do_str(DisasContext *s, uint32_t vofs, uint32_t len,
- int rn, int imm)
+static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
{
- uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
- uint32_t len_remain = len % 8;
- uint32_t nparts = len / 8 + ctpop8(len_remain);
+ int len_align = QEMU_ALIGN_DOWN(len, 8);
+ int len_remain = len % 8;
+ int nparts = len / 8 + ctpop8(len_remain);
int midx = get_mem_index(s);
TCGv_i64 addr, t0;
@@ -4652,8 +4665,7 @@ static bool trans_LD_zprr(DisasContext *s, arg_rprr_load
*a, uint32_t insn)
}
if (sve_access_check(s)) {
TCGv_i64 addr = new_tmp_a64(s);
- tcg_gen_muli_i64(addr, cpu_reg(s, a->rm),
- (a->nreg + 1) << dtype_msz(a->dtype));
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
}
@@ -4806,6 +4818,7 @@ static bool trans_LD1R_zpri(DisasContext *s,
arg_rpri_load *a, uint32_t insn)
unsigned vsz = vec_full_reg_size(s);
unsigned psz = pred_full_reg_size(s);
unsigned esz = dtype_esz[a->dtype];
+ unsigned msz = dtype_msz(a->dtype);
TCGLabel *over = gen_new_label();
TCGv_i64 temp;
@@ -4829,7 +4842,7 @@ static bool trans_LD1R_zpri(DisasContext *s,
arg_rpri_load *a, uint32_t insn)
/* Load the data. */
temp = tcg_temp_new_i64();
- tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << esz);
+ tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << msz);
tcg_gen_qemu_ld_i64(temp, temp, get_mem_index(s),
s->be_data | dtype_mop[a->dtype]);
@@ -4885,7 +4898,7 @@ static bool trans_ST_zprr(DisasContext *s, arg_rprr_store
*a, uint32_t insn)
}
if (sve_access_check(s)) {
TCGv_i64 addr = new_tmp_a64(s);
- tcg_gen_muli_i64(addr, cpu_reg(s, a->rm), (a->nreg + 1) << a->msz);
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->msz);
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 723e02221e..3ac627978f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -849,6 +849,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
},
.cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
.tcg_features = TCG_EXT3_FEATURES,
+ /*
+ * TOPOEXT is always allowed but can't be enabled blindly by
+ * "-cpu host", as it requires consistent cache topology info
+ * to be provided so it doesn't confuse guests.
+ */
+ .no_autoenable_flags = CPUID_EXT3_TOPOEXT,
},
[FEAT_C000_0001_EDX] = {
.feat_names = {
diff --git a/target/ppc/translate/vmx-ops.inc.c
b/target/ppc/translate/vmx-ops.inc.c
index 139f80cb24..84e05fb827 100644
--- a/target/ppc/translate/vmx-ops.inc.c
+++ b/target/ppc/translate/vmx-ops.inc.c
@@ -143,7 +143,7 @@ GEN_VXFORM(vaddsws, 0, 14),
GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
GEN_VXFORM(vsubuws, 0, 26),
-GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_NONE, PPC2_ISA300),
+GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_ALTIVEC, PPC2_ISA300),
GEN_VXFORM(vsubshs, 0, 29),
GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE),
GEN_VXFORM_207(vadduqm, 0, 4),
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index acb0f3d4af..aafa740f61 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -130,7 +130,7 @@ out:
}
return;
default:
- hw_error("Unhandled diag308 subcode %" PRIx64, subcode);
+ s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
break;
}
}
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index d22cdcdb16..c626583cd9 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -2288,7 +2288,7 @@ static void translate_s32c1i(DisasContext *dc, const
uint32_t arg[],
gen_load_store_alignment(dc, 2, addr, true);
gen_check_atomctl(dc, addr);
tcg_gen_atomic_cmpxchg_i32(cpu_R[arg[0]], addr, cpu_SR[SCOMPARE1],
- tmp, dc->cring, MO_32);
+ tmp, dc->cring, MO_TEUL);
tcg_temp_free(addr);
tcg_temp_free(tmp);
}
@@ -4706,7 +4706,7 @@ static void translate_movcond_s(DisasContext *dc, const
uint32_t arg[],
tcg_gen_movcond_i32(par[0], cpu_FR[arg[0]],
cpu_R[arg[2]], zero,
- cpu_FR[arg[1]], cpu_FR[arg[2]]);
+ cpu_FR[arg[1]], cpu_FR[arg[0]]);
tcg_temp_free(zero);
}
}
@@ -4867,7 +4867,7 @@ static const XtensaOpcodeOps fpu2000_ops[] = {
.translate = translate_compare_s,
.par = (const uint32_t[]){COMPARE_OLT},
}, {
- .name = "rfr.s",
+ .name = "rfr",
.translate = translate_rfr_s,
}, {
.name = "round.s",
@@ -4921,7 +4921,7 @@ static const XtensaOpcodeOps fpu2000_ops[] = {
.translate = translate_ftoi_s,
.par = (const uint32_t[]){float_round_to_zero, true},
}, {
- .name = "wfr.s",
+ .name = "wfr",
.translate = translate_wfr_s,
},
};
diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT
index 99f05a5027..c6adfe32d5 100644
Binary files a/tests/acpi-test-data/pc/DSDT and b/tests/acpi-test-data/pc/DSDT
differ
diff --git a/tests/acpi-test-data/pc/DSDT.bridge
b/tests/acpi-test-data/pc/DSDT.bridge
index cf23343e64..f01fa3ad4e 100644
Binary files a/tests/acpi-test-data/pc/DSDT.bridge and
b/tests/acpi-test-data/pc/DSDT.bridge differ
diff --git a/tests/acpi-test-data/pc/DSDT.cphp
b/tests/acpi-test-data/pc/DSDT.cphp
index c99c49f437..3295d81c7f 100644
Binary files a/tests/acpi-test-data/pc/DSDT.cphp and
b/tests/acpi-test-data/pc/DSDT.cphp differ
diff --git a/tests/acpi-test-data/pc/DSDT.dimmpxm
b/tests/acpi-test-data/pc/DSDT.dimmpxm
index 38661cb13e..f6ec911b11 100644
Binary files a/tests/acpi-test-data/pc/DSDT.dimmpxm and
b/tests/acpi-test-data/pc/DSDT.dimmpxm differ
diff --git a/tests/acpi-test-data/pc/DSDT.ipmikcs
b/tests/acpi-test-data/pc/DSDT.ipmikcs
index 5e970fda72..2633a8cecf 100644
Binary files a/tests/acpi-test-data/pc/DSDT.ipmikcs and
b/tests/acpi-test-data/pc/DSDT.ipmikcs differ
diff --git a/tests/acpi-test-data/pc/DSDT.memhp
b/tests/acpi-test-data/pc/DSDT.memhp
index 1fe6871aa2..e31ef50296 100644
Binary files a/tests/acpi-test-data/pc/DSDT.memhp and
b/tests/acpi-test-data/pc/DSDT.memhp differ
diff --git a/tests/acpi-test-data/pc/DSDT.numamem
b/tests/acpi-test-data/pc/DSDT.numamem
index 224cfdd9e9..71a975b3e2 100644
Binary files a/tests/acpi-test-data/pc/DSDT.numamem and
b/tests/acpi-test-data/pc/DSDT.numamem differ
diff --git a/tests/acpi-test-data/pc/SRAT.dimmpxm
b/tests/acpi-test-data/pc/SRAT.dimmpxm
index 5aa6f693ef..f5c0267ea2 100644
Binary files a/tests/acpi-test-data/pc/SRAT.dimmpxm and
b/tests/acpi-test-data/pc/SRAT.dimmpxm differ
diff --git a/tests/acpi-test-data/pc/SRAT.memhp
b/tests/acpi-test-data/pc/SRAT.memhp
index 5de8a100a4..e508b4ae3c 100644
Binary files a/tests/acpi-test-data/pc/SRAT.memhp and
b/tests/acpi-test-data/pc/SRAT.memhp differ
diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT
index aa402cca66..7576ffcd05 100644
Binary files a/tests/acpi-test-data/q35/DSDT and
b/tests/acpi-test-data/q35/DSDT differ
diff --git a/tests/acpi-test-data/q35/DSDT.bridge
b/tests/acpi-test-data/q35/DSDT.bridge
index fc3e79c583..c623cc5d72 100644
Binary files a/tests/acpi-test-data/q35/DSDT.bridge and
b/tests/acpi-test-data/q35/DSDT.bridge differ
diff --git a/tests/acpi-test-data/q35/DSDT.cphp
b/tests/acpi-test-data/q35/DSDT.cphp
index fd3cb34218..7ac526e466 100644
Binary files a/tests/acpi-test-data/q35/DSDT.cphp and
b/tests/acpi-test-data/q35/DSDT.cphp differ
diff --git a/tests/acpi-test-data/q35/DSDT.dimmpxm
b/tests/acpi-test-data/q35/DSDT.dimmpxm
index 14904e8ea2..3837792dec 100644
Binary files a/tests/acpi-test-data/q35/DSDT.dimmpxm and
b/tests/acpi-test-data/q35/DSDT.dimmpxm differ
diff --git a/tests/acpi-test-data/q35/DSDT.ipmibt
b/tests/acpi-test-data/q35/DSDT.ipmibt
index 332237529e..c7f431f058 100644
Binary files a/tests/acpi-test-data/q35/DSDT.ipmibt and
b/tests/acpi-test-data/q35/DSDT.ipmibt differ
diff --git a/tests/acpi-test-data/q35/DSDT.memhp
b/tests/acpi-test-data/q35/DSDT.memhp
index f0a27e1a30..8fba0baf79 100644
Binary files a/tests/acpi-test-data/q35/DSDT.memhp and
b/tests/acpi-test-data/q35/DSDT.memhp differ
diff --git a/tests/acpi-test-data/q35/DSDT.numamem
b/tests/acpi-test-data/q35/DSDT.numamem
index 8c9fa445b0..6c0d4f2bcb 100644
Binary files a/tests/acpi-test-data/q35/DSDT.numamem and
b/tests/acpi-test-data/q35/DSDT.numamem differ
diff --git a/tests/acpi-test-data/q35/SRAT.dimmpxm
b/tests/acpi-test-data/q35/SRAT.dimmpxm
index 5aa6f693ef..f5c0267ea2 100644
Binary files a/tests/acpi-test-data/q35/SRAT.dimmpxm and
b/tests/acpi-test-data/q35/SRAT.dimmpxm differ
diff --git a/tests/acpi-test-data/q35/SRAT.memhp
b/tests/acpi-test-data/q35/SRAT.memhp
index 5de8a100a4..e508b4ae3c 100644
Binary files a/tests/acpi-test-data/q35/SRAT.memhp and
b/tests/acpi-test-data/q35/SRAT.memhp differ
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index c20ac7da87..9336ab6ff5 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -234,6 +234,12 @@ class TestSingleBlockdev(TestSingleDrive):
result = self.vm.qmp("blockdev-add", **args)
self.assert_qmp(result, 'return', {})
+ def test_mirror_to_self(self):
+ result = self.vm.qmp(self.qmp_cmd, job_id='job0',
+ device=self.qmp_target, sync='full',
+ target=self.qmp_target)
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
test_large_cluster = None
test_image_not_found = None
test_small_buffer2 = None
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
index c28b392b87..e071d0b261 100644
--- a/tests/qemu-iotests/041.out
+++ b/tests/qemu-iotests/041.out
@@ -1,5 +1,5 @@
-.....................................................................................
+........................................................................................
----------------------------------------------------------------------
-Ran 85 tests
+Ran 88 tests
OK
diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out
index 2e71cff3ce..b10c71db03 100644
--- a/tests/qemu-iotests/067.out
+++ b/tests/qemu-iotests/067.out
@@ -385,6 +385,7 @@ Testing: -device virtio-scsi -device scsi-cd,id=cd0
{
"return": [
{
+ "io-status": "ok",
"device": "",
"locked": false,
"removable": true,
diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
new file mode 100755
index 0000000000..ff851ec431
--- /dev/null
+++ b/tests/qemu-iotests/229
@@ -0,0 +1,95 @@
+#!/bin/bash
+#
+# Test for force canceling a running blockjob that is paused in
+# an error state.
+#
+# Copyright (C) 2018 Red Hat, Inc.
+#
+# 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/>.
+#
+
+# creator
+owner=jcody@xxxxxxxxxx
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_qemu
+ _cleanup_test_img
+ rm -f "$TEST_IMG" "$DEST_IMG"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+# Needs backing file and backing format support
+_supported_fmt qcow2 qed
+_supported_proto file
+_supported_os Linux
+
+
+DEST_IMG="$TEST_DIR/d.$IMGFMT"
+TEST_IMG="$TEST_DIR/b.$IMGFMT"
+
+_make_test_img 2M
+
+# destination for mirror will be too small, causing error
+TEST_IMG=$DEST_IMG _make_test_img 1M
+
+$QEMU_IO -c 'write 0 2M' "$TEST_IMG" | _filter_qemu_io
+
+_launch_qemu -drive id=testdisk,file="$TEST_IMG",format="$IMGFMT"
+
+_send_qemu_cmd $QEMU_HANDLE \
+ "{'execute': 'qmp_capabilities'}" \
+ 'return'
+
+echo
+echo '=== Starting drive-mirror, causing error & stop ==='
+echo
+
+_send_qemu_cmd $QEMU_HANDLE \
+ "{'execute': 'drive-mirror',
+ 'arguments': {'device': 'testdisk',
+ 'mode': 'absolute-paths',
+ 'format': '$IMGFMT',
+ 'target': '$DEST_IMG',
+ 'sync': 'full',
+ 'mode': 'existing',
+ 'on-source-error': 'stop',
+ 'on-target-error': 'stop' }}" \
+ "JOB_STATUS_CHANGE.*pause"
+
+echo
+echo '=== Force cancel job paused in error state ==='
+echo
+
+success_or_failure="y" _send_qemu_cmd $QEMU_HANDLE \
+ "{'execute': 'block-job-cancel',
+ 'arguments': { 'device': 'testdisk',
+ 'force': true}}" \
+ "BLOCK_JOB_CANCELLED" "Assertion"
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
new file mode 100644
index 0000000000..4c4112805f
--- /dev/null
+++ b/tests/qemu-iotests/229.out
@@ -0,0 +1,23 @@
+QA output created by 229
+Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=2097152
+Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=1048576
+wrote 2097152/2097152 bytes at offset 0
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+
+=== Starting drive-mirror, causing error & stop ===
+
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write",
"action": "stop"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "testdisk"}}
+
+=== Force cancel job paused in error state ===
+
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write",
"action": "stop"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event":
"BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset":
1048576, "speed": 0, "type": "mirror"}}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |