summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.mailmap18
-rw-r--r--VERSION2
-rw-r--r--accel/tcg/tcg-runtime-gvec.c2
-rw-r--r--block/file-posix.c19
-rw-r--r--block/gluster.c21
-rw-r--r--block/rbd.c7
-rw-r--r--blockjob.c28
-rwxr-xr-xconfigure11
-rw-r--r--contrib/libvhost-user/libvhost-user.h1
-rw-r--r--docs/interop/vhost-user.txt21
-rw-r--r--dump.c4
-rw-r--r--exec.c1
-rw-r--r--gdbstub.c3
-rw-r--r--hw/block/vhost-user-blk.c4
-rw-r--r--hw/char/virtio-serial-bus.c7
-rw-r--r--hw/dma/i82374.c9
-rw-r--r--hw/i386/kvm/clock.c14
-rw-r--r--hw/s390x/ipl.c112
-rw-r--r--hw/s390x/s390-virtio-ccw.c5
-rw-r--r--hw/scsi/scsi-disk.c39
-rw-r--r--hw/scsi/scsi-generic.c48
-rw-r--r--hw/vfio/ccw.c2
-rw-r--r--hw/vfio/common.c11
-rw-r--r--hw/vfio/trace-events1
-rw-r--r--hw/virtio/vhost-user.c22
-rw-r--r--hw/virtio/vhost.c16
-rw-r--r--include/hw/scsi/scsi.h2
-rw-r--r--include/qemu/memfd.h1
-rw-r--r--include/ui/console.h2
-rw-r--r--linux-user/signal.c8
-rw-r--r--linux-user/syscall.c7
-rw-r--r--linux-user/syscall_defs.h5
-rwxr-xr-xpc-bios/hppa-firmware.imgbin215696 -> 215936 bytes
-rw-r--r--pc-bios/s390-ccw.imgbin34568 -> 30520 bytes
-rw-r--r--pc-bios/s390-ccw/bootmap.c7
-rw-r--r--pc-bios/s390-ccw/iplb.h15
-rw-r--r--pc-bios/s390-ccw/virtio.c2
-rw-r--r--pc-bios/s390-netboot.imgbin83776 -> 83856 bytes
-rw-r--r--qemu-doc.texi364
-rw-r--r--qemu-options.hx11
m---------roms/seabios-hppa0
-rwxr-xr-xscripts/checkpatch.pl15
-rwxr-xr-xscripts/device-crash-test1
-rw-r--r--scsi/qemu-pr-helper.c18
-rw-r--r--target/i386/cpu.c1
-rw-r--r--target/i386/cpu.h1
-rw-r--r--target/i386/kvm.c56
-rw-r--r--target/i386/sev.c4
-rw-r--r--target/i386/translate.c6
-rw-r--r--target/i386/whpx-all.c79
-rw-r--r--target/s390x/helper.c10
-rw-r--r--target/s390x/kvm.c2
-rw-r--r--target/s390x/mmu_helper.c2
-rwxr-xr-xtests/docker/common.rc4
-rw-r--r--tests/docker/dockerfiles/fedora.docker13
-rwxr-xr-xtests/docker/run2
-rw-r--r--tests/qemu-iotests/051.pc.out20
-rwxr-xr-xtests/qemu-iotests/10624
-rw-r--r--tests/qemu-iotests/106.out10
-rwxr-xr-xtests/qemu-iotests/12247
-rw-r--r--tests/qemu-iotests/122.out33
-rwxr-xr-xtests/qemu-iotests/1866
-rw-r--r--tests/qemu-iotests/186.out84
-rwxr-xr-xtests/qemu-iotests/2082
-rwxr-xr-xtests/qemu-iotests/check4
-rw-r--r--tests/qemu-iotests/common.config1
-rw-r--r--tests/qemu-iotests/common.filter5
-rw-r--r--tests/test-crypto-tlssession.c1
-rw-r--r--tests/test-io-channel-tls.c1
-rwxr-xr-xtests/vm/basevm.py5
-rw-r--r--ui/console.c15
-rw-r--r--ui/gtk.c4
-rw-r--r--ui/sdl2-gl.c2
-rw-r--r--ui/sdl2-input.c46
-rw-r--r--util/memfd.c34
-rw-r--r--util/sys_membarrier.c6
76 files changed, 1045 insertions, 371 deletions
diff --git a/.mailmap b/.mailmap
index cf689b9ec9..778a4d4e2c 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,6 +1,7 @@
-# This mailmap just translates the weird addresses from the original import into git
-# into proper addresses so that they are counted properly in git shortlog output.
-#
+# This mailmap fixes up author names/addresses.
+
+# The first section translates weird addresses from the original git import
+# into proper addresses so that they are counted properly by git shortlog.
Andrzej Zaborowski <balrogg@gmail.com> balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>
Anthony Liguori <anthony@codemonkey.ws> aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
@@ -15,10 +16,19 @@ Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com>
Paul Burton <paul.burton@mips.com> <paul@archlinuxmips.org>
Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>
+
# There is also a:
# (no author) <(no author)@c046a42c-6fe2-441c-8c8c-71466251a162>
# for the cvs2svn initialization commit e63c3dc74bf.
-#
+
+# Next, translate a few commits where mailman rewrote the From: line due
+# to strict SPF, although we prefer to avoid adding more entries like that.
+Ed Swierk <eswierk@skyportsystems.com> Ed Swierk via Qemu-devel <qemu-devel@nongnu.org>
+Ian McKellar <ianloic@google.com> Ian McKellar via Qemu-devel <qemu-devel@nongnu.org>
+Julia Suvorova <jusual@mail.ru> Julia Suvorova via Qemu-devel <qemu-devel@nongnu.org>
+Justin Terry (VM) <juterry@microsoft.com> Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org>
+
+
# Also list preferred name forms where people have changed their
# git author config
Daniel P. Berrangé <berrange@redhat.com>
diff --git a/VERSION b/VERSION
index 5610569c0d..d7b11949fc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.11.91
+2.11.92
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 8bf8d63912..90340e56e0 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -705,7 +705,7 @@ void HELPER(NAME)(void *d, void *a, void *b, uint32_t desc) \
{ \
intptr_t oprsz = simd_oprsz(desc); \
intptr_t i; \
- for (i = 0; i < oprsz; i += sizeof(vec64)) { \
+ for (i = 0; i < oprsz; i += sizeof(TYPE)) { \
*(TYPE *)(d + i) = DO_CMP0(*(TYPE *)(a + i) OP *(TYPE *)(b + i)); \
} \
clear_high(d, oprsz, desc); \
diff --git a/block/file-posix.c b/block/file-posix.c
index d7fb772c14..3794c0007a 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1701,6 +1701,7 @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc,
case PREALLOC_MODE_FULL:
{
int64_t num = 0, left = offset - current_length;
+ off_t seek_result;
/*
* Knowing the final size from the beginning could allow the file
@@ -1715,8 +1716,8 @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc,
buf = g_malloc0(65536);
- result = lseek(fd, current_length, SEEK_SET);
- if (result < 0) {
+ seek_result = lseek(fd, current_length, SEEK_SET);
+ if (seek_result < 0) {
result = -errno;
error_setg_errno(errp, -result,
"Failed to seek to the old end of file");
@@ -2114,7 +2115,12 @@ static int find_allocation(BlockDriverState *bs, off_t start,
if (offs < 0) {
return -errno; /* D3 or D4 */
}
- assert(offs >= start);
+
+ if (offs < start) {
+ /* This is not a valid return by lseek(). We are safe to just return
+ * -EIO in this case, and we'll treat it like D4. */
+ return -EIO;
+ }
if (offs > start) {
/* D2: in hole, next data at offs */
@@ -2146,7 +2152,12 @@ static int find_allocation(BlockDriverState *bs, off_t start,
if (offs < 0) {
return -errno; /* D1 and (H3 or H4) */
}
- assert(offs >= start);
+
+ if (offs < start) {
+ /* This is not a valid return by lseek(). We are safe to just return
+ * -EIO in this case, and we'll treat it like H4. */
+ return -EIO;
+ }
if (offs > start) {
/*
diff --git a/block/gluster.c b/block/gluster.c
index 296e036b3d..4adc1a875b 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -167,7 +167,12 @@ static QemuOptsList runtime_unix_opts = {
{
.name = GLUSTER_OPT_SOCKET,
.type = QEMU_OPT_STRING,
- .help = "socket file path)",
+ .help = "socket file path (legacy)",
+ },
+ {
+ .name = GLUSTER_OPT_PATH,
+ .type = QEMU_OPT_STRING,
+ .help = "socket file path (QAPI)",
},
{ /* end of list */ }
},
@@ -615,10 +620,18 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
goto out;
}
- ptr = qemu_opt_get(opts, GLUSTER_OPT_SOCKET);
+ ptr = qemu_opt_get(opts, GLUSTER_OPT_PATH);
+ if (!ptr) {
+ ptr = qemu_opt_get(opts, GLUSTER_OPT_SOCKET);
+ } else if (qemu_opt_get(opts, GLUSTER_OPT_SOCKET)) {
+ error_setg(&local_err,
+ "Conflicting parameters 'path' and 'socket'");
+ error_append_hint(&local_err, GERR_INDEX_HINT, i);
+ goto out;
+ }
if (!ptr) {
error_setg(&local_err, QERR_MISSING_PARAMETER,
- GLUSTER_OPT_SOCKET);
+ GLUSTER_OPT_PATH);
error_append_hint(&local_err, GERR_INDEX_HINT, i);
goto out;
}
@@ -684,7 +697,7 @@ static int qemu_gluster_parse(BlockdevOptionsGluster *gconf,
"file.server.0.host=1.2.3.4,"
"file.server.0.port=24007,"
"file.server.1.transport=unix,"
- "file.server.1.socket=/var/run/glusterd.socket ..."
+ "file.server.1.path=/var/run/glusterd.socket ..."
"\n");
return ret;
}
diff --git a/block/rbd.c b/block/rbd.c
index 5b64849dc6..c9359d0ad8 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -623,6 +623,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
BlockdevOptionsRbd *opts = NULL;
Visitor *v;
QObject *crumpled = NULL;
+ const QDictEntry *e;
Error *local_err = NULL;
const char *filename;
char *keypairs, *secretid;
@@ -671,6 +672,12 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
goto out;
}
+ /* Remove the processed options from the QDict (the visitor processes
+ * _all_ options in the QDict) */
+ while ((e = qdict_first(options))) {
+ qdict_del(options, e->key);
+ }
+
r = qemu_rbd_connect(&s->cluster, &s->io_ctx, opts,
!(flags & BDRV_O_NOCACHE), keypairs, secretid, errp);
if (r < 0) {
diff --git a/blockjob.c b/blockjob.c
index ef3ed69ff1..27f957e571 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -75,10 +75,8 @@ static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
"allowed" : "disallowed",
- qapi_enum_lookup(&BlockJobStatus_lookup,
- s0),
- qapi_enum_lookup(&BlockJobStatus_lookup,
- s1));
+ BlockJobStatus_str(s0),
+ BlockJobStatus_str(s1));
assert(BlockJobSTT[s0][s1]);
job->status = s1;
}
@@ -86,17 +84,15 @@ static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
{
assert(bv >= 0 && bv <= BLOCK_JOB_VERB__MAX);
- trace_block_job_apply_verb(job, qapi_enum_lookup(&BlockJobStatus_lookup,
- job->status),
- qapi_enum_lookup(&BlockJobVerb_lookup, bv),
+ trace_block_job_apply_verb(job, BlockJobStatus_str(job->status),
+ BlockJobVerb_str(bv),
BlockJobVerbTable[bv][job->status] ?
"allowed" : "prohibited");
if (BlockJobVerbTable[bv][job->status]) {
return 0;
}
error_setg(errp, "Job '%s' in state '%s' cannot accept command verb '%s'",
- job->id, qapi_enum_lookup(&BlockJobStatus_lookup, job->status),
- qapi_enum_lookup(&BlockJobVerb_lookup, bv));
+ job->id, BlockJobStatus_str(job->status), BlockJobVerb_str(bv));
return -EPERM;
}
@@ -204,6 +200,15 @@ void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
block_job_txn_ref(txn);
}
+static void block_job_txn_del_job(BlockJob *job)
+{
+ if (job->txn) {
+ QLIST_REMOVE(job, txn_list);
+ block_job_txn_unref(job->txn);
+ job->txn = NULL;
+ }
+}
+
static void block_job_pause(BlockJob *job)
{
job->pause_count++;
@@ -232,6 +237,7 @@ void block_job_unref(BlockJob *job)
{
if (--job->refcnt == 0) {
assert(job->status == BLOCK_JOB_STATUS_NULL);
+ assert(!job->txn);
BlockDriverState *bs = blk_bs(job->blk);
QLIST_REMOVE(job, job_list);
bs->job = NULL;
@@ -392,6 +398,7 @@ static void block_job_decommission(BlockJob *job)
job->busy = false;
job->paused = false;
job->deferred_to_main_loop = true;
+ block_job_txn_del_job(job);
block_job_state_transition(job, BLOCK_JOB_STATUS_NULL);
block_job_unref(job);
}
@@ -481,8 +488,7 @@ static int block_job_finalize_single(BlockJob *job)
}
}
- QLIST_REMOVE(job, txn_list);
- block_job_txn_unref(job->txn);
+ block_job_txn_del_job(job);
block_job_conclude(job);
return 0;
}
diff --git a/configure b/configure
index 4d0e92c96c..752dd9ef32 100755
--- a/configure
+++ b/configure
@@ -1497,16 +1497,19 @@ Advanced options (experts only):
--install=INSTALL use specified install [$install]
--python=PYTHON use specified python [$python]
--smbd=SMBD use specified smbd [$smbd]
+ --with-git=GIT use specified git [$git]
--static enable static build [$static]
--mandir=PATH install man pages in PATH
--datadir=PATH install firmware in PATH$confsuffix
--docdir=PATH install documentation in PATH$confsuffix
--bindir=PATH install binaries in PATH
--libdir=PATH install libraries in PATH
+ --libexecdir=PATH install helper binaries in PATH
--sysconfdir=PATH install config in PATH$confsuffix
--localstatedir=PATH install local state in PATH (set at runtime on win32)
--firmwarepath=PATH search PATH for firmware files
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
+ --with-pkgversion=VERS use specified string as sub-version of the package
--enable-debug enable common debug build options
--enable-sanitizers enable default sanitizers
--disable-strip disable stripping binaries
@@ -5054,6 +5057,14 @@ static S2 c2;
static S4 c4;
static S8 c8;
static int i;
+void helper(void *d, void *a, int shift, int i);
+void helper(void *d, void *a, int shift, int i)
+{
+ *(U1 *)(d + i) = *(U1 *)(a + i) << shift;
+ *(U2 *)(d + i) = *(U2 *)(a + i) << shift;
+ *(U4 *)(d + i) = *(U4 *)(a + i) << shift;
+ *(U8 *)(d + i) = *(U8 *)(a + i) << shift;
+}
int main(void)
{
a1 += b1; a2 += b2; a4 += b4; a8 += b8;
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index 79f7a53ee8..b27075ea3b 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -50,6 +50,7 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
+ VHOST_USER_PROTOCOL_F_CONFIG = 9,
VHOST_USER_PROTOCOL_F_MAX
};
diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
index c058c407df..534caab18a 100644
--- a/docs/interop/vhost-user.txt
+++ b/docs/interop/vhost-user.txt
@@ -379,6 +379,7 @@ Protocol features
#define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
+#define VHOST_USER_PROTOCOL_F_CONFIG 9
Master message types
--------------------
@@ -664,7 +665,8 @@ Master message types
Master payload: virtio device config space
Slave payload: virtio device config space
- Submitted by the vhost-user master to fetch the contents of the virtio
+ When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is
+ submitted by the vhost-user master to fetch the contents of the virtio
device configuration space, vhost-user slave's payload size MUST match
master's request, vhost-user slave uses zero length of payload to
indicate an error to vhost-user master. The vhost-user master may
@@ -677,7 +679,8 @@ Master message types
Master payload: virtio device config space
Slave payload: N/A
- Submitted by the vhost-user master when the Guest changes the virtio
+ When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is
+ submitted by the vhost-user master when the Guest changes the virtio
device configuration space and also can be used for live migration
on the destination host. The vhost-user slave must check the flags
field, and slaves MUST NOT accept SET_CONFIG for read-only
@@ -766,13 +769,13 @@ Slave message types
Slave payload: N/A
Master payload: N/A
- Vhost-user slave sends such messages to notify that the virtio device's
- configuration space has changed, for those host devices which can support
- such feature, host driver can send VHOST_USER_GET_CONFIG message to slave
- to get the latest content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is
- negotiated, and slave set the VHOST_USER_NEED_REPLY flag, master must
- respond with zero when operation is successfully completed, or non-zero
- otherwise.
+ When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, vhost-user slave sends
+ such messages to notify that the virtio device's configuration space has
+ changed, for those host devices which can support such feature, host
+ driver can send VHOST_USER_GET_CONFIG message to slave to get the latest
+ content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is negotiated, and slave set
+ the VHOST_USER_NEED_REPLY flag, master must respond with zero when
+ operation is successfully completed, or non-zero otherwise.
VHOST_USER_PROTOCOL_F_REPLY_ACK:
-------------------------------
diff --git a/dump.c b/dump.c
index 669f715274..b54cd42b21 100644
--- a/dump.c
+++ b/dump.c
@@ -814,7 +814,7 @@ static void create_header32(DumpState *s, Error **errp)
size = sizeof(DiskDumpHeader32);
dh = g_malloc0(size);
- strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
+ memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
dh->header_version = cpu_to_dump32(s, 6);
block_size = s->dump_info.page_size;
dh->block_size = cpu_to_dump32(s, block_size);
@@ -926,7 +926,7 @@ static void create_header64(DumpState *s, Error **errp)
size = sizeof(DiskDumpHeader64);
dh = g_malloc0(size);
- strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
+ memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
dh->header_version = cpu_to_dump32(s, 6);
block_size = s->dump_info.page_size;
dh->block_size = cpu_to_dump32(s, block_size);
diff --git a/exec.c b/exec.c
index c09bd93df3..02b1efebb7 100644
--- a/exec.c
+++ b/exec.c
@@ -1495,6 +1495,7 @@ static int find_max_supported_pagesize(Object *obj, void *opaque)
mem_path = object_property_get_str(obj, "mem-path", NULL);
if (mem_path) {
long hpsize = qemu_mempath_getpagesize(mem_path);
+ g_free(mem_path);
if (hpsize < *hpsize_min) {
*hpsize_min = hpsize;
}
diff --git a/gdbstub.c b/gdbstub.c
index a76b2fa481..3c3807358c 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -507,6 +507,7 @@ static inline int tohex(int v)
return v - 10 + 'a';
}
+/* writes 2*len+1 bytes in buf */
static void memtohex(char *buf, const uint8_t *mem, int len)
{
int i, c;
@@ -999,8 +1000,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
const char *p;
uint32_t thread;
int ch, reg_size, type, res;
- char buf[MAX_PACKET_LENGTH];
uint8_t mem_buf[MAX_PACKET_LENGTH];
+ char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
uint8_t *registers;
target_ulong addr, len;
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index f840f07dfe..262baca432 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -259,6 +259,8 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
s->dev.vq_index = 0;
s->dev.backend_features = 0;
+ vhost_dev_set_config_notifier(&s->dev, &blk_ops);
+
ret = vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, 0);
if (ret < 0) {
error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
@@ -277,8 +279,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
s->blkcfg.num_queues = s->num_queues;
}
- vhost_dev_set_config_notifier(&s->dev, &blk_ops);
-
return;
vhost_err:
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 9470bd7be7..d2dd8ab502 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -580,13 +580,16 @@ static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
struct virtio_console_config *config =
(struct virtio_console_config *)config_data;
- uint8_t emerg_wr_lo = le32_to_cpu(config->emerg_wr);
VirtIOSerialPort *port = find_first_connected_console(vser);
VirtIOSerialPortClass *vsc;
+ uint8_t emerg_wr_lo;
- if (!config->emerg_wr) {
+ if (!virtio_has_feature(vser->host_features,
+ VIRTIO_CONSOLE_F_EMERG_WRITE) || !config->emerg_wr) {
return;
}
+
+ emerg_wr_lo = le32_to_cpu(config->emerg_wr);
/* Make sure we don't misdetect an emergency write when the guest
* does a short config write after an emergency write. */
config->emerg_wr = 0;
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index 83c87d92e0..892f655a7e 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "hw/isa/isa.h"
#include "hw/dma/i8257.h"
@@ -118,13 +119,19 @@ static const MemoryRegionPortio i82374_portio_list[] = {
static void i82374_realize(DeviceState *dev, Error **errp)
{
I82374State *s = I82374(dev);
+ ISABus *isa_bus = isa_bus_from_device(ISA_DEVICE(dev));
+
+ if (isa_get_dma(isa_bus, 0)) {
+ error_setg(errp, "DMA already initialized on ISA bus");
+ return;
+ }
+ i8257_dma_init(isa_bus, true);
portio_list_init(&s->port_list, OBJECT(s), i82374_portio_list, s,
"i82374");
portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj),
s->iobase);
- i8257_dma_init(isa_bus_from_device(ISA_DEVICE(dev)), true);
memset(s->commands, 0, sizeof(s->commands));
}
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 1707434db3..7dac319403 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -242,6 +242,19 @@ static const VMStateDescription kvmclock_reliable_get_clock = {
};
/*
+ * When migrating, assume the source has an unreliable
+ * KVM_GET_CLOCK unless told otherwise.
+ */
+static int kvmclock_pre_load(void *opaque)
+{
+ KVMClockState *s = opaque;
+
+ s->clock_is_reliable = false;
+
+ return 0;
+}
+
+/*
* When migrating, read the clock just before migration,
* so that the guest clock counts during the events
* between:
@@ -268,6 +281,7 @@ static const VMStateDescription kvmclock_vmsd = {
.name = "kvmclock",
.version_id = 1,
.minimum_version_id = 1,
+ .pre_load = kvmclock_pre_load,
.pre_save = kvmclock_pre_save,
.fields = (VMStateField[]) {
VMSTATE_UINT64(clock, KVMClockState),
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index fdeaec3a58..fb554ab156 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -279,44 +279,52 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
*timeout = cpu_to_be32(splash_time);
}
+static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
+{
+ CcwDevice *ccw_dev = NULL;
+
+ if (dev_st) {
+ VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
+ object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
+ TYPE_VIRTIO_CCW_DEVICE);
+ if (virtio_ccw_dev) {
+ ccw_dev = CCW_DEVICE(virtio_ccw_dev);
+ } else {
+ SCSIDevice *sd = (SCSIDevice *)
+ object_dynamic_cast(OBJECT(dev_st),
+ TYPE_SCSI_DEVICE);
+ if (sd) {
+ SCSIBus *bus = scsi_bus_from_device(sd);
+ VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus);
+ VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw,
+ vdev);
+
+ ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw),
+ TYPE_CCW_DEVICE);
+ }
+ }
+ }
+ return ccw_dev;
+}
+
static bool s390_gen_initial_iplb(S390IPLState *ipl)
{
DeviceState *dev_st;
+ CcwDevice *ccw_dev = NULL;
dev_st = get_boot_device(0);
if (dev_st) {
- VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
- object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
- TYPE_VIRTIO_CCW_DEVICE);
+ ccw_dev = s390_get_ccw_device(dev_st);
+ }
+
+ /*
+ * Currently allow IPL only from CCW devices.
+ */
+ if (ccw_dev) {
SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
TYPE_SCSI_DEVICE);
- VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
- TYPE_VIRTIO_NET);
-
- if (vn) {
- ipl->netboot = true;
- }
- if (virtio_ccw_dev) {
- CcwDevice *ccw_dev = CCW_DEVICE(virtio_ccw_dev);
-
- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
- ipl->iplb.blk0_len =
- cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
- ipl->iplb.pbt = S390_IPL_TYPE_CCW;
- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
- } else if (sd) {
- SCSIBus *bus = scsi_bus_from_device(sd);
- VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus);
- VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw, vdev);
- CcwDevice *ccw_dev;
-
- ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw),
- TYPE_CCW_DEVICE);
- if (!ccw_dev) { /* It might be a PCI device instead */
- return false;
- }
+ if (sd) {
ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
ipl->iplb.blk0_len =
cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
@@ -327,12 +335,25 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
} else {
- return false; /* unknown device */
+ VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
+ TYPE_VIRTIO_NET);
+
+ ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+ ipl->iplb.blk0_len =
+ cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
+ ipl->iplb.pbt = S390_IPL_TYPE_CCW;
+ ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
+ ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
+
+ if (vn) {
+ ipl->netboot = true;
+ }
}
if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) {
ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID;
}
+
return true;
}
@@ -406,7 +427,8 @@ unref_mr:
return img_size;
}
-static bool is_virtio_net_device(IplParameterBlock *iplb)
+static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
+ int virtio_id)
{
uint8_t cssid;
uint8_t ssid;
@@ -426,13 +448,23 @@ static bool is_virtio_net_device(IplParameterBlock *iplb)
sch = css_find_subch(1, cssid, ssid, schid);
if (sch && sch->devno == devno) {
- return sch->id.cu_model == VIRTIO_ID_NET;
+ return sch->id.cu_model == virtio_id;
}
}
}
return false;
}
+static bool is_virtio_net_device(IplParameterBlock *iplb)
+{
+ return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET);
+}
+
+static bool is_virtio_scsi_device(IplParameterBlock *iplb)
+{
+ return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
+}
+
void s390_ipl_update_diag308(IplParameterBlock *iplb)
{
S390IPLState *ipl = get_ipl_device();
@@ -457,6 +489,22 @@ void s390_reipl_request(void)
S390IPLState *ipl = get_ipl_device();
ipl->reipl_requested = true;
+ if (ipl->iplb_valid &&
+ !ipl->netboot &&
+ ipl->iplb.pbt == S390_IPL_TYPE_CCW &&
+ is_virtio_scsi_device(&ipl->iplb)) {
+ CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0));
+
+ if (ccw_dev &&
+ cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno &&
+ (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) {
+ /*
+ * this is the original boot device's SCSI
+ * so restore IPL parameter info from it
+ */
+ ipl->iplb_valid = s390_gen_initial_iplb(ipl);
+ }
+ }
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 864145a7c6..435f7c99e7 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -246,6 +246,7 @@ static void s390_init_ipl_dev(const char *kernel_filename,
{
Object *new = object_new(TYPE_S390_IPL);
DeviceState *dev = DEVICE(new);
+ char *netboot_fw_prop;
if (kernel_filename) {
qdev_prop_set_string(dev, "kernel", kernel_filename);
@@ -256,9 +257,11 @@ static void s390_init_ipl_dev(const char *kernel_filename,
qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
qdev_prop_set_string(dev, "firmware", firmware);
qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
- if (!strlen(object_property_get_str(new, "netboot_fw", &error_abort))) {
+ netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort);
+ if (!strlen(netboot_fw_prop)) {
qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
}
+ g_free(netboot_fw_prop);
object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
new, NULL);
object_unref(new);
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index f5ab767ab5..ded23d36ca 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -714,10 +714,12 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
/* min_io_size and opt_io_size can't be greater than
* max_io_sectors */
- min_io_size =
- MIN_NON_ZERO(min_io_size, max_io_sectors);
- opt_io_size =
- MIN_NON_ZERO(opt_io_size, max_io_sectors);
+ if (min_io_size) {
+ min_io_size = MIN(min_io_size, max_io_sectors);
+ }
+ if (opt_io_size) {
+ opt_io_size = MIN(opt_io_size, max_io_sectors);
+ }
}
/* required VPD size with unmap support */
buflen = 0x40;
@@ -823,7 +825,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
* block characteristics VPD page by default. Not all of SPC-3
* is actually implemented, but we're good enough.
*/
- outbuf[2] = 5;
+ outbuf[2] = s->qdev.default_scsi_version;
outbuf[3] = 2 | 0x10; /* Format 2, HiSup */
if (buflen > 36) {
@@ -2191,7 +2193,11 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
case READ_12:
case READ_16:
DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len);
- if (r->req.cmd.buf[1] & 0xe0) {
+ /* Protection information is not supported. For SCSI versions 2 and
+ * older (as determined by snooping the guest's INQUIRY commands),
+ * there is no RD/WR/VRPROTECT, so skip this check in these versions.
+ */
+ if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) {
goto illegal_request;
}
if (!check_lba_range(s, r->req.cmd.lba, len)) {
@@ -2222,7 +2228,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
* As far as DMA is concerned, we can treat it the same as a write;
* scsi_block_do_sgio will send VERIFY commands.
*/
- if (r->req.cmd.buf[1] & 0xe0) {
+ if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) {
goto illegal_request;
}
if (!check_lba_range(s, r->req.cmd.lba, len)) {
@@ -2268,6 +2274,8 @@ static void scsi_disk_reset(DeviceState *dev)
/* reset tray statuses */
s->tray_locked = 0;
s->tray_open = 0;
+
+ s->qdev.scsi_version = s->qdev.default_scsi_version;
}
static void scsi_disk_resize_cb(void *opaque)
@@ -2812,6 +2820,8 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
{
SCSIBlockReq *r = (SCSIBlockReq *)req;
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
+
r->cmd = req->cmd.buf[0];
switch (r->cmd >> 5) {
case 0:
@@ -2837,8 +2847,11 @@ static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
abort();
}
- if (r->cdb1 & 0xe0) {
- /* Protection information is not supported. */
+ /* Protection information is not supported. For SCSI versions 2 and
+ * older (as determined by snooping the guest's INQUIRY commands),
+ * there is no RD/WR/VRPROTECT, so skip this check in these versions.
+ */
+ if (s->qdev.scsi_version > 2 && (req->cmd.buf[1] & 0xe0)) {
scsi_check_condition(&r->req, SENSE_CODE(INVALID_FIELD));
return 0;
}
@@ -2950,6 +2963,8 @@ static Property scsi_hd_properties[] = {
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
+ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+ 5),
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2995,6 +3010,8 @@ static Property scsi_cd_properties[] = {
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
+ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+ 5),
DEFINE_PROP_END_OF_LIST(),
};
@@ -3023,6 +3040,8 @@ static Property scsi_block_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false),
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
+ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+ -1),
DEFINE_PROP_END_OF_LIST(),
};
@@ -3063,6 +3082,8 @@ static Property scsi_disk_properties[] = {
DEFAULT_MAX_UNMAP_SIZE),
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
+ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+ 5),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 4753f8738f..381f04e339 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -194,17 +194,40 @@ static void scsi_read_complete(void * opaque, int ret)
r->buf[3] |= 0x80;
}
}
- if (s->type == TYPE_DISK &&
- r->req.cmd.buf[0] == INQUIRY &&
- r->req.cmd.buf[2] == 0xb0) {
- uint32_t max_transfer =
- blk_get_max_transfer(s->conf.blk) / s->blocksize;
-
- assert(max_transfer);
- stl_be_p(&r->buf[8], max_transfer);
- /* Also take care of the opt xfer len. */
- stl_be_p(&r->buf[12],
- MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
+ if (r->req.cmd.buf[0] == INQUIRY) {
+ /*
+ * EVPD set to zero returns the standard INQUIRY data.
+ *
+ * Check if scsi_version is unset (-1) to avoid re-defining it
+ * each time an INQUIRY with standard data is received.
+ * scsi_version is initialized with -1 in scsi_generic_reset
+ * and scsi_disk_reset, making sure that we'll set the
+ * scsi_version after a reset. If the version field of the
+ * INQUIRY response somehow changes after a guest reboot,
+ * we'll be able to keep track of it.
+ *
+ * On SCSI-2 and older, first 3 bits of byte 2 is the
+ * ANSI-approved version, while on later versions the
+ * whole byte 2 contains the version. Check if we're dealing
+ * with a newer version and, in that case, assign the
+ * whole byte.
+ */
+ if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) {
+ s->scsi_version = r->buf[2] & 0x07;
+ if (s->scsi_version > 2) {
+ s->scsi_version = r->buf[2];
+ }
+ }
+ if (s->type == TYPE_DISK && r->req.cmd.buf[2] == 0xb0) {
+ uint32_t max_transfer =
+ blk_get_max_transfer(s->conf.blk) / s->blocksize;
+
+ assert(max_transfer);
+ stl_be_p(&r->buf[8], max_transfer);
+ /* Also take care of the opt xfer len. */
+ stl_be_p(&r->buf[12],
+ MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
+ }
}
scsi_req_data(&r->req, len);
scsi_req_unref(&r->req);
@@ -474,6 +497,7 @@ static void scsi_generic_reset(DeviceState *dev)
{
SCSIDevice *s = SCSI_DEVICE(dev);
+ s->scsi_version = s->default_scsi_version;
scsi_device_purge_requests(s, SENSE_CODE(RESET));
}
@@ -549,6 +573,8 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
DPRINTF("block size %d\n", s->blocksize);
+ /* Only used by scsi-block, but initialize it nevertheless to be clean. */
+ s->default_scsi_version = -1;
scsi_generic_read_device_identification(s);
}
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 4e5855741a..fe34b50769 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -357,11 +357,13 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
error_setg(&err, "vfio: subchannel %s has already been attached",
vcdev->vdev.name);
+ g_free(vcdev->vdev.name);
goto out_device_err;
}
}
if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, &err)) {
+ g_free(vcdev->vdev.name);
goto out_device_err;
}
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 5e84716218..07ffa0ba10 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -548,12 +548,11 @@ static void vfio_listener_region_add(MemoryListener *listener,
hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) {
- error_report("Region 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx
- " is not aligned to 0x%"HWADDR_PRIx
- " and cannot be mapped for DMA",
- section->offset_within_region,
- int128_getlo(section->size),
- pgmask + 1);
+ trace_vfio_listener_region_add_no_dma_map(
+ memory_region_name(section->mr),
+ section->offset_within_address_space,
+ int128_getlo(section->size),
+ pgmask + 1);
return;
}
}
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 79f63a2ff6..20109cb758 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -90,6 +90,7 @@ vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "i
vfio_listener_region_add_skip(uint64_t start, uint64_t end) "SKIPPING region_add 0x%"PRIx64" - 0x%"PRIx64
vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] 0x%"PRIx64" - 0x%"PRIx64
vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
+vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA"
vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING region_del 0x%"PRIx64" - 0x%"PRIx64
vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64
vfio_disconnect_container(int fd) "close container->fd=%d"
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 44aea5c0a8..38da8692bb 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -46,6 +46,7 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
+ VHOST_USER_PROTOCOL_F_CONFIG = 9,
VHOST_USER_PROTOCOL_F_MAX
};
@@ -1211,6 +1212,17 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
dev->protocol_features =
protocol_features & VHOST_USER_PROTOCOL_FEATURE_MASK;
+
+ if (!dev->config_ops || !dev->config_ops->vhost_dev_config_notifier) {
+ /* Don't acknowledge CONFIG feature if device doesn't support it */
+ dev->protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIG);
+ } else if (!(protocol_features &
+ (1ULL << VHOST_USER_PROTOCOL_F_CONFIG))) {
+ error_report("Device expects VHOST_USER_PROTOCOL_F_CONFIG "
+ "but backend does not support it.");
+ return -1;
+ }
+
err = vhost_user_set_protocol_features(dev, dev->protocol_features);
if (err < 0) {
return err;
@@ -1405,6 +1417,11 @@ static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
.hdr.size = VHOST_USER_CONFIG_HDR_SIZE + config_len,
};
+ if (!virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_CONFIG)) {
+ return -1;
+ }
+
if (config_len > VHOST_USER_MAX_CONFIG_SIZE) {
return -1;
}
@@ -1448,6 +1465,11 @@ static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data,
.hdr.size = VHOST_USER_CONFIG_HDR_SIZE + size,
};
+ if (!virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_CONFIG)) {
+ return -1;
+ }
+
if (reply_supported) {
msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 250f886acb..f51bf573d5 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -595,10 +595,15 @@ static void vhost_region_add_section(struct vhost_dev *dev,
prev_sec->offset_within_address_space,
prev_sec->offset_within_region);
} else {
- error_report("%s: Overlapping but not coherent sections "
- "at %"PRIx64,
- __func__, mrs_gpa);
- return;
+ /* adjoining regions are fine, but overlapping ones with
+ * different blocks/offsets shouldn't happen
+ */
+ if (mrs_gpa != prev_gpa_end + 1) {
+ error_report("%s: Overlapping but not coherent sections "
+ "at %"PRIx64,
+ __func__, mrs_gpa);
+ return;
+ }
}
}
}
@@ -1223,7 +1228,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
error_setg(&hdev->migration_blocker,
"Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
- } else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_check()) {
+ } else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_alloc_check()) {
error_setg(&hdev->migration_blocker,
"Migration disabled: failed to allocate shared memory");
}
@@ -1451,7 +1456,6 @@ int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data,
void vhost_dev_set_config_notifier(struct vhost_dev *hdev,
const VhostDevConfigOps *ops)
{
- assert(hdev->vhost_ops);
hdev->config_ops = ops;
}
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 7ecaddac9d..e35137ea78 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -85,6 +85,8 @@ struct SCSIDevice
uint64_t max_lba;
uint64_t wwn;
uint64_t port_wwn;
+ int scsi_version;
+ int default_scsi_version;
};
extern const VMStateDescription vmstate_scsi_device;
diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h
index de10198ed6..49e79634da 100644
--- a/include/qemu/memfd.h
+++ b/include/qemu/memfd.h
@@ -18,6 +18,7 @@
int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
uint64_t hugetlbsize, unsigned int seals, Error **errp);
+bool qemu_memfd_alloc_check(void);
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
int *fd, Error **errp);
void qemu_memfd_free(void *ptr, size_t size, int fd);
diff --git a/include/ui/console.h b/include/ui/console.h
index 6d2c052068..37a8d68d29 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -99,7 +99,7 @@ void hmp_mouse_set(Monitor *mon, const QDict *qdict);
#define QEMU_KEY_CTRL_PAGEDOWN 0xe407
void kbd_put_keysym_console(QemuConsole *s, int keysym);
-bool kbd_put_qcode_console(QemuConsole *s, int qcode);
+bool kbd_put_qcode_console(QemuConsole *s, int qcode, bool ctrl);
void kbd_put_string_console(QemuConsole *s, const char *str, int len);
void kbd_put_keysym(int keysym);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 33d5ced30c..046d4c8aa0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2920,8 +2920,8 @@ static void setup_frame(int sig, struct target_sigaction *ka,
env->pc = ka->_sa_handler;
env->npc = (env->pc + 4);
/* 5. return to kernel instructions */
- if (ka->sa_restorer) {
- env->regwptr[UREG_I7] = ka->sa_restorer;
+ if (ka->ka_restorer) {
+ env->regwptr[UREG_I7] = ka->ka_restorer;
} else {
uint32_t val32;
@@ -6367,7 +6367,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
&frame->retcode[1]);
__put_user(INSN_CALLSYS, &frame->retcode[2]);
/* imb() */
- r26 = frame_addr;
+ r26 = frame_addr + offsetof(struct target_sigframe, retcode);
}
unlock_user_struct(frame, frame_addr, 1);
@@ -6424,7 +6424,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
&frame->retcode[1]);
__put_user(INSN_CALLSYS, &frame->retcode[2]);
/* imb(); */
- r26 = frame_addr;
+ r26 = frame_addr + offsetof(struct target_sigframe, retcode);
}
if (err) {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0eab5cc6ad..643b8833de 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8717,6 +8717,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
target_siginitset(&act.sa_mask, old_act->sa_mask);
act.sa_flags = old_act->sa_flags;
act.sa_restorer = old_act->sa_restorer;
+#ifdef TARGET_ARCH_HAS_KA_RESTORER
+ act.ka_restorer = 0;
+#endif
unlock_user_struct(old_act, arg2, 0);
pact = &act;
} else {
@@ -8791,8 +8794,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
goto efault;
}
-#ifdef TARGET_SPARC
- act->sa_restorer = restorer;
+#ifdef TARGET_ARCH_HAS_KA_RESTORER
+ act->ka_restorer = restorer;
#endif
} else {
act = NULL;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 13fe840239..23f5bccf0e 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -435,6 +435,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
#define TARGET_SA_NODEFER 0x20u
#define TARGET_SA_RESETHAND 4u
#define TARGET_ARCH_HAS_SA_RESTORER 1
+#define TARGET_ARCH_HAS_KA_RESTORER 1
#elif defined(TARGET_MIPS)
#define TARGET_SA_NOCLDSTOP 0x00000001
#define TARGET_SA_NOCLDWAIT 0x00010000
@@ -742,6 +743,9 @@ struct target_sigaction {
abi_ulong sa_restorer;
#endif
target_sigset_t sa_mask;
+#ifdef TARGET_ARCH_HAS_KA_RESTORER
+ abi_ulong ka_restorer;
+#endif
};
#endif
@@ -2561,6 +2565,7 @@ struct target_statfs64 {
#define TARGET_O_CLOEXEC 0x400000
#define TARGET___O_SYNC 0x800000
#define TARGET_O_PATH 0x1000000
+#define TARGET___O_TMPFILE 0x2000000
#endif
/* <asm-generic/fcntl.h> values follow. */
diff --git a/pc-bios/hppa-firmware.img b/pc-bios/hppa-firmware.img
index d2098f1fd9..4ec0dbfc4a 100755
--- a/pc-bios/hppa-firmware.img
+++ b/pc-bios/hppa-firmware.img
Binary files differ
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index fbd76bb55e..fdd6809c70 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differ
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index fc2a9fe33b..9287b7a70f 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -70,6 +70,13 @@ static void jump_to_IPL_code(uint64_t address)
{
/* store the subsystem information _after_ the bootmap was loaded */
write_subsystem_identification();
+
+ /* prevent unknown IPL types in the guest */
+ if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
+ iplb.pbt = S390_IPL_TYPE_CCW;
+ set_iplb(&iplb);
+ }
+
/*
* The IPL PSW is at address 0. We also must not overwrite the
* content of non-BIOS memory after we loaded the guest, so we
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index 7dfce4fbcf..5357a36d51 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -97,16 +97,27 @@ extern QemuIplParameters qipl;
#define S390_IPL_TYPE_CCW 0x02
#define S390_IPL_TYPE_QEMU_SCSI 0xff
-static inline bool store_iplb(IplParameterBlock *iplb)
+static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
{
register unsigned long addr asm("0") = (unsigned long) iplb;
register unsigned long rc asm("1") = 0;
asm volatile ("diag %0,%2,0x308\n"
: "+d" (addr), "+d" (rc)
- : "d" (6)
+ : "d" (store ? 6 : 5)
: "memory", "cc");
return rc == 0x01;
}
+
+static inline bool store_iplb(IplParameterBlock *iplb)
+{
+ return manage_iplb(iplb, true);
+}
+
+static inline bool set_iplb(IplParameterBlock *iplb)
+{
+ return manage_iplb(iplb, false);
+}
+
#endif /* IPLB_H */
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 817e7f56ea..cdb66f459e 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -14,7 +14,7 @@
#include "virtio-scsi.h"
#include "bswap.h"
-#define VRING_WAIT_REPLY_TIMEOUT 3
+#define VRING_WAIT_REPLY_TIMEOUT 30
static VRing block[VIRTIO_MAX_VQS];
static char ring_area[VIRTIO_RING_SIZE * VIRTIO_MAX_VQS]
diff --git a/pc-bios/s390-netboot.img b/pc-bios/s390-netboot.img
index 9f5926b534..31f3d141cd 100644
--- a/pc-bios/s390-netboot.img
+++ b/pc-bios/s390-netboot.img
Binary files differ
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 89fa80518a..5813d27615 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -140,6 +140,7 @@ accelerator is required to use more than one host CPU for emulation.
* direct_linux_boot:: Direct Linux Boot
* pcsys_usb:: USB emulation
* vnc_security:: VNC security
+* network_tls:: TLS setup for network services
* gdb_usage:: GDB usage
* pcsys_os_specific:: Target OS specific information
@end menu
@@ -1041,7 +1042,6 @@ considerations depending on the deployment scenarios.
* vnc_sec_certificate_pw::
* vnc_sec_sasl::
* vnc_sec_certificate_sasl::
-* vnc_generate_cert::
* vnc_setup_sasl::
@end menu
@node vnc_sec_none
@@ -1161,25 +1161,105 @@ with the aforementioned TLS + x509 options:
qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio
@end example
+@node vnc_setup_sasl
-@node vnc_generate_cert
-@subsection Generating certificates for VNC
+@subsection Configuring SASL mechanisms
-The GNU TLS packages provides a command called @code{certtool} which can
-be used to generate certificates and keys in PEM format. At a minimum it
-is necessary to setup a certificate authority, and issue certificates to
-each server. If using certificates for authentication, then each client
-will also need to be issued a certificate. The recommendation is for the
-server to keep its certificates in either @code{/etc/pki/qemu} or for
-unprivileged users in @code{$HOME/.pki/qemu}.
+The following documentation assumes use of the Cyrus SASL implementation on a
+Linux host, but the principles should apply to any other SASL implementation
+or host. When SASL is enabled, the mechanism configuration will be loaded from
+system default SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
+unprivileged user, an environment variable SASL_CONF_PATH can be used to make
+it search alternate locations for the service config file.
+
+If the TLS option is enabled for VNC, then it will provide session encryption,
+otherwise the SASL mechanism will have to provide encryption. In the latter
+case the list of possible plugins that can be used is drastically reduced. In
+fact only the GSSAPI SASL mechanism provides an acceptable level of security
+by modern standards. Previous versions of QEMU referred to the DIGEST-MD5
+mechanism, however, it has multiple serious flaws described in detail in
+RFC 6331 and thus should never be used any more. The SCRAM-SHA-1 mechanism
+provides a simple username/password auth facility similar to DIGEST-MD5, but
+does not support session encryption, so can only be used in combination with
+TLS.
+
+When not using TLS the recommended configuration is
+
+@example
+mech_list: gssapi
+keytab: /etc/qemu/krb5.tab
+@end example
+
+This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with
+the server principal stored in /etc/qemu/krb5.tab. For this to work the
+administrator of your KDC must generate a Kerberos principal for the server,
+with a name of 'qemu/somehost.example.com@@EXAMPLE.COM' replacing
+'somehost.example.com' with the fully qualified host name of the machine
+running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
+
+When using TLS, if username+password authentication is desired, then a
+reasonable configuration is
+
+@example
+mech_list: scram-sha-1
+sasldb_path: /etc/qemu/passwd.db
+@end example
+
+The @code{saslpasswd2} program can be used to populate the @code{passwd.db}
+file with accounts.
+
+Other SASL configurations will be left as an exercise for the reader. Note that
+all mechanisms, except GSSAPI, should be combined with use of TLS to ensure a
+secure data channel.
+
+
+@node network_tls
+@section TLS setup for network services
+
+Almost all network services in QEMU have the ability to use TLS for
+session data encryption, along with x509 certificates for simple
+client authentication. What follows is a description of how to
+generate certificates suitable for usage with QEMU, and applies to
+the VNC server, character devices with the TCP backend, NBD server
+and client, and migration server and client.
+
+At a high level, QEMU requires certificates and private keys to be
+provided in PEM format. Aside from the core fields, the certificates
+should include various extension data sets, including v3 basic
+constraints data, key purpose, key usage and subject alt name.
+
+The GnuTLS package includes a command called @code{certtool} which can
+be used to easily generate certificates and keys in the required format
+with expected data present. Alternatively a certificate management
+service may be used.
+
+At a minimum it is necessary to setup a certificate authority, and
+issue certificates to each server. If using x509 certificates for
+authentication, then each client will also need to be issued a
+certificate.
+
+Assuming that the QEMU network services will only ever be exposed to
+clients on a private intranet, there is no need to use a commercial
+certificate authority to create certificates. A self-signed CA is
+sufficient, and in fact likely to be more secure since it removes
+the ability of malicious 3rd parties to trick the CA into mis-issuing
+certs for impersonating your services. The only likely exception
+where a commercial CA might be desirable is if enabling the VNC
+websockets server and exposing it directly to remote browser clients.
+In such a case it might be useful to use a commercial CA to avoid
+needing to install custom CA certs in the web browsers.
+
+The recommendation is for the server to keep its certificates in either
+@code{/etc/pki/qemu} or for unprivileged users in @code{$HOME/.pki/qemu}.
@menu
-* vnc_generate_ca::
-* vnc_generate_server::
-* vnc_generate_client::
+* tls_generate_ca::
+* tls_generate_server::
+* tls_generate_client::
+* tls_creds_setup::
@end menu
-@node vnc_generate_ca
-@subsubsection Setup the Certificate Authority
+@node tls_generate_ca
+@subsection Setup the Certificate Authority
This step only needs to be performed once per organization / organizational
unit. First the CA needs a private key. This key must be kept VERY secret
@@ -1190,11 +1270,10 @@ issued with it is lost.
# certtool --generate-privkey > ca-key.pem
@end example
-A CA needs to have a public certificate. For simplicity it can be a self-signed
-certificate, or one issue by a commercial certificate issuing authority. To
-generate a self-signed certificate requires one core piece of information, the
-name of the organization.
-
+To generate a self-signed certificate requires one core piece of information,
+the name of the organization. A template file @code{ca.info} should be
+populated with the desired data to avoid having to deal with interactive
+prompts from certtool:
@example
# cat > ca.info <<EOF
cn = Name of your organization
@@ -1207,123 +1286,224 @@ EOF
--outfile ca-cert.pem
@end example
-The @code{ca-cert.pem} file should be copied to all servers and clients wishing to utilize
-TLS support in the VNC server. The @code{ca-key.pem} must not be disclosed/copied at all.
+The @code{ca} keyword in the template sets the v3 basic constraints extension
+to indicate this certificate is for a CA, while @code{cert_signing_key} sets
+the key usage extension to indicate this will be used for signing other keys.
+The generated @code{ca-cert.pem} file should be copied to all servers and
+clients wishing to utilize TLS support in the VNC server. The @code{ca-key.pem}
+must not be disclosed/copied anywhere except the host responsible for issuing
+certificates.
-@node vnc_generate_server
-@subsubsection Issuing server certificates
+@node tls_generate_server
+@subsection Issuing server certificates
Each server (or host) needs to be issued with a key and certificate. When connecting
the certificate is sent to the client which validates it against the CA certificate.
-The core piece of information for a server certificate is the hostname. This should
-be the fully qualified hostname that the client will connect with, since the client
-will typically also verify the hostname in the certificate. On the host holding the
-secure CA private key:
-
-@example
-# cat > server.info <<EOF
+The core pieces of information for a server certificate are the hostnames and/or IP
+addresses that will be used by clients when connecting. The hostname / IP address
+that the client specifies when connecting will be validated against the hostname(s)
+and IP address(es) recorded in the server certificate, and if no match is found
+the client will close the connection.
+
+Thus it is recommended that the server certificate include both the fully qualified
+and unqualified hostnames. If the server will have permanently assigned IP address(es),
+and clients are likely to use them when connecting, they may also be included in the
+certificate. Both IPv4 and IPv6 addresses are supported. Historically certificates
+only included 1 hostname in the @code{CN} field, however, usage of this field for
+validation is now deprecated. Instead modern TLS clients will validate against the
+Subject Alt Name extension data, which allows for multiple entries. In the future
+usage of the @code{CN} field may be discontinued entirely, so providing SAN
+extension data is strongly recommended.
+
+On the host holding the CA, create template files containing the information
+for each server, and use it to issue server certificates.
+
+@example
+# cat > server-hostNNN.info <<EOF
organization = Name of your organization
-cn = server.foo.example.com
+cn = hostNNN.foo.example.com
+dns_name = hostNNN
+dns_name = hostNNN.foo.example.com
+ip_address = 10.0.1.87
+ip_address = 192.8.0.92
+ip_address = 2620:0:cafe::87
+ip_address = 2001:24::92
tls_www_server
encryption_key
signing_key
EOF
-# certtool --generate-privkey > server-key.pem
+# certtool --generate-privkey > server-hostNNN-key.pem
# certtool --generate-certificate \
--load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem \
- --load-privkey server-key.pem \
- --template server.info \
- --outfile server-cert.pem
+ --load-privkey server-hostNNN-key.pem \
+ --template server-hostNNN.info \
+ --outfile server-hostNNN-cert.pem
@end example
-The @code{server-key.pem} and @code{server-cert.pem} files should now be securely copied
-to the server for which they were generated. The @code{server-key.pem} is security
-sensitive and should be kept protected with file mode 0600 to prevent disclosure.
+The @code{dns_name} and @code{ip_address} fields in the template are setting
+the subject alt name extension data. The @code{tls_www_server} keyword is the
+key purpose extension to indicate this certificate is intended for usage in
+a web server. Although QEMU network services are not in fact HTTP servers
+(except for VNC websockets), setting this key purpose is still recommended.
+The @code{encryption_key} and @code{signing_key} keyword is the key usage
+extension to indicate this certificate is intended for usage in the data
+session.
-@node vnc_generate_client
-@subsubsection Issuing client certificates
+The @code{server-hostNNN-key.pem} and @code{server-hostNNN-cert.pem} files
+should now be securely copied to the server for which they were generated,
+and renamed to @code{server-key.pem} and @code{server-cert.pem} when added
+to the @code{/etc/pki/qemu} directory on the target host. The @code{server-key.pem}
+file is security sensitive and should be kept protected with file mode 0600
+to prevent disclosure.
+
+@node tls_generate_client
+@subsection Issuing client certificates
+
+The QEMU x509 TLS credential setup defaults to enabling client verification
+using certificates, providing a simple authentication mechanism. If this
+default is used, each client also needs to be issued a certificate. The client
+certificate contains enough metadata to uniquely identify the client with the
+scope of the certificate authority. The client certificate would typically
+include fields for organization, state, city, building, etc.
+
+Once again on the host holding the CA, create template files containing the
+information for each client, and use it to issue client certificates.
-If the QEMU VNC server is to use the @code{x509verify} option to validate client
-certificates as its authentication mechanism, each client also needs to be issued
-a certificate. The client certificate contains enough metadata to uniquely identify
-the client, typically organization, state, city, building, etc. On the host holding
-the secure CA private key:
@example
-# cat > client.info <<EOF
+# cat > client-hostNNN.info <<EOF
country = GB
state = London
-locality = London
+locality = City Of London
organization = Name of your organization
-cn = client.foo.example.com
+cn = hostNNN.foo.example.com
tls_www_client
encryption_key
signing_key
EOF
-# certtool --generate-privkey > client-key.pem
+# certtool --generate-privkey > client-hostNNN-key.pem
# certtool --generate-certificate \
--load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem \
- --load-privkey client-key.pem \
- --template client.info \
- --outfile client-cert.pem
+ --load-privkey client-hostNNN-key.pem \
+ --template client-hostNNN.info \
+ --outfile client-hostNNN-cert.pem
+@end example
+
+The subject alt name extension data is not required for clients, so the
+the @code{dns_name} and @code{ip_address} fields are not included.
+The @code{tls_www_client} keyword is the key purpose extension to indicate
+this certificate is intended for usage in a web client. Although QEMU
+network clients are not in fact HTTP clients, setting this key purpose is
+still recommended. The @code{encryption_key} and @code{signing_key} keyword
+is the key usage extension to indicate this certificate is intended for
+usage in the data session.
+
+The @code{client-hostNNN-key.pem} and @code{client-hostNNN-cert.pem} files
+should now be securely copied to the client for which they were generated,
+and renamed to @code{client-key.pem} and @code{client-cert.pem} when added
+to the @code{/etc/pki/qemu} directory on the target host. The @code{client-key.pem}
+file is security sensitive and should be kept protected with file mode 0600
+to prevent disclosure.
+
+If a single host is going to be using TLS in both a client and server
+role, it is possible to create a single certificate to cover both roles.
+This would be quite common for the migration and NBD services, where a
+QEMU process will be started by accepting a TLS protected incoming migration,
+and later itself be migrated out to another host. To generate a single
+certificate, simply include the template data from both the client and server
+instructions in one.
+
+@example
+# cat > both-hostNNN.info <<EOF
+country = GB
+state = London
+locality = City Of London
+organization = Name of your organization
+cn = hostNNN.foo.example.com
+dns_name = hostNNN
+dns_name = hostNNN.foo.example.com
+ip_address = 10.0.1.87
+ip_address = 192.8.0.92
+ip_address = 2620:0:cafe::87
+ip_address = 2001:24::92
+tls_www_server
+tls_www_client
+encryption_key
+signing_key
+EOF
+# certtool --generate-privkey > both-hostNNN-key.pem
+# certtool --generate-certificate \
+ --load-ca-certificate ca-cert.pem \
+ --load-ca-privkey ca-key.pem \
+ --load-privkey both-hostNNN-key.pem \
+ --template both-hostNNN.info \
+ --outfile both-hostNNN-cert.pem
@end example
-The @code{client-key.pem} and @code{client-cert.pem} files should now be securely
-copied to the client for which they were generated.
+When copying the PEM files to the target host, save them twice,
+once as @code{server-cert.pem} and @code{server-key.pem}, and
+again as @code{client-cert.pem} and @code{client-key.pem}.
+@node tls_creds_setup
+@subsection TLS x509 credential configuration
-@node vnc_setup_sasl
+QEMU has a standard mechanism for loading x509 credentials that will be
+used for network services and clients. It requires specifying the
+@code{tls-creds-x509} class name to the @code{--object} command line
+argument for the system emulators. Each set of credentials loaded should
+be given a unique string identifier via the @code{id} parameter. A single
+set of TLS credentials can be used for multiple network backends, so VNC,
+migration, NBD, character devices can all share the same credentials. Note,
+however, that credentials for use in a client endpoint must be loaded
+separately from those used in a server endpoint.
-@subsection Configuring SASL mechanisms
+When specifying the object, the @code{dir} parameters specifies which
+directory contains the credential files. This directory is expected to
+contain files with the names mentioned previously, @code{ca-cert.pem},
+@code{server-key.pem}, @code{server-cert.pem}, @code{client-key.pem}
+and @code{client-cert.pem} as appropriate. It is also possible to
+include a set of pre-generated Diffie-Hellman (DH) parameters in a file
+@code{dh-params.pem}, which can be created using the
+@code{certtool --generate-dh-params} command. If omitted, QEMU will
+dynamically generate DH parameters when loading the credentials.
-The following documentation assumes use of the Cyrus SASL implementation on a
-Linux host, but the principals should apply to any other SASL impl. When SASL
-is enabled, the mechanism configuration will be loaded from system default
-SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
-unprivileged user, an environment variable SASL_CONF_PATH can be used
-to make it search alternate locations for the service config.
+The @code{endpoint} parameter indicates whether the credentials will
+be used for a network client or server, and determines which PEM
+files are loaded.
-If the TLS option is enabled for VNC, then it will provide session encryption,
-otherwise the SASL mechanism will have to provide encryption. In the latter
-case the list of possible plugins that can be used is drastically reduced. In
-fact only the GSSAPI SASL mechanism provides an acceptable level of security
-by modern standards. Previous versions of QEMU referred to the DIGEST-MD5
-mechanism, however, it has multiple serious flaws described in detail in
-RFC 6331 and thus should never be used any more. The SCRAM-SHA-1 mechanism
-provides a simple username/password auth facility similar to DIGEST-MD5, but
-does not support session encryption, so can only be used in combination with
-TLS.
+The @code{verify} parameter determines whether x509 certificate
+validation should be performed. This defaults to enabled, meaning
+clients will always validate the server hostname against the
+certificate subject alt name fields and/or CN field. It also
+means that servers will request that clients provide a certificate
+and validate them. Verification should never be turned off for
+client endpoints, however, it may be turned off for server endpoints
+if an alternative mechanism is used to authenticate clients. For
+example, the VNC server can use SASL to authenticate clients
+instead.
-When not using TLS the recommended configuration is
+To load server credentials with client certificate validation
+enabled
@example
-mech_list: gssapi
-keytab: /etc/qemu/krb5.tab
+$QEMU -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server
@end example
-This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with
-the server principal stored in /etc/qemu/krb5.tab. For this to work the
-administrator of your KDC must generate a Kerberos principal for the server,
-with a name of 'qemu/somehost.example.com@@EXAMPLE.COM' replacing
-'somehost.example.com' with the fully qualified host name of the machine
-running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
-
-When using TLS, if username+password authentication is desired, then a
-reasonable configuration is
+while to load client credentials use
@example
-mech_list: scram-sha-1
-sasldb_path: /etc/qemu/passwd.db
+$QEMU -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client
@end example
-The saslpasswd2 program can be used to populate the passwd.db file with
-accounts.
+Network services which support TLS will all have a @code{tls-creds}
+parameter which expects the ID of the TLS credentials object. For
+example with VNC:
-Other SASL configurations will be left as an exercise for the reader. Note that
-all mechanisms except GSSAPI, should be combined with use of TLS to ensure a
-secure data channel.
+@example
+$QEMU -vnc 0.0.0.0:0,tls-creds=tls0
+@end example
@node gdb_usage
@section GDB usage
diff --git a/qemu-options.hx b/qemu-options.hx
index 3ece30d216..ca4e412f2f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4112,7 +4112,7 @@ expensive operation that consumes random pool entropy, so it is
recommended that a persistent set of parameters be generated
upfront and saved.
-@item -object tls-creds-x509,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},verify-peer=@var{on|off},passwordid=@var{id}
+@item -object tls-creds-x509,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},priority=@var{priority},verify-peer=@var{on|off},passwordid=@var{id}
Creates a TLS anonymous credentials object, which can be used to provide
TLS support on network backends. The @option{id} parameter is a unique
@@ -4145,6 +4145,15 @@ version by providing the @var{passwordid} parameter. This provides
the ID of a previously created @code{secret} object containing the
password for decryption.
+The @var{priority} parameter allows to override the global default
+priority used by gnutls. This can be useful if the system administrator
+needs to use a weaker set of crypto priorities for QEMU without
+potentially forcing the weakness onto all applications. Or conversely
+if one wants wants a stronger default for QEMU than for all other
+applications, they can do this through this parameter. Its format is
+a gnutls priority string as described at
+@url{https://gnutls.org/manual/html_node/Priority-Strings.html}.
+
@item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}]
Interval @var{t} can't be 0, this filter batches the packet delivery: all
diff --git a/roms/seabios-hppa b/roms/seabios-hppa
-Subproject 649e6202b8d65d46c69f542b1380f840fbe8ab1
+Subproject 1ef99a01572c2581c30e16e6fe69e9ea2ef92ce
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 57daae05ea..d52207a3cc 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2356,6 +2356,18 @@ sub process {
# check for missing bracing around if etc
if ($line =~ /(^.*)\b(?:if|while|for)\b/ &&
$line !~ /\#\s*if/) {
+ my $allowed = 0;
+
+ # Check the pre-context.
+ if ($line =~ /(\}.*?)$/) {
+ my $pre = $1;
+
+ if ($line !~ /else/) {
+ print "APW: ALLOWED: pre<$pre> line<$line>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
+ }
+ }
my ($level, $endln, @chunks) =
ctx_statement_full($linenr, $realcnt, 1);
if ($dbg_adv_apw) {
@@ -2364,7 +2376,6 @@ sub process {
if $#chunks >= 1;
}
if ($#chunks >= 0 && $level == 0) {
- my $allowed = 0;
my $seen = 0;
my $herectx = $here . "\n";
my $ln = $linenr - 1;
@@ -2408,7 +2419,7 @@ sub process {
$allowed = 1;
}
}
- if ($seen != ($#chunks + 1)) {
+ if ($seen != ($#chunks + 1) && !$allowed) {
ERROR("braces {} are necessary for all arms of this statement\n" . $herectx);
}
}
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index 24c7bf5a16..5d17dc68dd 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -217,7 +217,6 @@ ERROR_WHITELIST = [
{'exitcode':-6, 'log':r"Object .* is not an instance of type generic-pc-machine", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"Object .* is not an instance of type e500-ccsr", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"vmstate_register_with_alias_id: Assertion `!se->compat \|\| se->instance_id == 0' failed", 'loglevel':logging.ERROR},
- {'exitcode':-6, 'device':'isa-fdc', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'isa-serial', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'mioe3680_pci', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'pcm3680_pci', 'loglevel':logging.ERROR, 'expected':True},
diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
index 21e1b8ea60..d0f83176e1 100644
--- a/scsi/qemu-pr-helper.c
+++ b/scsi/qemu-pr-helper.c
@@ -924,6 +924,7 @@ int main(int argc, char **argv)
Error *local_err = NULL;
char *trace_file = NULL;
bool daemonize = false;
+ bool pidfile_specified = false;
unsigned socket_activation;
struct sigaction sa_sigterm;
@@ -954,6 +955,7 @@ int main(int argc, char **argv)
case 'f':
g_free(pidfile);
pidfile = g_strdup(optarg);
+ pidfile_specified = true;
break;
#ifdef CONFIG_LIBCAP
case 'u': {
@@ -1081,20 +1083,22 @@ int main(int argc, char **argv)
accept_client,
NULL, NULL);
-#ifdef CONFIG_LIBCAP
- if (drop_privileges() < 0) {
- error_report("Failed to drop privileges: %s", strerror(errno));
- exit(EXIT_FAILURE);
- }
-#endif
-
if (daemonize) {
if (daemon(0, 0) < 0) {
error_report("Failed to daemonize: %s", strerror(errno));
exit(EXIT_FAILURE);
}
+ }
+
+ if (daemonize || pidfile_specified)
write_pidfile();
+
+#ifdef CONFIG_LIBCAP
+ if (drop_privileges() < 0) {
+ error_report("Failed to drop privileges: %s", strerror(errno));
+ exit(EXIT_FAILURE);
}
+#endif
state = RUNNING;
do {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 555ae79d29..1a6b082b6f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4761,6 +4761,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
+ DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 78db1b833a..1b219fafc4 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1296,6 +1296,7 @@ struct X86CPU {
bool hyperv_runtime;
bool hyperv_synic;
bool hyperv_stimer;
+ bool hyperv_frequencies;
bool check_cpuid;
bool enforce_cpuid;
bool expose_kvm;
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index d23fff12f5..6c49954e68 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -632,11 +632,6 @@ static int hyperv_handle_properties(CPUState *cs)
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
- if (cpu->hyperv_time &&
- kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) <= 0) {
- cpu->hyperv_time = false;
- }
-
if (cpu->hyperv_relaxed_timing) {
env->features[FEAT_HYPERV_EAX] |= HV_HYPERCALL_AVAILABLE;
}
@@ -645,26 +640,61 @@ static int hyperv_handle_properties(CPUState *cs)
env->features[FEAT_HYPERV_EAX] |= HV_APIC_ACCESS_AVAILABLE;
}
if (cpu->hyperv_time) {
+ if (kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) <= 0) {
+ fprintf(stderr, "Hyper-V clocksources "
+ "(requested by 'hv-time' cpu flag) "
+ "are not supported by kernel\n");
+ return -ENOSYS;
+ }
env->features[FEAT_HYPERV_EAX] |= HV_HYPERCALL_AVAILABLE;
env->features[FEAT_HYPERV_EAX] |= HV_TIME_REF_COUNT_AVAILABLE;
env->features[FEAT_HYPERV_EAX] |= HV_REFERENCE_TSC_AVAILABLE;
-
- if (has_msr_hv_frequencies && tsc_is_stable_and_known(env)) {
- env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_FREQUENCY_MSRS;
- env->features[FEAT_HYPERV_EDX] |= HV_FREQUENCY_MSRS_AVAILABLE;
+ }
+ if (cpu->hyperv_frequencies) {
+ if (!has_msr_hv_frequencies) {
+ fprintf(stderr, "Hyper-V frequency MSRs "
+ "(requested by 'hv-frequencies' cpu flag) "
+ "are not supported by kernel\n");
+ return -ENOSYS;
}
+ env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_FREQUENCY_MSRS;
+ env->features[FEAT_HYPERV_EDX] |= HV_FREQUENCY_MSRS_AVAILABLE;
}
- if (cpu->hyperv_crash && has_msr_hv_crash) {
+ if (cpu->hyperv_crash) {
+ if (!has_msr_hv_crash) {
+ fprintf(stderr, "Hyper-V crash MSRs "
+ "(requested by 'hv-crash' cpu flag) "
+ "are not supported by kernel\n");
+ return -ENOSYS;
+ }
env->features[FEAT_HYPERV_EDX] |= HV_GUEST_CRASH_MSR_AVAILABLE;
}
env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
- if (cpu->hyperv_reset && has_msr_hv_reset) {
+ if (cpu->hyperv_reset) {
+ if (!has_msr_hv_reset) {
+ fprintf(stderr, "Hyper-V reset MSR "
+ "(requested by 'hv-reset' cpu flag) "
+ "is not supported by kernel\n");
+ return -ENOSYS;
+ }
env->features[FEAT_HYPERV_EAX] |= HV_RESET_AVAILABLE;
}
- if (cpu->hyperv_vpindex && has_msr_hv_vpindex) {
+ if (cpu->hyperv_vpindex) {
+ if (!has_msr_hv_vpindex) {
+ fprintf(stderr, "Hyper-V VP_INDEX MSR "
+ "(requested by 'hv-vpindex' cpu flag) "
+ "is not supported by kernel\n");
+ return -ENOSYS;
+ }
env->features[FEAT_HYPERV_EAX] |= HV_VP_INDEX_AVAILABLE;
}
- if (cpu->hyperv_runtime && has_msr_hv_runtime) {
+ if (cpu->hyperv_runtime) {
+ if (!has_msr_hv_runtime) {
+ fprintf(stderr, "Hyper-V VP_RUNTIME MSR "
+ "(requested by 'hv-runtime' cpu flag) "
+ "is not supported by kernel\n");
+ return -ENOSYS;
+ }
env->features[FEAT_HYPERV_EAX] |= HV_VP_RUNTIME_AVAILABLE;
}
if (cpu->hyperv_synic) {
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 019d84cef2..c01167143f 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -748,9 +748,11 @@ sev_guest_init(const char *id)
if (s->sev_fd < 0) {
error_report("%s: Failed to open %s '%s'", __func__,
devname, strerror(errno));
- goto err;
}
g_free(devname);
+ if (s->sev_fd < 0) {
+ goto err;
+ }
ret = sev_platform_ioctl(s->sev_fd, SEV_PLATFORM_STATUS, &status,
&fw_error);
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 0135415d92..c9ed8dc709 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -3802,7 +3802,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
}
ot = mo_64_32(s->dflag);
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
- tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
+ tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_regs[s->vex_v]);
gen_op_mov_reg_v(ot, reg, cpu_T0);
gen_op_update1_cc();
set_cc_op(s, CC_OP_LOGICB + ot);
@@ -4563,9 +4563,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
#endif
rex_r = (~vex2 >> 4) & 8;
if (b == 0xc5) {
+ /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
vex3 = vex2;
- b = x86_ldub_code(env, s);
+ b = x86_ldub_code(env, s) | 0x100;
} else {
+ /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
#ifdef TARGET_X86_64
s->rex_x = (~vex2 >> 3) & 8;
s->rex_b = (~vex2 >> 2) & 8;
diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c
index bf33d320bf..58435178a4 100644
--- a/target/i386/whpx-all.c
+++ b/target/i386/whpx-all.c
@@ -911,12 +911,62 @@ static int whpx_vcpu_run(CPUState *cpu)
ret = 1;
break;
+ case WHvRunVpExitReasonX64Cpuid: {
+ WHV_REGISTER_VALUE reg_values[5] = {0};
+ WHV_REGISTER_NAME reg_names[5];
+ UINT32 reg_count = 5;
+ UINT64 rip, rax, rcx, rdx, rbx;
+
+ rip = vcpu->exit_ctx.VpContext.Rip +
+ vcpu->exit_ctx.VpContext.InstructionLength;
+ switch (vcpu->exit_ctx.CpuidAccess.Rax) {
+ case 1:
+ rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax;
+ /* Advertise that we are running on a hypervisor */
+ rcx =
+ vcpu->exit_ctx.CpuidAccess.DefaultResultRcx |
+ CPUID_EXT_HYPERVISOR;
+
+ rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx;
+ rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx;
+ break;
+ default:
+ rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax;
+ rcx = vcpu->exit_ctx.CpuidAccess.DefaultResultRcx;
+ rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx;
+ rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx;
+ }
+
+ reg_names[0] = WHvX64RegisterRip;
+ reg_names[1] = WHvX64RegisterRax;
+ reg_names[2] = WHvX64RegisterRcx;
+ reg_names[3] = WHvX64RegisterRdx;
+ reg_names[4] = WHvX64RegisterRbx;
+
+ reg_values[0].Reg64 = rip;
+ reg_values[1].Reg64 = rax;
+ reg_values[2].Reg64 = rcx;
+ reg_values[3].Reg64 = rdx;
+ reg_values[4].Reg64 = rbx;
+
+ hr = WHvSetVirtualProcessorRegisters(whpx->partition,
+ cpu->cpu_index,
+ reg_names,
+ reg_count,
+ reg_values);
+
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to set CpuidAccess state registers,"
+ " hr=%08lx", hr);
+ }
+ ret = 0;
+ break;
+ }
case WHvRunVpExitReasonNone:
case WHvRunVpExitReasonUnrecoverableException:
case WHvRunVpExitReasonInvalidVpRegisterValue:
case WHvRunVpExitReasonUnsupportedFeature:
case WHvRunVpExitReasonX64MsrAccess:
- case WHvRunVpExitReasonX64Cpuid:
case WHvRunVpExitReasonException:
default:
error_report("WHPX: Unexpected VP exit code %d",
@@ -1272,6 +1322,33 @@ static int whpx_accel_init(MachineState *ms)
goto error;
}
+ memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
+ prop.ExtendedVmExits.X64CpuidExit = 1;
+ hr = WHvSetPartitionProperty(whpx->partition,
+ WHvPartitionPropertyCodeExtendedVmExits,
+ &prop,
+ sizeof(WHV_PARTITION_PROPERTY));
+
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to enable partition extended X64CpuidExit"
+ " hr=%08lx", hr);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ UINT32 cpuidExitList[] = {1};
+ hr = WHvSetPartitionProperty(whpx->partition,
+ WHvPartitionPropertyCodeCpuidExitList,
+ cpuidExitList,
+ RTL_NUMBER_OF(cpuidExitList) * sizeof(UINT32));
+
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to set partition CpuidExitList hr=%08lx",
+ hr);
+ ret = -EINVAL;
+ goto error;
+ }
+
hr = WHvSetupPartition(whpx->partition);
if (FAILED(hr)) {
error_report("WHPX: Failed to setup partition, hr=%08lx", hr);
diff --git a/target/s390x/helper.c b/target/s390x/helper.c
index 615fa24ab9..e8548f340a 100644
--- a/target/s390x/helper.c
+++ b/target/s390x/helper.c
@@ -103,16 +103,18 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
env->psw.addr = addr;
env->psw.mask = mask;
- if (tcg_enabled()) {
- env->cc_op = (mask >> 44) & 3;
+
+ /* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */
+ if (!tcg_enabled()) {
+ return;
}
+ env->cc_op = (mask >> 44) & 3;
if ((old_mask ^ mask) & PSW_MASK_PER) {
s390_cpu_recompute_watchpoints(CPU(s390_env_get_cpu(env)));
}
- /* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */
- if (tcg_enabled() && (mask & PSW_MASK_WAIT)) {
+ if (mask & PSW_MASK_WAIT) {
s390_handle_wait(s390_env_get_cpu(env));
}
}
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index f570896dc1..fb59d92def 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1778,6 +1778,8 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
qemu_mutex_lock_iothread();
+ cpu_synchronize_state(cs);
+
switch (run->exit_reason) {
case KVM_EXIT_S390_SIEIC:
ret = handle_intercept(cpu);
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 1deeb6e6e4..a25deef5dd 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -325,7 +325,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
r = mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw,
exc);
- if (rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE)) {
+ if (!r && rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE)) {
trigger_prot_fault(env, vaddr, asc, rw, exc);
return -1;
}
diff --git a/tests/docker/common.rc b/tests/docker/common.rc
index 7951555e3f..046f8a5921 100755
--- a/tests/docker/common.rc
+++ b/tests/docker/common.rc
@@ -30,7 +30,9 @@ build_qemu()
$@"
echo "Configure options:"
echo $config_opts
- $QEMU_SRC/configure $config_opts && make $MAKEFLAGS
+ $QEMU_SRC/configure $config_opts || \
+ { cat config.log && test_fail "Failed to run 'configure'"; }
+ make $MAKEFLAGS
}
test_fail()
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index a00004319e..b706f42405 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -1,9 +1,16 @@
FROM fedora:27
ENV PACKAGES \
ccache gettext git tar PyYAML sparse flex bison python3 bzip2 hostname \
- glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
- gcc gcc-c++ llvm clang make perl which bc findutils libaio-devel \
- nettle-devel libasan libubsan \
+ gcc gcc-c++ llvm clang make perl which bc findutils glib2-devel \
+ libaio-devel pixman-devel zlib-devel libfdt-devel libasan libubsan \
+ bluez-libs-devel brlapi-devel bzip2-devel \
+ device-mapper-multipath-devel glusterfs-api-devel gnutls-devel \
+ gtk3-devel libattr-devel libcap-devel libcap-ng-devel libcurl-devel \
+ libjpeg-devel libpng-devel librbd-devel libssh2-devel libusbx-devel \
+ libxml2-devel lzo-devel ncurses-devel nettle-devel nss-devel \
+ numactl-devel SDL2-devel snappy-devel spice-server-devel \
+ systemtap-sdt-devel usbredir-devel virglrenderer-devel vte3-devel \
+ xen-devel \
mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \
mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
diff --git a/tests/docker/run b/tests/docker/run
index 9dd362bb98..7aebf4b569 100755
--- a/tests/docker/run
+++ b/tests/docker/run
@@ -29,7 +29,7 @@ export TEST_DIR=/tmp/qemu-test
mkdir -p $TEST_DIR/{src,build,install}
# Extract the source tarballs
-tar -C $TEST_DIR/src -xf $BASE/qemu.tar || prep_fail "Failed to untar source"
+tar -C $TEST_DIR/src -xf $BASE/qemu.tar || { echo "Failed to untar source"; exit 2; }
if test -f $TEST_DIR/src/Makefile; then
export FEATURES="$FEATURES dtc"
fi
diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out
index 830c11880a..b01f9a90d7 100644
--- a/tests/qemu-iotests/051.pc.out
+++ b/tests/qemu-iotests/051.pc.out
@@ -117,20 +117,10 @@ Testing: -drive if=ide,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) quit
-Testing: -drive if=scsi,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
-quit
-
Testing: -drive if=ide
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: Initialization of device ide-hd failed: Device needs media, but drive is empty
-Testing: -drive if=scsi
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi: warning: bus=0,unit=0 is deprecated with this machine type
-QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
-
Testing: -drive if=virtio
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
@@ -170,20 +160,10 @@ Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) quit
-Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type
-quit
-
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: Initialization of device ide-hd failed: Block node is read-only
-Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type
-quit
-
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) quit
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
index bfe71f4e60..5e51f88a78 100755
--- a/tests/qemu-iotests/106
+++ b/tests/qemu-iotests/106
@@ -86,6 +86,30 @@ for growth_mode in falloc full off; do
$QEMU_IMG resize -f "$IMGFMT" --shrink --preallocation=$growth_mode "$TEST_IMG" -${GROWTH_SIZE}K
done
+echo
+echo '=== Testing image growth on 2G empty image ==='
+
+for growth_mode in falloc full; do
+ echo
+ echo "--- growth_mode=$growth_mode ---"
+
+ # Maybe we want to do an lseek() to the end of the file before the
+ # preallocation; if the file has a length of 2 GB, that would
+ # return an integer that overflows to negative when put into a
+ # plain int. We should use the correct type for the result, and
+ # this tests we do.
+
+ _make_test_img 2G
+ $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
+
+ actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
+ actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/')
+
+ if [ $actual_size -lt $GROWTH_SIZE ]; then
+ echo "ERROR: Image should have at least ${GROWTH_SIZE}K, but has ${actual_size}K"
+ fi
+done
+
# success, all done
echo '*** done'
rm -f $seq.full
diff --git a/tests/qemu-iotests/106.out b/tests/qemu-iotests/106.out
index 0a42312301..c459957660 100644
--- a/tests/qemu-iotests/106.out
+++ b/tests/qemu-iotests/106.out
@@ -47,4 +47,14 @@ qemu-img: Preallocation can only be used for growing images
--- growth_mode=off ---
Image resized.
+
+=== Testing image growth on 2G empty image ===
+
+--- growth_mode=falloc ---
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
+Image resized.
+
+--- growth_mode=full ---
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
+Image resized.
*** done
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
index 45b359c2ba..6cf4fcb866 100755
--- a/tests/qemu-iotests/122
+++ b/tests/qemu-iotests/122
@@ -130,6 +130,53 @@ $QEMU_IO -c "read -P 0 1024k 1022k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _fil
echo
+echo "=== Corrupted size field in compressed cluster descriptor ==="
+echo
+# Create an empty image and fill half of it with compressed data.
+# The L2 entries of the two compressed clusters are located at
+# 0x800000 and 0x800008, their original values are 0x4008000000a00000
+# and 0x4008000000a00802 (5 sectors for compressed data each).
+_make_test_img 8M -o cluster_size=2M
+$QEMU_IO -c "write -c -P 0x11 0 2M" -c "write -c -P 0x11 2M 2M" "$TEST_IMG" \
+ 2>&1 | _filter_qemu_io | _filter_testdir
+
+# Reduce size of compressed data to 4 sectors: this corrupts the image.
+poke_file "$TEST_IMG" $((0x800000)) "\x40\x06"
+$QEMU_IO -c "read -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+
+# 'qemu-img check' however doesn't see anything wrong because it
+# doesn't try to decompress the data and the refcounts are consistent.
+# TODO: update qemu-img so this can be detected.
+_check_test_img
+
+# Increase size of compressed data to the maximum (8192 sectors).
+# This makes QEMU read more data (8192 sectors instead of 5, host
+# addresses [0xa00000, 0xdfffff]), but the decompression algorithm
+# stops once we have enough to restore the uncompressed cluster, so
+# the rest of the data is ignored.
+poke_file "$TEST_IMG" $((0x800000)) "\x7f\xfe"
+# Do it also for the second compressed cluster (L2 entry at 0x800008).
+# In this case the compressed data would span 3 host clusters
+# (host addresses: [0xa00802, 0xe00801])
+poke_file "$TEST_IMG" $((0x800008)) "\x7f\xfe"
+
+# Here the image is too small so we're asking QEMU to read beyond the
+# end of the image.
+$QEMU_IO -c "read -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+# But if we grow the image we won't be reading beyond its end anymore.
+$QEMU_IO -c "write -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+$QEMU_IO -c "read -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+
+# The refcount data is however wrong because due to the increased size
+# of the compressed data it now reaches the following host clusters.
+# This can be repaired by qemu-img check by increasing the refcount of
+# those clusters.
+# TODO: update qemu-img to correct the compressed cluster size instead.
+_check_test_img -r all
+$QEMU_IO -c "read -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+$QEMU_IO -c "read -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+
+echo
echo "=== Full allocation with -S 0 ==="
echo
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
index 47d8656db8..a6b7fe007e 100644
--- a/tests/qemu-iotests/122.out
+++ b/tests/qemu-iotests/122.out
@@ -99,6 +99,39 @@ read 1024/1024 bytes at offset 1047552
read 1046528/1046528 bytes at offset 1048576
1022 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+=== Corrupted size field in compressed cluster descriptor ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608
+wrote 2097152/2097152 bytes at offset 0
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2097152/2097152 bytes at offset 2097152
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read failed: Input/output error
+No errors were found on the image.
+read 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 4194304/4194304 bytes at offset 4194304
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ERROR cluster 6 refcount=1 reference=3
+ERROR cluster 7 refcount=1 reference=2
+Repairing cluster 6 refcount=1 reference=3
+Repairing cluster 7 refcount=1 reference=2
+Repairing OFLAG_COPIED data cluster: l2_entry=8000000000c00000 refcount=3
+Repairing OFLAG_COPIED data cluster: l2_entry=8000000000e00000 refcount=2
+The following inconsistencies were found and repaired:
+
+ 0 leaked clusters
+ 4 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+read 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4194304/4194304 bytes at offset 4194304
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
=== Full allocation with -S 0 ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
index 44cc01ed87..0aa4395a57 100755
--- a/tests/qemu-iotests/186
+++ b/tests/qemu-iotests/186
@@ -64,7 +64,7 @@ function check_info_block()
{
echo "info block" |
do_run_qemu "$@" | _filter_win32 | _filter_hmp | _filter_qemu |
- _filter_generated_node_ids
+ _filter_generated_node_ids | _filter_qom_path
}
@@ -133,10 +133,6 @@ check_info_block -drive if=ide,driver=null-co
check_info_block -drive if=ide,media=cdrom
check_info_block -drive if=ide,driver=null-co,media=cdrom
-check_info_block -drive if=scsi,driver=null-co
-check_info_block -drive if=scsi,media=cdrom
-check_info_block -drive if=scsi,driver=null-co,media=cdrom
-
check_info_block -drive if=virtio,driver=null-co
check_info_block -drive if=pflash,driver=null-co,size=1M
diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
index c8377fe146..716b01ac3d 100644
--- a/tests/qemu-iotests/186.out
+++ b/tests/qemu-iotests/186.out
@@ -7,7 +7,7 @@ Testing: -device floppy
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
/machine/peripheral-anon/device[1]: [not inserted]
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -23,7 +23,7 @@ Testing: -device ide-cd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
/machine/peripheral-anon/device[1]: [not inserted]
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -39,7 +39,7 @@ Testing: -device scsi-cd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
/machine/peripheral-anon/device[1]: [not inserted]
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -58,7 +58,7 @@ Testing: -blockdev driver=null-co,node-name=null -device ide-hd,drive=null
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -74,7 +74,7 @@ Testing: -blockdev driver=null-co,node-name=null -device scsi-hd,drive=null
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -90,7 +90,7 @@ Testing: -blockdev driver=null-co,node-name=null -device virtio-blk-pci,drive=nu
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]/virtio-backend
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -98,7 +98,7 @@ Testing: -blockdev driver=null-co,node-name=null -device virtio-blk-pci,drive=nu
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: null-co:// (null-co)
- Attached to: /machine/peripheral/qdev_id/virtio-backend
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -106,7 +106,7 @@ Testing: -blockdev driver=null-co,node-name=null -device floppy,drive=null
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -124,7 +124,7 @@ Testing: -blockdev driver=null-co,node-name=null -device ide-cd,drive=null
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -142,7 +142,7 @@ Testing: -blockdev driver=null-co,node-name=null -device scsi-cd,drive=null
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -191,7 +191,7 @@ none0 (null): null-co:// (null-co)
Cache mode: writeback
null: null-co:// (null-co)
- Attached to: /machine/peripheral/qdev_id/virtio-backend
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -241,7 +241,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device ide-hd,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -257,7 +257,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device scsi-hd,drive=none
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -273,7 +273,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device virtio-blk-pci,dri
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]/virtio-backend
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -281,7 +281,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device virtio-blk-pci,dri
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): null-co:// (null-co)
- Attached to: /machine/peripheral/qdev_id/virtio-backend
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -289,7 +289,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device floppy,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -307,7 +307,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device ide-cd,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -325,7 +325,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device scsi-cd,drive=none
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -353,7 +353,7 @@ Testing: -drive if=none -device floppy,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0: [not inserted]
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -369,7 +369,7 @@ Testing: -drive if=none -device ide-cd,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0: [not inserted]
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -385,7 +385,7 @@ Testing: -drive if=none -device scsi-cd,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0: [not inserted]
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -404,7 +404,7 @@ Testing: -drive if=floppy
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
floppy0: [not inserted]
- Attached to: /machine/unattached/device[17]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -412,7 +412,7 @@ Testing: -drive if=floppy,driver=null-co
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
floppy0 (NODE_NAME): null-co:// (null-co)
- Attached to: /machine/unattached/device[17]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -421,7 +421,7 @@ Testing: -drive if=ide,driver=null-co
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
ide0-hd0 (NODE_NAME): null-co:// (null-co)
- Attached to: /machine/unattached/device[18]
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -429,7 +429,7 @@ Testing: -drive if=ide,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
ide0-cd0: [not inserted]
- Attached to: /machine/unattached/device[18]
+ Attached to: PATH
Removable device: not locked, tray closed
(qemu) quit
@@ -437,35 +437,7 @@ Testing: -drive if=ide,driver=null-co,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
ide0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
- Attached to: /machine/unattached/device[18]
- Removable device: not locked, tray closed
- Cache mode: writeback
-(qemu) quit
-
-Testing: -drive if=scsi,driver=null-co
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,driver=null-co: warning: bus=0,unit=0 is deprecated with this machine type
-info block
-scsi0-hd0 (NODE_NAME): null-co:// (null-co)
- Attached to: /machine/unattached/device[27]/scsi.0/legacy[0]
- Cache mode: writeback
-(qemu) quit
-
-Testing: -drive if=scsi,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
-info block
-scsi0-cd0: [not inserted]
- Attached to: /machine/unattached/device[27]/scsi.0/legacy[0]
- Removable device: not locked, tray closed
-(qemu) quit
-
-Testing: -drive if=scsi,driver=null-co,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,driver=null-co,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
-info block
-scsi0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
- Attached to: /machine/unattached/device[27]/scsi.0/legacy[0]
+ Attached to: PATH
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -474,7 +446,7 @@ Testing: -drive if=virtio,driver=null-co
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
virtio0 (NODE_NAME): null-co:// (null-co)
- Attached to: /machine/peripheral-anon/device[1]/virtio-backend
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
@@ -482,7 +454,7 @@ Testing: -drive if=pflash,driver=null-co,size=1M
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
pflash0 (NODE_NAME): json:{"driver": "null-co", "size": "1M"} (null-co)
- Attached to: /machine/unattached/device[2]
+ Attached to: PATH
Cache mode: writeback
(qemu) quit
diff --git a/tests/qemu-iotests/208 b/tests/qemu-iotests/208
index 4e82b96c82..18f59ada94 100755
--- a/tests/qemu-iotests/208
+++ b/tests/qemu-iotests/208
@@ -28,7 +28,7 @@ with iotests.FilePath('disk.img') as disk_img_path, \
iotests.VM() as vm:
img_size = '10M'
- iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk_img_path, img_size)
+ iotests.qemu_img_create('-f', iotests.imgfmt, disk_img_path, img_size)
iotests.log('Launching VM...')
(vm.add_drive(disk_img_path, 'node-name=drive0-node', interface='none')
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index ec8033350d..aa94c6c7ea 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -538,8 +538,8 @@ if [ -z "$QEMU_PROG" ]
then
if [ -x "$build_iotests/qemu" ]; then
export QEMU_PROG="$build_iotests/qemu"
- elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
- export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
+ elif [ -x "$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}" ]; then
+ export QEMU_PROG="$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}"
else
pushd "$build_root" > /dev/null
for binary in *-softmmu/qemu-system-*
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index cdcda54546..102aa6878a 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -23,6 +23,7 @@ PATH=".:$PATH"
HOSTOS=`uname -s`
arch=`uname -m`
+[[ "$arch" =~ "ppc64" ]] && qemu_arch=ppc64 || qemu_arch="$arch"
export PWD=`pwd`
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index cb2be23340..c5f4bcf578 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -32,6 +32,11 @@ _filter_generated_node_ids()
sed -re 's/\#block[0-9]{3,}/NODE_NAME/'
}
+_filter_qom_path()
+{
+ sed -e 's#\(Attached to: *\) /.*#\1 PATH#'
+}
+
# replace occurrences of the actual TEST_DIR value with TEST_DIR
_filter_testdir()
{
diff --git a/tests/test-crypto-tlssession.c b/tests/test-crypto-tlssession.c
index 1a4a066d76..82f21c27f2 100644
--- a/tests/test-crypto-tlssession.c
+++ b/tests/test-crypto-tlssession.c
@@ -75,6 +75,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
"server" : "client"),
"dir", certdir,
"verify-peer", "yes",
+ "priority", "NORMAL",
/* We skip initial sanity checks here because we
* want to make sure that problems are being
* detected at the TLS session validation stage,
diff --git a/tests/test-io-channel-tls.c b/tests/test-io-channel-tls.c
index 32743b2c96..bb88ee870f 100644
--- a/tests/test-io-channel-tls.c
+++ b/tests/test-io-channel-tls.c
@@ -78,6 +78,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
"server" : "client"),
"dir", certdir,
"verify-peer", "yes",
+ "priority", "NORMAL",
/* We skip initial sanity checks here because we
* want to make sure that problems are being
* detected at the TLS session validation stage,
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 686d88decf..3a2d508c35 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -107,10 +107,7 @@ class BaseVM(object):
assert not isinstance(cmd, str)
ssh_cmd += ["%s@127.0.0.1" % user] + list(cmd)
logging.debug("ssh_cmd: %s", " ".join(ssh_cmd))
- r = subprocess.call(ssh_cmd,
- stdin=sys.stdin if interactive else self._devnull,
- stdout=sys.stdout if interactive else self._stdout,
- stderr=sys.stderr if interactive else self._stderr)
+ r = subprocess.call(ssh_cmd)
if check and r != 0:
raise Exception("SSH command failed: %s" % cmd)
return r
diff --git a/ui/console.c b/ui/console.c
index 530a491987..3fb2f4e09f 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1191,11 +1191,22 @@ static const int qcode_to_keysym[Q_KEY_CODE__MAX] = {
[Q_KEY_CODE_BACKSPACE] = QEMU_KEY_BACKSPACE,
};
-bool kbd_put_qcode_console(QemuConsole *s, int qcode)
+static const int ctrl_qcode_to_keysym[Q_KEY_CODE__MAX] = {
+ [Q_KEY_CODE_UP] = QEMU_KEY_CTRL_UP,
+ [Q_KEY_CODE_DOWN] = QEMU_KEY_CTRL_DOWN,
+ [Q_KEY_CODE_RIGHT] = QEMU_KEY_CTRL_RIGHT,
+ [Q_KEY_CODE_LEFT] = QEMU_KEY_CTRL_LEFT,
+ [Q_KEY_CODE_HOME] = QEMU_KEY_CTRL_HOME,
+ [Q_KEY_CODE_END] = QEMU_KEY_CTRL_END,
+ [Q_KEY_CODE_PGUP] = QEMU_KEY_CTRL_PAGEUP,
+ [Q_KEY_CODE_PGDN] = QEMU_KEY_CTRL_PAGEDOWN,
+};
+
+bool kbd_put_qcode_console(QemuConsole *s, int qcode, bool ctrl)
{
int keysym;
- keysym = qcode_to_keysym[qcode];
+ keysym = ctrl ? ctrl_qcode_to_keysym[qcode] : qcode_to_keysym[qcode];
if (keysym == 0) {
return false;
}
diff --git a/ui/gtk.c b/ui/gtk.c
index ef5bc42094..e98ac4d2fc 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1197,12 +1197,12 @@ static gboolean gd_text_key_down(GtkWidget *widget,
QemuConsole *con = vc->gfx.dcl.con;
if (key->keyval == GDK_KEY_Delete) {
- kbd_put_qcode_console(con, Q_KEY_CODE_DELETE);
+ kbd_put_qcode_console(con, Q_KEY_CODE_DELETE, false);
} else if (key->length) {
kbd_put_string_console(con, key->string, key->length);
} else {
int qcode = gd_map_keycode(key->hardware_keycode);
- kbd_put_qcode_console(con, qcode);
+ kbd_put_qcode_console(con, qcode, false);
}
return TRUE;
}
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index 5e1073a084..c3683e6b65 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -32,8 +32,6 @@
#include "ui/sdl2.h"
#include "sysemu/sysemu.h"
-#include <epoxy/gl.h>
-
static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout)
{
if (scon->scanout_mode == scanout) {
diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c
index 605d781971..1378b63dd9 100644
--- a/ui/sdl2-input.c
+++ b/ui/sdl2-input.c
@@ -60,32 +60,8 @@ void sdl2_process_key(struct sdl2_console *scon,
qcode = qemu_input_map_usb_to_qcode[ev->keysym.scancode];
- if (!qemu_console_is_graphic(con)) {
- if (ev->type == SDL_KEYDOWN) {
- switch (ev->keysym.scancode) {
- case SDL_SCANCODE_RETURN:
- kbd_put_keysym_console(con, '\n');
- break;
- case SDL_SCANCODE_BACKSPACE:
- kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE);
- break;
- default:
- kbd_put_qcode_console(con, qcode);
- break;
- }
- }
- return;
- }
-
+ /* modifier state tracking */
switch (ev->keysym.scancode) {
-#if 0
- case SDL_SCANCODE_NUMLOCKCLEAR:
- case SDL_SCANCODE_CAPSLOCK:
- /* SDL does not send the key up event, so we generate it */
- qemu_input_event_send_key_qcode(con, qcode, true);
- qemu_input_event_send_key_qcode(con, qcode, false);
- return;
-#endif
case SDL_SCANCODE_LCTRL:
case SDL_SCANCODE_LSHIFT:
case SDL_SCANCODE_LALT:
@@ -99,8 +75,26 @@ void sdl2_process_key(struct sdl2_console *scon,
} else {
modifiers_state[ev->keysym.scancode] = 1;
}
- /* fall though */
+ break;
default:
+ /* nothing */
+ break;
+ }
+
+ if (!qemu_console_is_graphic(con)) {
+ bool ctrl = (modifiers_state[SDL_SCANCODE_LCTRL] ||
+ modifiers_state[SDL_SCANCODE_RCTRL]);
+ if (ev->type == SDL_KEYDOWN) {
+ switch (ev->keysym.scancode) {
+ case SDL_SCANCODE_RETURN:
+ kbd_put_keysym_console(con, '\n');
+ break;
+ default:
+ kbd_put_qcode_console(con, qcode, ctrl);
+ break;
+ }
+ }
+ } else {
qemu_input_event_send_key_qcode(con, qcode,
ev->type == SDL_KEYDOWN);
}
diff --git a/util/memfd.c b/util/memfd.c
index 07d579ea7d..b3ecbac19e 100644
--- a/util/memfd.c
+++ b/util/memfd.c
@@ -173,7 +173,13 @@ enum {
MEMFD_TODO
};
-bool qemu_memfd_check(void)
+/**
+ * qemu_memfd_alloc_check():
+ *
+ * Check if qemu_memfd_alloc() can allocate, including using a
+ * fallback implementation when host doesn't support memfd.
+ */
+bool qemu_memfd_alloc_check(void)
{
static int memfd_check = MEMFD_TODO;
@@ -188,3 +194,29 @@ bool qemu_memfd_check(void)
return memfd_check == MEMFD_OK;
}
+
+/**
+ * qemu_memfd_check():
+ *
+ * Check if host supports memfd.
+ */
+bool qemu_memfd_check(void)
+{
+#ifdef CONFIG_LINUX
+ static int memfd_check = MEMFD_TODO;
+
+ if (memfd_check == MEMFD_TODO) {
+ int mfd = memfd_create("test", 0);
+ if (mfd >= 0) {
+ memfd_check = MEMFD_OK;
+ close(mfd);
+ } else {
+ memfd_check = MEMFD_KO;
+ }
+ }
+
+ return memfd_check == MEMFD_OK;
+#else
+ return false;
+#endif
+}
diff --git a/util/sys_membarrier.c b/util/sys_membarrier.c
index 8dcb53e63e..1362c0c4c5 100644
--- a/util/sys_membarrier.c
+++ b/util/sys_membarrier.c
@@ -6,9 +6,9 @@
* Author: Paolo Bonzini <pbonzini@redhat.com>
*/
-#include <qemu/osdep.h>
-#include <qemu/sys_membarrier.h>
-#include <qemu/error-report.h>
+#include "qemu/osdep.h"
+#include "qemu/sys_membarrier.h"
+#include "qemu/error-report.h"
#ifdef CONFIG_LINUX
#include <linux/membarrier.h>