bump version to 2.9.1-1

master
Wolfgang Bumiller 2017-09-08 09:33:44 +02:00
parent 6c7dbd74a9
commit ddbcf45e51
64 changed files with 1297 additions and 1666 deletions

View File

@ -1,6 +1,6 @@
# also update debian/changelog
KVMVER=2.9.0
KVMPKGREL=5
KVMVER=2.9.1
KVMPKGREL=1
KVMPACKAGE = pve-qemu-kvm
KVMSRC = qemu

16
debian/changelog vendored
View File

@ -1,3 +1,19 @@
pve-qemu-kvm (2.9.1-1) stable; urgency=medium
* update to 2.9.1
* fix CVE-2017-14167: i386: multiboot OOB access while loading guest kernel image
* fix CVE-2017-13673: vga: reachable assert failure during during display update
* fix CVE-2017-13672: vga: OOB read access during display update
* fix CVE-2017-13711: Slirp: use-after-free when sending response
* fix CVE-2017-12809: ide: flushing of empty CDROM drives leads to NULL dereference
-- Proxmox Support Team <support@proxmox.com> Fri, 08 Sep 2017 09:31:33 +0200
pve-qemu-kvm (2.9.0-5) stable; urgency=medium
* Fix #1420: fix stop mode backups with virtio-blk

View File

@ -1,7 +1,7 @@
From 3949cb837593d29db5c06cef51f405ee3250c4c1 Mon Sep 17 00:00:00 2001
From b143eba39dd462833093ee1c9660bb157e72ce54 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Mon, 4 Jul 2016 15:02:26 +0200
Subject: [PATCH 01/23] Revert "target-i386: disable LINT0 after reset"
Subject: [PATCH 01/13] Revert "target-i386: disable LINT0 after reset"
This reverts commit b8eb5512fd8a115f164edbbe897cdf8884920ccb.
---
@ -9,7 +9,7 @@ This reverts commit b8eb5512fd8a115f164edbbe897cdf8884920ccb.
1 file changed, 9 insertions(+)
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index c3829e31b5..d4411a2fd4 100644
index 1ef56f8d10..31fb73e9fb 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -257,6 +257,15 @@ static void apic_reset_common(DeviceState *dev)

View File

@ -1,98 +0,0 @@
From e340d6c3321d3eb4e6f7854550cfdc94aa1c8143 Mon Sep 17 00:00:00 2001
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
Date: Wed, 26 Apr 2017 11:33:15 +0300
Subject: [PATCH 02/23] qemu-img: wait for convert coroutines to complete
On error path (like i/o error in one of the coroutines), it's required to
- wait for coroutines completion before cleaning the common structures
- reenter dependent coroutines so they ever finish
Introduced in 2d9187bc65.
Cc: qemu-stable@nongnu.org
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qemu-img.c | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index b9d1ef7bb8..59f4f7f22a 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1761,13 +1761,13 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
qemu_co_mutex_lock(&s->lock);
if (s->ret != -EINPROGRESS || s->sector_num >= s->total_sectors) {
qemu_co_mutex_unlock(&s->lock);
- goto out;
+ break;
}
n = convert_iteration_sectors(s, s->sector_num);
if (n < 0) {
qemu_co_mutex_unlock(&s->lock);
s->ret = n;
- goto out;
+ break;
}
/* save current sector and allocation status to local variables */
sector_num = s->sector_num;
@@ -1792,7 +1792,6 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
error_report("error while reading sector %" PRId64
": %s", sector_num, strerror(-ret));
s->ret = ret;
- goto out;
}
} else if (!s->min_sparse && status == BLK_ZERO) {
status = BLK_DATA;
@@ -1801,22 +1800,20 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
if (s->wr_in_order) {
/* keep writes in order */
- while (s->wr_offs != sector_num) {
- if (s->ret != -EINPROGRESS) {
- goto out;
- }
+ while (s->wr_offs != sector_num && s->ret == -EINPROGRESS) {
s->wait_sector_num[index] = sector_num;
qemu_coroutine_yield();
}
s->wait_sector_num[index] = -1;
}
- ret = convert_co_write(s, sector_num, n, buf, status);
- if (ret < 0) {
- error_report("error while writing sector %" PRId64
- ": %s", sector_num, strerror(-ret));
- s->ret = ret;
- goto out;
+ if (s->ret == -EINPROGRESS) {
+ ret = convert_co_write(s, sector_num, n, buf, status);
+ if (ret < 0) {
+ error_report("error while writing sector %" PRId64
+ ": %s", sector_num, strerror(-ret));
+ s->ret = ret;
+ }
}
if (s->wr_in_order) {
@@ -1837,7 +1834,6 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
}
}
-out:
qemu_vfree(buf);
s->co[index] = NULL;
s->running_coroutines--;
@@ -1899,7 +1895,7 @@ static int convert_do_copy(ImgConvertState *s)
qemu_coroutine_enter(s->co[i]);
}
- while (s->ret == -EINPROGRESS) {
+ while (s->running_coroutines) {
main_loop_wait(false);
}
--
2.11.0

View File

@ -1,7 +1,7 @@
From 1b7f7a21084578b528c6a3faac29f46c5dbd6408 Mon Sep 17 00:00:00 2001
From aec6bba73f7d7692de2c4196ee80e4d753b45604 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Fri, 2 Jun 2017 10:54:24 +0100
Subject: [PATCH 08/23] virtio-serial: fix segfault on disconnect
Subject: [PATCH 02/13] virtio-serial: fix segfault on disconnect
Since commit d4c19cdeeb2f1e474bc426a6da261f1d7346eb5b ("virtio-serial:
add missing virtio_detach_element() call") the following commands may

View File

@ -1,78 +0,0 @@
From 80a3ed331899e4710b33c4b2a88f1b7b888d6497 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Thu, 13 Apr 2017 17:43:34 +0200
Subject: [PATCH 03/23] block: Do not unref bs->file on error in BD's open
The block layer takes care of removing the bs->file child if the block
driver's bdrv_open()/bdrv_file_open() implementation fails. The block
driver therefore does not need to do so, and indeed should not unless it
sets bs->file to NULL afterwards -- because if this is not done, the
bdrv_unref_child() in bdrv_open_inherit() will dereference the freed
memory block at bs->file afterwards, which is not good.
We can now decide whether to add a "bs->file = NULL;" after each of the
offending bdrv_unref_child() invocations, or just drop them altogether.
The latter is simpler, so let's do that.
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/blkdebug.c | 4 +---
block/blkreplay.c | 3 ---
block/blkverify.c | 3 ---
3 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 67e8024e36..cc4a146e84 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -389,14 +389,12 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
} else if (align) {
error_setg(errp, "Invalid alignment");
ret = -EINVAL;
- goto fail_unref;
+ goto out;
}
ret = 0;
goto out;
-fail_unref:
- bdrv_unref_child(bs, bs->file);
out:
if (ret < 0) {
g_free(s->config_file);
diff --git a/block/blkreplay.c b/block/blkreplay.c
index e1102119fb..6aa5fd4156 100755
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -37,9 +37,6 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
ret = 0;
fail:
- if (ret < 0) {
- bdrv_unref_child(bs, bs->file);
- }
return ret;
}
diff --git a/block/blkverify.c b/block/blkverify.c
index 9a1e21c6ad..af23281669 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -142,9 +142,6 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
ret = 0;
fail:
- if (ret < 0) {
- bdrv_unref_child(bs, bs->file);
- }
qemu_opts_del(opts);
return ret;
}
--
2.11.0

View File

@ -1,7 +1,7 @@
From d312b31b5c5e8e36c6e283bdb04b4784dd2e023b Mon Sep 17 00:00:00 2001
From 3884a6e250302f5f3d002ed03c20fb9678ea85e7 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 1 Jun 2017 17:26:14 +0200
Subject: [PATCH 17/23] megasas: always store SCSIRequest* into MegasasCmd
Subject: [PATCH 03/13] megasas: always store SCSIRequest* into MegasasCmd
This ensures that the request is unref'ed properly, and avoids a
segmentation fault in the new qtest testcase that is added.
@ -14,10 +14,10 @@ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 887958481b..a0cafe3010 100644
index 135662df31..734fdaef90 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -607,6 +607,9 @@ static void megasas_reset_frames(MegasasState *s)
@@ -609,6 +609,9 @@ static void megasas_reset_frames(MegasasState *s)
static void megasas_abort_command(MegasasCmd *cmd)
{
/* Never abort internal commands. */
@ -27,7 +27,7 @@ index 887958481b..a0cafe3010 100644
if (cmd->req != NULL) {
scsi_req_cancel(cmd->req);
}
@@ -1014,7 +1017,6 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
@@ -1017,7 +1020,6 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
uint64_t pd_size;
uint16_t pd_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
uint8_t cmdbuf[6];
@ -35,7 +35,7 @@ index 887958481b..a0cafe3010 100644
size_t len, resid;
if (!cmd->iov_buf) {
@@ -1023,8 +1025,8 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
@@ -1026,8 +1028,8 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
info->inquiry_data[0] = 0x7f; /* Force PQual 0x3, PType 0x1f */
info->vpd_page83[0] = 0x7f;
megasas_setup_inquiry(cmdbuf, 0, sizeof(info->inquiry_data));
@ -46,7 +46,7 @@ index 887958481b..a0cafe3010 100644
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"PD get info std inquiry");
g_free(cmd->iov_buf);
@@ -1033,26 +1035,26 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
@@ -1036,26 +1038,26 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
}
trace_megasas_dcmd_internal_submit(cmd->index,
"PD get info std inquiry", lun);
@ -79,7 +79,7 @@ index 887958481b..a0cafe3010 100644
}
return MFI_STAT_INVALID_STATUS;
}
@@ -1214,7 +1216,6 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
@@ -1217,7 +1219,6 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
struct mfi_ld_info *info = cmd->iov_buf;
size_t dcmd_size = sizeof(struct mfi_ld_info);
uint8_t cdb[6];
@ -87,7 +87,7 @@ index 887958481b..a0cafe3010 100644
ssize_t len, resid;
uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
uint64_t ld_size;
@@ -1223,8 +1224,8 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
@@ -1226,8 +1227,8 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
cmd->iov_buf = g_malloc0(dcmd_size);
info = cmd->iov_buf;
megasas_setup_inquiry(cdb, 0x83, sizeof(info->vpd_page83));
@ -98,7 +98,7 @@ index 887958481b..a0cafe3010 100644
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"LD get info vpd inquiry");
g_free(cmd->iov_buf);
@@ -1233,10 +1234,10 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
@@ -1236,10 +1237,10 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
}
trace_megasas_dcmd_internal_submit(cmd->index,
"LD get info vpd inquiry", lun);
@ -111,7 +111,7 @@ index 887958481b..a0cafe3010 100644
}
return MFI_STAT_INVALID_STATUS;
}
@@ -1865,7 +1866,7 @@ static void megasas_command_complete(SCSIRequest *req, uint32_t status,
@@ -1851,7 +1852,7 @@ static void megasas_command_complete(SCSIRequest *req, uint32_t status,
return;
}

View File

@ -1,103 +0,0 @@
From 952bdc64b03ffc3bdf3529b22f291ad26ef94d1b Mon Sep 17 00:00:00 2001
From: Greg Kurz <groug@kaod.org>
Date: Thu, 25 May 2017 10:30:13 +0200
Subject: [PATCH 04/23] 9pfs: local: fix unlink of alien files in mapped-file
mode
When trying to remove a file from a directory, both created in non-mapped
mode, the file remains and EBADF is returned to the guest.
This is a regression introduced by commit "df4938a6651b 9pfs: local:
unlinkat: don't follow symlinks" when fixing CVE-2016-9602. It changed the
way we unlink the metadata file from
ret = remove("$dir/.virtfs_metadata/$name");
if (ret < 0 && errno != ENOENT) {
/* Error out */
}
/* Ignore absence of metadata */
to
fd = openat("$dir/.virtfs_metadata")
unlinkat(fd, "$name")
if (ret < 0 && errno != ENOENT) {
/* Error out */
}
/* Ignore absence of metadata */
If $dir was created in non-mapped mode, openat() fails with ENOENT and
we pass -1 to unlinkat(), which fails in turn with EBADF.
We just need to check the return of openat() and ignore ENOENT, in order
to restore the behaviour we had with remove().
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
[groug: rewrote the comments as suggested by Eric]
---
hw/9pfs/9p-local.c | 34 +++++++++++++++-------------------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index f3ebca4f7a..7a0c383e7e 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -957,6 +957,14 @@ static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
int map_dirfd;
+ /* We need to remove the metadata as well:
+ * - the metadata directory if we're removing a directory
+ * - the metadata file in the parent's metadata directory
+ *
+ * If any of these are missing (ie, ENOENT) then we're probably
+ * trying to remove something that wasn't created in mapped-file
+ * mode. We just ignore the error.
+ */
if (flags == AT_REMOVEDIR) {
int fd;
@@ -964,32 +972,20 @@ static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
if (fd == -1) {
goto err_out;
}
- /*
- * If directory remove .virtfs_metadata contained in the
- * directory
- */
ret = unlinkat(fd, VIRTFS_META_DIR, AT_REMOVEDIR);
close_preserve_errno(fd);
if (ret < 0 && errno != ENOENT) {
- /*
- * We didn't had the .virtfs_metadata file. May be file created
- * in non-mapped mode ?. Ignore ENOENT.
- */
goto err_out;
}
}
- /*
- * Now remove the name from parent directory
- * .virtfs_metadata directory.
- */
map_dirfd = openat_dir(dirfd, VIRTFS_META_DIR);
- ret = unlinkat(map_dirfd, name, 0);
- close_preserve_errno(map_dirfd);
- if (ret < 0 && errno != ENOENT) {
- /*
- * We didn't had the .virtfs_metadata file. May be file created
- * in non-mapped mode ?. Ignore ENOENT.
- */
+ if (map_dirfd != -1) {
+ ret = unlinkat(map_dirfd, name, 0);
+ close_preserve_errno(map_dirfd);
+ if (ret < 0 && errno != ENOENT) {
+ goto err_out;
+ }
+ } else if (errno != ENOENT) {
goto err_out;
}
}
--
2.11.0

View File

@ -1,7 +1,7 @@
From f3b5bdea7ea51404bbf88bea6fc8887586a423b2 Mon Sep 17 00:00:00 2001
From 918e23903f5712274830bb20e2d5603bf5794af7 Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Mon, 17 Jul 2017 17:33:26 +0530
Subject: [PATCH 23/23] slirp: check len against dhcp options array end
Subject: [PATCH 04/13] slirp: check len against dhcp options array end
While parsing dhcp options string in 'dhcp_decode', if an options'
length 'len' appeared towards the end of 'bp_vend' array, ensuing

View File

@ -0,0 +1,44 @@
From f635d03bc56b8d56589f8f962f893de1e8126c06 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Wed, 9 Aug 2017 17:02:11 +0100
Subject: [PATCH 05/13] IDE: Do not flush empty CDROM drives
The block backend changed in a way that flushing empty CDROM drives now
crashes. Amend IDE to avoid doing so until the root problem can be
addressed for 2.11.
Original patch by John Snow <jsnow@redhat.com>.
Reported-by: Kieron Shorrock <kshorrock@paloaltonetworks.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20170809160212.29976-2-stefanha@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/ide/core.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 0b48b64d3a..bea39536b0 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1063,7 +1063,15 @@ static void ide_flush_cache(IDEState *s)
s->status |= BUSY_STAT;
ide_set_retry(s);
block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH);
- s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
+
+ if (blk_bs(s->blk)) {
+ s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
+ } else {
+ /* XXX blk_aio_flush() crashes when blk_bs(blk) is NULL, remove this
+ * temporary workaround when blk_aio_*() functions handle NULL blk_bs.
+ */
+ ide_flush_cb(s, 0);
+ }
}
static void ide_cfata_metadata_inquiry(IDEState *s)
--
2.11.0

View File

@ -1,44 +0,0 @@
From 0720bbba9f7ebac6f4f0ae7a65cd687ac6f3c452 Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Wed, 10 May 2017 13:39:45 -0400
Subject: [PATCH 05/23] blockdev: use drained_begin/end for qmp_block_resize
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1447551
If one tries to issue a block_resize while a guest is busy
accessing the disk, it is possible that qemu may deadlock
when invoking aio_poll from both the main loop and the iothread.
Replace another instance of bdrv_drain_all that doesn't
quite belong.
Cc: qemu-stable@nongnu.org
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
blockdev.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 1eeffb0571..1dca232781 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2929,10 +2929,9 @@ void qmp_block_resize(bool has_device, const char *device,
goto out;
}
- /* complete all in-flight operations before resizing the device */
- bdrv_drain_all();
-
+ bdrv_drained_begin(bs);
ret = blk_truncate(blk, size);
+ bdrv_drained_end(bs);
switch (ret) {
case 0:
break;
--
2.11.0

View File

@ -1,71 +0,0 @@
From 28a204390093e5dfa0b4a2e94c06e807fe777c5f Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 8 May 2017 14:07:05 -0400
Subject: [PATCH 06/23] aio: add missing aio_notify() to aio_enable_external()
The main loop uses aio_disable_external()/aio_enable_external() to
temporarily disable processing of external AioContext clients like
device emulation.
This allows monitor commands to quiesce I/O and prevent the guest from
submitting new requests while a monitor command is in progress.
The aio_enable_external() API is currently broken when an IOThread is in
aio_poll() waiting for fd activity when the main loop re-enables
external clients. Incrementing ctx->external_disable_cnt does not wake
the IOThread from ppoll(2) so fd processing remains suspended and leads
to unresponsive emulated devices.
This patch adds an aio_notify() call to aio_enable_external() so the
IOThread is kicked out of ppoll(2) and will re-arm the file descriptors.
The bug can be reproduced as follows:
$ qemu -M accel=kvm -m 1024 \
-object iothread,id=iothread0 \
-device virtio-scsi-pci,iothread=iothread0,id=virtio-scsi-pci0 \
-drive if=none,id=drive0,aio=native,cache=none,format=raw,file=test.img \
-device scsi-hd,id=scsi-hd0,drive=drive0 \
-qmp tcp::5555,server,nowait
$ scripts/qmp/qmp-shell localhost:5555
(qemu) blockdev-snapshot-sync device=drive0 snapshot-file=sn1.qcow2
mode=absolute-paths format=qcow2
After blockdev-snapshot-sync completes the SCSI disk will be
unresponsive. This leads to request timeouts inside the guest.
Reported-by: Qianqian Zhu <qizhu@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20170508180705.20609-1-stefanha@redhat.com
Suggested-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
include/block/aio.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/block/aio.h b/include/block/aio.h
index 406e32305a..e9aeeaec94 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -454,8 +454,14 @@ static inline void aio_disable_external(AioContext *ctx)
*/
static inline void aio_enable_external(AioContext *ctx)
{
- assert(ctx->external_disable_cnt > 0);
- atomic_dec(&ctx->external_disable_cnt);
+ int old;
+
+ old = atomic_fetch_dec(&ctx->external_disable_cnt);
+ assert(old > 0);
+ if (old == 1) {
+ /* Kick event loop so it re-arms file descriptors */
+ aio_notify(ctx);
+ }
}
/**
--
2.11.0

View File

@ -0,0 +1,51 @@
From 9d6486413e60b1d973f7ec2ac006fc9b8e210ddd Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 21 Apr 2017 11:16:24 +0200
Subject: [PATCH 06/13] bitmap: add bitmap_copy_and_clear_atomic
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-2-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/qemu/bitmap.h | 2 ++
util/bitmap.c | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
index 63ea2d0b1e..c318da12d7 100644
--- a/include/qemu/bitmap.h
+++ b/include/qemu/bitmap.h
@@ -220,6 +220,8 @@ void bitmap_set(unsigned long *map, long i, long len);
void bitmap_set_atomic(unsigned long *map, long i, long len);
void bitmap_clear(unsigned long *map, long start, long nr);
bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr);
+void bitmap_copy_and_clear_atomic(unsigned long *dst, unsigned long *src,
+ long nr);
unsigned long bitmap_find_next_zero_area(unsigned long *map,
unsigned long size,
unsigned long start,
diff --git a/util/bitmap.c b/util/bitmap.c
index c1a84ca5e3..efced9a7d8 100644
--- a/util/bitmap.c
+++ b/util/bitmap.c
@@ -287,6 +287,17 @@ bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr)
return dirty != 0;
}
+void bitmap_copy_and_clear_atomic(unsigned long *dst, unsigned long *src,
+ long nr)
+{
+ while (nr > 0) {
+ *dst = atomic_xchg(src, 0);
+ dst++;
+ src++;
+ nr -= BITS_PER_LONG;
+ }
+}
+
#define ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
/**
--
2.11.0

View File

@ -0,0 +1,242 @@
From a89da93a2d3ffd3ba9516da89ecfbb0dd5fd51ad Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 21 Apr 2017 11:16:25 +0200
Subject: [PATCH 07/13] memory: add support getting and using a dirty bitmap
copy.
This patch adds support for getting and using a local copy of the dirty
bitmap.
memory_region_snapshot_and_clear_dirty() will create a snapshot of the
dirty bitmap for the specified range, clear the dirty bitmap and return
the copy. The returned bitmap can be a bit larger than requested, the
range is expanded so the code can copy unsigned longs from the bitmap
and avoid atomic bit update operations.
memory_region_snapshot_get_dirty() will return the dirty status of
pages, pretty much like memory_region_get_dirty(), but using the copy
returned by memory_region_copy_and_clear_dirty().
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-3-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
exec.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
include/exec/memory.h | 47 +++++++++++++++++++++++++++++++
include/exec/ram_addr.h | 7 +++++
include/qemu/typedefs.h | 1 +
memory.c | 17 +++++++++++
5 files changed, 147 insertions(+)
diff --git a/exec.c b/exec.c
index fcb5b16131..07c2c8ea88 100644
--- a/exec.c
+++ b/exec.c
@@ -223,6 +223,12 @@ struct CPUAddressSpace {
MemoryListener tcg_as_listener;
};
+struct DirtyBitmapSnapshot {
+ ram_addr_t start;
+ ram_addr_t end;
+ unsigned long dirty[];
+};
+
#endif
#if !defined(CONFIG_USER_ONLY)
@@ -1061,6 +1067,75 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start,
return dirty;
}
+DirtyBitmapSnapshot *cpu_physical_memory_snapshot_and_clear_dirty
+ (ram_addr_t start, ram_addr_t length, unsigned client)
+{
+ DirtyMemoryBlocks *blocks;
+ unsigned long align = 1UL << (TARGET_PAGE_BITS + BITS_PER_LEVEL);
+ ram_addr_t first = QEMU_ALIGN_DOWN(start, align);
+ ram_addr_t last = QEMU_ALIGN_UP(start + length, align);
+ DirtyBitmapSnapshot *snap;
+ unsigned long page, end, dest;
+
+ snap = g_malloc0(sizeof(*snap) +
+ ((last - first) >> (TARGET_PAGE_BITS + 3)));
+ snap->start = first;
+ snap->end = last;
+
+ page = first >> TARGET_PAGE_BITS;
+ end = last >> TARGET_PAGE_BITS;
+ dest = 0;
+
+ rcu_read_lock();
+
+ blocks = atomic_rcu_read(&ram_list.dirty_memory[client]);
+
+ while (page < end) {
+ unsigned long idx = page / DIRTY_MEMORY_BLOCK_SIZE;
+ unsigned long offset = page % DIRTY_MEMORY_BLOCK_SIZE;
+ unsigned long num = MIN(end - page, DIRTY_MEMORY_BLOCK_SIZE - offset);
+
+ assert(QEMU_IS_ALIGNED(offset, (1 << BITS_PER_LEVEL)));
+ assert(QEMU_IS_ALIGNED(num, (1 << BITS_PER_LEVEL)));
+ offset >>= BITS_PER_LEVEL;
+
+ bitmap_copy_and_clear_atomic(snap->dirty + dest,
+ blocks->blocks[idx] + offset,
+ num);
+ page += num;
+ dest += num >> BITS_PER_LEVEL;
+ }
+
+ rcu_read_unlock();
+
+ if (tcg_enabled()) {
+ tlb_reset_dirty_range_all(start, length);
+ }
+
+ return snap;
+}
+
+bool cpu_physical_memory_snapshot_get_dirty(DirtyBitmapSnapshot *snap,
+ ram_addr_t start,
+ ram_addr_t length)
+{
+ unsigned long page, end;
+
+ assert(start >= snap->start);
+ assert(start + length <= snap->end);
+
+ end = TARGET_PAGE_ALIGN(start + length - snap->start) >> TARGET_PAGE_BITS;
+ page = (start - snap->start) >> TARGET_PAGE_BITS;
+
+ while (page < end) {
+ if (test_bit(page, snap->dirty)) {
+ return true;
+ }
+ page++;
+ }
+ return false;
+}
+
/* Called from RCU critical section */
hwaddr memory_region_section_get_iotlb(CPUState *cpu,
MemoryRegionSection *section,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index f20b191793..1e15e79d00 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -871,6 +871,53 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr,
*/
bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,
hwaddr size, unsigned client);
+
+/**
+ * memory_region_snapshot_and_clear_dirty: Get a snapshot of the dirty
+ * bitmap and clear it.
+ *
+ * Creates a snapshot of the dirty bitmap, clears the dirty bitmap and
+ * returns the snapshot. The snapshot can then be used to query dirty
+ * status, using memory_region_snapshot_get_dirty. Unlike
+ * memory_region_test_and_clear_dirty this allows to query the same
+ * page multiple times, which is especially useful for display updates
+ * where the scanlines often are not page aligned.
+ *
+ * The dirty bitmap region which gets copyed into the snapshot (and
+ * cleared afterwards) can be larger than requested. The boundaries
+ * are rounded up/down so complete bitmap longs (covering 64 pages on
+ * 64bit hosts) can be copied over into the bitmap snapshot. Which
+ * isn't a problem for display updates as the extra pages are outside
+ * the visible area, and in case the visible area changes a full
+ * display redraw is due anyway. Should other use cases for this
+ * function emerge we might have to revisit this implementation
+ * detail.
+ *
+ * Use g_free to release DirtyBitmapSnapshot.
+ *
+ * @mr: the memory region being queried.
+ * @addr: the address (relative to the start of the region) being queried.
+ * @size: the size of the range being queried.
+ * @client: the user of the logging information; typically %DIRTY_MEMORY_VGA.
+ */
+DirtyBitmapSnapshot *memory_region_snapshot_and_clear_dirty(MemoryRegion *mr,
+ hwaddr addr,
+ hwaddr size,
+ unsigned client);
+
+/**
+ * memory_region_snapshot_get_dirty: Check whether a range of bytes is dirty
+ * in the specified dirty bitmap snapshot.
+ *
+ * @mr: the memory region being queried.
+ * @snap: the dirty bitmap snapshot
+ * @addr: the address (relative to the start of the region) being queried.
+ * @size: the size of the range being queried.
+ */
+bool memory_region_snapshot_get_dirty(MemoryRegion *mr,
+ DirtyBitmapSnapshot *snap,
+ hwaddr addr, hwaddr size);
+
/**
* memory_region_sync_dirty_bitmap: Synchronize a region's dirty bitmap with
* any external TLBs (e.g. kvm)
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index b05dc84ab9..2b63d7f59e 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -343,6 +343,13 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start,
ram_addr_t length,
unsigned client);
+DirtyBitmapSnapshot *cpu_physical_memory_snapshot_and_clear_dirty
+ (ram_addr_t start, ram_addr_t length, unsigned client);
+
+bool cpu_physical_memory_snapshot_get_dirty(DirtyBitmapSnapshot *snap,
+ ram_addr_t start,
+ ram_addr_t length);
+
static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start,
ram_addr_t length)
{
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index e95f28cfec..f08d327aec 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -23,6 +23,7 @@ typedef struct CPUAddressSpace CPUAddressSpace;
typedef struct CPUState CPUState;
typedef struct DeviceListener DeviceListener;
typedef struct DeviceState DeviceState;
+typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
typedef struct DisplayChangeListener DisplayChangeListener;
typedef struct DisplayState DisplayState;
typedef struct DisplaySurface DisplaySurface;
diff --git a/memory.c b/memory.c
index 4c95aaf39c..8a0648551f 100644
--- a/memory.c
+++ b/memory.c
@@ -1716,6 +1716,23 @@ bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,
memory_region_get_ram_addr(mr) + addr, size, client);
}
+DirtyBitmapSnapshot *memory_region_snapshot_and_clear_dirty(MemoryRegion *mr,
+ hwaddr addr,
+ hwaddr size,
+ unsigned client)
+{
+ assert(mr->ram_block);
+ return cpu_physical_memory_snapshot_and_clear_dirty(
+ memory_region_get_ram_addr(mr) + addr, size, client);
+}
+
+bool memory_region_snapshot_get_dirty(MemoryRegion *mr, DirtyBitmapSnapshot *snap,
+ hwaddr addr, hwaddr size)
+{
+ assert(mr->ram_block);
+ return cpu_physical_memory_snapshot_get_dirty(snap,
+ memory_region_get_ram_addr(mr) + addr, size);
+}
void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
{
--
2.11.0

View File

@ -1,42 +0,0 @@
From 691689ab216143f5fefd8e229ffd91086b9a261e Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Tue, 30 May 2017 10:59:43 +0200
Subject: [PATCH 07/23] virtio-serial-bus: Unset hotplug handler when unrealize
Virtio serial device controls the lifetime of virtio-serial-bus and
virtio-serial-bus links back to the device via its hotplug-handler
property. This extra ref-count prevents the device from getting
finalized, leaving the VirtIODevice memory listener registered and
leading to use-after-free later on.
This patch addresses the same issue as Fam Zheng's
"virtio-scsi: Unset hotplug handler when unrealize"
only for a different virtio device.
Cc: qemu-stable@nongnu.org
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
---
hw/char/virtio-serial-bus.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index d797a6796e..aa9c11ae92 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -1121,6 +1121,9 @@ static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
timer_free(vser->post_load->timer);
g_free(vser->post_load);
}
+
+ qbus_set_hotplug_handler(BUS(&vser->bus), NULL, errp);
+
virtio_cleanup(vdev);
}
--
2.11.0

View File

@ -0,0 +1,63 @@
From cef8fb2b8ea711b6686032f86b1caf1815786aaa Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 21 Apr 2017 11:16:26 +0200
Subject: [PATCH 08/13] vga: add vga_scanline_invalidated helper
Add vga_scanline_invalidated helper to check whenever a scanline was
invalidated. Add a sanity check to fix OOB read access for display
heights larger than 2048.
Only cirrus uses this, for hardware cursor rendering, so having this
work properly for the first 2048 scanlines only shouldn't be a problem
as the cirrus can't handle large resolutions anyway. Also changing the
invalidated_y_table size would break live migration.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-4-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/display/vga.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 69c3e1d674..3991b88aac 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1434,6 +1434,14 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
}
}
+static bool vga_scanline_invalidated(VGACommonState *s, int y)
+{
+ if (y >= VGA_MAX_HEIGHT) {
+ return false;
+ }
+ return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f));
+}
+
void vga_sync_dirty_bitmap(VGACommonState *s)
{
memory_region_sync_dirty_bitmap(&s->vram);
@@ -1638,8 +1646,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
page1 = addr + bwidth - 1;
update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
DIRTY_MEMORY_VGA);
- /* explicit invalidation for the hardware cursor */
- update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
+ /* explicit invalidation for the hardware cursor (cirrus only) */
+ update |= vga_scanline_invalidated(s, y);
if (update) {
if (y_start < 0)
y_start = y;
@@ -1686,7 +1694,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
page_max - page_min,
DIRTY_MEMORY_VGA);
}
- memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
+ memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
}
static void vga_draw_blank(VGACommonState *s, int full_update)
--
2.11.0

View File

@ -1,96 +0,0 @@
From 02b34affd75f205f50445217ad28ef28002e0bf0 Mon Sep 17 00:00:00 2001
From: Sameeh Jubran <sameeh@daynix.com>
Date: Mon, 22 May 2017 14:26:22 +0300
Subject: [PATCH 09/23] e1000e: Fix ICR "Other" causes clear logic
This commit fixes a bug which causes the guest to hang. The bug was
observed upon a "receive overrun" (bit #6 of the ICR register)
interrupt which could be triggered post migration in a heavy traffic
environment. Even though the "receive overrun" bit (#6) is masked out
by the IMS register (refer to the log below) the driver still receives
an interrupt as the "receive overrun" bit (#6) causes the "Other" -
bit #24 of the ICR register - bit to be set as documented below. The
driver handles the interrupt and clears the "Other" bit (#24) but
doesn't clear the "receive overrun" bit (#6) which leads to an
infinite loop. Apparently the Windows driver expects that the "receive
overrun" bit and other ones - documented below - to be cleared when
the "Other" bit (#24) is cleared.
So to sum that up:
1. Bit #6 of the ICR register is set by heavy traffic
2. As a results of setting bit #6, bit #24 is set
3. The driver receives an interrupt for bit 24 (it doesn't receieve an
interrupt for bit #6 as it is masked out by IMS)
4. The driver handles and clears the interrupt of bit #24
5. Bit #6 is still set.
6. 2 happens all over again
The Interrupt Cause Read - ICR register:
The ICR has the "Other" bit - bit #24 - that is set when one or more
of the following ICR register's bits are set:
LSC - bit #2, RXO - bit #6, MDAC - bit #9, SRPD - bit #16, ACK - bit
#17, MNG - bit #18
This bug can occur with any of these bits depending on the driver's
behaviour and the way it configures the device. However, trying to
reproduce it with any bit other than RX0 is challenging and came to
failure as the drivers don't implement most of these bits, trying to
reproduce it with LSC (Link Status Change - bit #2) bit didn't succeed
too as it seems that Windows handles this bit differently.
Log sample of the storm:
27563@1494850819.411877:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
27563@1494850819.411900:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.411915:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412380:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412395:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412436:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412441:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412998:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
* This bug behaviour wasn't observed with the Linux driver.
This commit solves:
https://bugzilla.redhat.com/show_bug.cgi?id=1447935
https://bugzilla.redhat.com/show_bug.cgi?id=1449490
Cc: qemu-stable@nongnu.org
Signed-off-by: Sameeh Jubran <sjubran@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
hw/net/e1000e_core.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 28c5be1506..81405640f0 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -2454,14 +2454,20 @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val)
static void
e1000e_set_icr(E1000ECore *core, int index, uint32_t val)
{
+ uint32_t icr = 0;
if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
(core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
trace_e1000e_irq_icr_process_iame();
e1000e_clear_ims_bits(core, core->mac[IAM]);
}
- trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val);
- core->mac[ICR] &= ~val;
+ icr = core->mac[ICR] & ~val;
+ /* Windows driver expects that the "receive overrun" bit and other
+ * ones to be cleared when the "Other" bit (#24) is cleared.
+ */
+ icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr;
+ trace_e1000e_irq_icr_write(val, core->mac[ICR], icr);
+ core->mac[ICR] = icr;
e1000e_update_interrupt_state(core);
}
--
2.11.0

View File

@ -0,0 +1,114 @@
From f7f03687246e62d8efed10ee5ce8c571fc3debc4 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 21 Apr 2017 11:16:27 +0200
Subject: [PATCH 09/13] vga: make display updates thread safe.
The vga code clears the dirty bits *after* reading the framebuffer
memory. So if the guest framebuffer updates hits the race window
between vga reading the framebuffer and vga clearing the dirty bits
vga will miss that update
Fix it by using the new memory_region_copy_and_clear_dirty()
memory_region_copy_get_dirty() functions. That way we clear the
dirty bitmap before reading the framebuffer. Any guest display
updates happening in parallel will be properly tracked in the
dirty bitmap then and the next display refresh will pick them up.
Problem triggers with mttcg only. Before mttcg was merged tcg
never ran in parallel to vga emulation. Using kvm will hide the
problem too, due to qemu operating on a userspace copy of the
kernel's dirty bitmap.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-5-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/display/vga.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 3991b88aac..b2516c8d21 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1465,7 +1465,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
DisplaySurface *surface = qemu_console_surface(s->con);
int y1, y, update, linesize, y_start, double_scan, mask, depth;
int width, height, shift_control, line_offset, bwidth, bits;
- ram_addr_t page0, page1, page_min, page_max;
+ ram_addr_t page0, page1;
+ DirtyBitmapSnapshot *snap = NULL;
int disp_width, multi_scan, multi_run;
uint8_t *d;
uint32_t v, addr1, addr;
@@ -1480,9 +1481,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
full_update |= update_basic_params(s);
- if (!full_update)
- vga_sync_dirty_bitmap(s);
-
s->get_resolution(s, &width, &height);
disp_width = width;
@@ -1625,11 +1623,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
addr1 = (s->start_addr * 4);
bwidth = (width * bits + 7) / 8;
y_start = -1;
- page_min = -1;
- page_max = 0;
d = surface_data(surface);
linesize = surface_stride(surface);
y1 = 0;
+
+ if (!full_update) {
+ vga_sync_dirty_bitmap(s);
+ snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
+ bwidth * height,
+ DIRTY_MEMORY_VGA);
+ }
+
for(y = 0; y < height; y++) {
addr = addr1;
if (!(s->cr[VGA_CRTC_MODE] & 1)) {
@@ -1644,17 +1648,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
update = full_update;
page0 = addr;
page1 = addr + bwidth - 1;
- update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
- DIRTY_MEMORY_VGA);
+ if (full_update) {
+ update = 1;
+ } else {
+ update = memory_region_snapshot_get_dirty(&s->vram, snap,
+ page0, page1 - page0);
+ }
/* explicit invalidation for the hardware cursor (cirrus only) */
update |= vga_scanline_invalidated(s, y);
if (update) {
if (y_start < 0)
y_start = y;
- if (page0 < page_min)
- page_min = page0;
- if (page1 > page_max)
- page_max = page1;
if (!(is_buffer_shared(surface))) {
vga_draw_line(s, d, s->vram_ptr + addr, width);
if (s->cursor_draw_line)
@@ -1687,13 +1691,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
dpy_gfx_update(s->con, 0, y_start,
disp_width, y - y_start);
}
- /* reset modified pages */
- if (page_max >= page_min) {
- memory_region_reset_dirty(&s->vram,
- page_min,
- page_max - page_min,
- DIRTY_MEMORY_VGA);
- }
+ g_free(snap);
memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
}
--
2.11.0

View File

@ -1,57 +0,0 @@
From 9c4164d74133304aaf7d77001e5ac8a22150df44 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 29 May 2017 14:08:32 +0200
Subject: [PATCH 10/23] mirror: Drop permissions on s->target on completion
This fixes an assertion failure that was triggered by qemu-iotests 129
on some CI host, while the same test case didn't seem to fail on other
hosts.
Essentially the problem is that the blk_unref(s->target) in
mirror_exit() doesn't necessarily mean that the BlockBackend goes away
immediately. It is possible that the job completion was triggered nested
in mirror_drain(), which looks like this:
BlockBackend *target = s->target;
blk_ref(target);
blk_drain(target);
blk_unref(target);
In this case, the write permissions for s->target are retained until
after blk_drain(), which makes removing mirror_top_bs fail for the
active commit case (can't have a writable backing file in the chain
without the filter driver).
Explicitly dropping the permissions first means that the additional
reference doesn't hurt and the job can complete successfully even if
called from the nested blk_drain().
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/mirror.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/block/mirror.c b/block/mirror.c
index 164438f422..779b753b8a 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -514,7 +514,12 @@ static void mirror_exit(BlockJob *job, void *opaque)
/* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
* inserting target_bs at s->to_replace, where we might not be able to get
- * these permissions. */
+ * these permissions.
+ *
+ * Note that blk_unref() alone doesn't necessarily drop permissions because
+ * we might be running nested inside mirror_drain(), which takes an extra
+ * reference, so use an explicit blk_set_perm() first. */
+ blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort);
blk_unref(s->target);
s->target = NULL;
--
2.11.0

View File

@ -0,0 +1,37 @@
From 616f285a074869fd79bc26509a0bd50e6e04e39d Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 9 May 2017 12:48:39 +0200
Subject: [PATCH 10/13] vga: fix display update region calculation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
vga display update mis-calculated the region for the dirty bitmap
snapshot in case the scanlines are padded. This can triggere an
assert in cpu_physical_memory_snapshot_get_dirty().
Fixes: fec5e8c92becad223df9d972770522f64aafdb72
Reported-by: Kevin Wolf <kwolf@redhat.com>
Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170509104839.19415-1-kraxel@redhat.com
---
hw/display/vga.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index b2516c8d21..dcc95f88e2 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1630,7 +1630,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (!full_update) {
vga_sync_dirty_bitmap(s);
snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
- bwidth * height,
+ line_offset * height,
DIRTY_MEMORY_VGA);
}
--
2.11.0

View File

@ -0,0 +1,47 @@
From c93a020a1c6a37398d124f063af23d6acb3eb5cb Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 1 Sep 2017 14:57:38 +0200
Subject: [PATCH 11/13] vga: fix display update region calculation (split
screen)
vga display update mis-calculated the region for the dirty bitmap
snapshot in case split screen mode is used. This can trigger an
assert in cpu_physical_memory_snapshot_get_dirty().
Impact: DoS for privileged guest users.
Fixes: CVE-2017-13673
Fixes: fec5e8c92becad223df9d972770522f64aafdb72
Cc: P J P <ppandit@redhat.com>
Reported-by: David Buchanan <d@vidbuchanan.co.uk>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170828123307.15392-1-kraxel@redhat.com
---
hw/display/vga.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index dcc95f88e2..533d8d7895 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1628,9 +1628,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
y1 = 0;
if (!full_update) {
+ ram_addr_t region_start = addr1;
+ ram_addr_t region_end = addr1 + line_offset * height;
vga_sync_dirty_bitmap(s);
- snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
- line_offset * height,
+ if (s->line_compare < height) {
+ /* split screen mode */
+ region_start = 0;
+ }
+ snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
+ region_end - region_start,
DIRTY_MEMORY_VGA);
}
--
2.11.0

View File

@ -1,34 +0,0 @@
From 1e709e6e073c7907676ea9263a1f92b1bd5fc9ac Mon Sep 17 00:00:00 2001
From: P J P <ppandit@redhat.com>
Date: Tue, 25 Apr 2017 18:36:23 +0530
Subject: [PATCH 11/23] vmw_pvscsi: check message ring page count at
initialisation
A guest could set the message ring page count to zero, resulting in
infinite loop. Add check to avoid it.
Reported-by: YY Z <bigbird475958471@gmail.com>
Signed-off-by: P J P <ppandit@redhat.com>
Message-Id: <20170425130623.3649-1-ppandit@redhat.com>
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/vmw_pvscsi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 75575461e2..4a106da856 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -202,7 +202,7 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
uint32_t len_log2;
uint32_t ring_size;
- if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
+ if (!ri->numPages || ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
return -1;
}
ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
--
2.11.0

View File

@ -1,38 +0,0 @@
From 74f9fd9420fadd64a42ee8de780dc6de61864ea8 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 28 Apr 2017 09:56:12 +0200
Subject: [PATCH 12/23] audio: release capture buffers
AUD_add_capture() allocates two buffers which are never released.
Add the missing calls to AUD_del_capture().
Impact: Allows vnc clients to exhaust host memory by repeatedly
starting and stopping audio capture.
Fixes: CVE-2017-8309
Cc: P J P <ppandit@redhat.com>
Cc: Huawei PSIRT <PSIRT@huawei.com>
Reported-by: "Jiangxin (hunter, SCC)" <jiangxin1@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 20170428075612.9997-1-kraxel@redhat.com
---
audio/audio.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/audio/audio.c b/audio/audio.c
index c8898d8422..beafed209b 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2028,6 +2028,8 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
sw = sw1;
}
QLIST_REMOVE (cap, entries);
+ g_free (cap->hw.mix_buf);
+ g_free (cap->buf);
g_free (cap);
}
return;
--
2.11.0

View File

@ -0,0 +1,497 @@
From 15c2b7e06a85dd78c7d45b3703639735eee09c01 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 1 Sep 2017 14:57:39 +0200
Subject: [PATCH 12/13] vga: stop passing pointers to vga_draw_line* functions
Instead pass around the address (aka offset into vga memory).
Add vga_read_* helper functions which apply vbe_size_mask to
the address, to make sure the address stays within the valid
range, similar to the cirrus blitter fixes (commits ffaf857778
and 026aeffcb4).
Impact: DoS for privileged guest users. qemu crashes with
a segfault, when hitting the guard page after vga memory
allocation, while reading vga memory for display updates.
Fixes: CVE-2017-13672
Cc: P J P <ppandit@redhat.com>
Reported-by: David Buchanan <d@vidbuchanan.co.uk>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170828122906.18993-1-kraxel@redhat.com
---
hw/display/vga-helpers.h | 202 ++++++++++++++++++++++++++---------------------
hw/display/vga.c | 5 +-
hw/display/vga_int.h | 1 +
3 files changed, 114 insertions(+), 94 deletions(-)
diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h
index 94f6de2046..5a752b3f9e 100644
--- a/hw/display/vga-helpers.h
+++ b/hw/display/vga-helpers.h
@@ -95,20 +95,46 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
} while (--h);
}
+static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr)
+{
+ return vga->vram_ptr[addr & vga->vbe_size_mask];
+}
+
+static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr)
+{
+ uint32_t offset = addr & vga->vbe_size_mask & ~1;
+ uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
+ return lduw_le_p(ptr);
+}
+
+static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr)
+{
+ uint32_t offset = addr & vga->vbe_size_mask & ~1;
+ uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
+ return lduw_be_p(ptr);
+}
+
+static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr)
+{
+ uint32_t offset = addr & vga->vbe_size_mask & ~3;
+ uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset);
+ return ldl_le_p(ptr);
+}
+
/*
* 4 color mode
*/
-static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
uint32_t plane_mask, *palette, data, v;
int x;
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ palette = vga->last_palette;
+ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
+ data = vga_read_dword_le(vga, addr);
data &= plane_mask;
v = expand2[GET_PLANE(data, 0)];
v |= expand2[GET_PLANE(data, 2)] << 2;
@@ -124,7 +150,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
d += 32;
- s += 4;
+ addr += 4;
}
}
@@ -134,17 +160,17 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
/*
* 4 color mode, dup2 horizontal
*/
-static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
uint32_t plane_mask, *palette, data, v;
int x;
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ palette = vga->last_palette;
+ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
+ data = vga_read_dword_le(vga, addr);
data &= plane_mask;
v = expand2[GET_PLANE(data, 0)];
v |= expand2[GET_PLANE(data, 2)] << 2;
@@ -160,24 +186,24 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
d += 64;
- s += 4;
+ addr += 4;
}
}
/*
* 16 color mode
*/
-static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
uint32_t plane_mask, data, v, *palette;
int x;
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ palette = vga->last_palette;
+ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
+ data = vga_read_dword_le(vga, addr);
data &= plane_mask;
v = expand4[GET_PLANE(data, 0)];
v |= expand4[GET_PLANE(data, 1)] << 1;
@@ -192,24 +218,24 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
d += 32;
- s += 4;
+ addr += 4;
}
}
/*
* 16 color mode, dup2 horizontal
*/
-static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
uint32_t plane_mask, data, v, *palette;
int x;
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ palette = vga->last_palette;
+ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
width >>= 3;
for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
+ data = vga_read_dword_le(vga, addr);
data &= plane_mask;
v = expand4[GET_PLANE(data, 0)];
v |= expand4[GET_PLANE(data, 1)] << 1;
@@ -224,7 +250,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
d += 64;
- s += 4;
+ addr += 4;
}
}
@@ -233,21 +259,21 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
*
* XXX: add plane_mask support (never used in standard VGA modes)
*/
-static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
uint32_t *palette;
int x;
- palette = s1->last_palette;
+ palette = vga->last_palette;
width >>= 3;
for(x = 0; x < width; x++) {
- PUT_PIXEL2(d, 0, palette[s[0]]);
- PUT_PIXEL2(d, 1, palette[s[1]]);
- PUT_PIXEL2(d, 2, palette[s[2]]);
- PUT_PIXEL2(d, 3, palette[s[3]]);
+ PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
+ PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
+ PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
+ PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
d += 32;
- s += 4;
+ addr += 4;
}
}
@@ -256,63 +282,63 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
*
* XXX: add plane_mask support (never used in standard VGA modes)
*/
-static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
uint32_t *palette;
int x;
- palette = s1->last_palette;
+ palette = vga->last_palette;
width >>= 3;
for(x = 0; x < width; x++) {
- ((uint32_t *)d)[0] = palette[s[0]];
- ((uint32_t *)d)[1] = palette[s[1]];
- ((uint32_t *)d)[2] = palette[s[2]];
- ((uint32_t *)d)[3] = palette[s[3]];
- ((uint32_t *)d)[4] = palette[s[4]];
- ((uint32_t *)d)[5] = palette[s[5]];
- ((uint32_t *)d)[6] = palette[s[6]];
- ((uint32_t *)d)[7] = palette[s[7]];
+ ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
+ ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
+ ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
+ ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
+ ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
+ ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
+ ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
+ ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
d += 32;
- s += 8;
+ addr += 8;
}
}
/*
* 15 bit color
*/
-static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
int w;
uint32_t v, r, g, b;
w = width;
do {
- v = lduw_le_p((void *)s);
+ v = vga_read_word_le(vga, addr);
r = (v >> 7) & 0xf8;
g = (v >> 2) & 0xf8;
b = (v << 3) & 0xf8;
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
+ addr += 2;
d += 4;
} while (--w != 0);
}
-static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
int w;
uint32_t v, r, g, b;
w = width;
do {
- v = lduw_be_p((void *)s);
+ v = vga_read_word_be(vga, addr);
r = (v >> 7) & 0xf8;
g = (v >> 2) & 0xf8;
b = (v << 3) & 0xf8;
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
+ addr += 2;
d += 4;
} while (--w != 0);
}
@@ -320,38 +346,38 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
/*
* 16 bit color
*/
-static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
int w;
uint32_t v, r, g, b;
w = width;
do {
- v = lduw_le_p((void *)s);
+ v = vga_read_word_le(vga, addr);
r = (v >> 8) & 0xf8;
g = (v >> 3) & 0xfc;
b = (v << 3) & 0xf8;
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
+ addr += 2;
d += 4;
} while (--w != 0);
}
-static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
int w;
uint32_t v, r, g, b;
w = width;
do {
- v = lduw_be_p((void *)s);
+ v = vga_read_word_be(vga, addr);
r = (v >> 8) & 0xf8;
g = (v >> 3) & 0xfc;
b = (v << 3) & 0xf8;
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
+ addr += 2;
d += 4;
} while (--w != 0);
}
@@ -359,36 +385,36 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
/*
* 24 bit color
*/
-static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
int w;
uint32_t r, g, b;
w = width;
do {
- b = s[0];
- g = s[1];
- r = s[2];
+ b = vga_read_byte(vga, addr + 0);
+ g = vga_read_byte(vga, addr + 1);
+ r = vga_read_byte(vga, addr + 2);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 3;
+ addr += 3;
d += 4;
} while (--w != 0);
}
-static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
int w;
uint32_t r, g, b;
w = width;
do {
- r = s[0];
- g = s[1];
- b = s[2];
+ r = vga_read_byte(vga, addr + 0);
+ g = vga_read_byte(vga, addr + 1);
+ b = vga_read_byte(vga, addr + 2);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 3;
+ addr += 3;
d += 4;
} while (--w != 0);
}
@@ -396,44 +422,36 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
/*
* 32 bit color
*/
-static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
-#ifndef HOST_WORDS_BIGENDIAN
- memcpy(d, s, width * 4);
-#else
int w;
uint32_t r, g, b;
w = width;
do {
- b = s[0];
- g = s[1];
- r = s[2];
+ b = vga_read_byte(vga, addr + 0);
+ g = vga_read_byte(vga, addr + 1);
+ r = vga_read_byte(vga, addr + 2);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 4;
+ addr += 4;
d += 4;
} while (--w != 0);
-#endif
}
-static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
+static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
+ uint32_t addr, int width)
{
-#ifdef HOST_WORDS_BIGENDIAN
- memcpy(d, s, width * 4);
-#else
int w;
uint32_t r, g, b;
w = width;
do {
- r = s[1];
- g = s[2];
- b = s[3];
+ r = vga_read_byte(vga, addr + 1);
+ g = vga_read_byte(vga, addr + 2);
+ b = vga_read_byte(vga, addr + 3);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 4;
+ addr += 4;
d += 4;
} while (--w != 0);
-#endif
}
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 533d8d7895..13e4a5d55d 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1005,7 +1005,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
}
typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width);
+ uint32_t srcaddr, int width);
#include "vga-helpers.h"
@@ -1666,7 +1666,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (y_start < 0)
y_start = y;
if (!(is_buffer_shared(surface))) {
- vga_draw_line(s, d, s->vram_ptr + addr, width);
+ vga_draw_line(s, d, addr, width);
if (s->cursor_draw_line)
s->cursor_draw_line(s, d, y);
}
@@ -2170,6 +2170,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
if (!s->vbe_size) {
s->vbe_size = s->vram_size;
}
+ s->vbe_size_mask = s->vbe_size - 1;
s->is_vbe_vmstate = 1;
memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size,
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index dd6c958da3..ad34a1f048 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -94,6 +94,7 @@ typedef struct VGACommonState {
uint32_t vram_size;
uint32_t vram_size_mb; /* property */
uint32_t vbe_size;
+ uint32_t vbe_size_mask;
uint32_t latch;
bool has_chain4_alias;
MemoryRegion chain4_alias;
--
2.11.0

View File

@ -1,90 +0,0 @@
From e96b198df364a2918896c41a9759b38aaebcf211 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 28 Apr 2017 10:42:37 +0200
Subject: [PATCH 13/23] input: limit kbd queue depth
Apply a limit to the number of items we accept into the keyboard queue.
Impact: Without this limit vnc clients can exhaust host memory by
sending keyboard events faster than qemu feeds them to the guest.
Fixes: CVE-2017-8379
Cc: P J P <ppandit@redhat.com>
Cc: Huawei PSIRT <PSIRT@huawei.com>
Reported-by: jiangxin1@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170428084237.23960-1-kraxel@redhat.com
---
ui/input.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/ui/input.c b/ui/input.c
index ed88cda6d6..fb1f404095 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -41,6 +41,8 @@ static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue =
QTAILQ_HEAD_INITIALIZER(kbd_queue);
static QEMUTimer *kbd_timer;
static uint32_t kbd_default_delay_ms = 10;
+static uint32_t queue_count;
+static uint32_t queue_limit = 1024;
QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
QemuInputHandler *handler)
@@ -268,6 +270,7 @@ static void qemu_input_queue_process(void *opaque)
break;
}
QTAILQ_REMOVE(queue, item, node);
+ queue_count--;
g_free(item);
}
}
@@ -282,6 +285,7 @@ static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
item->delay_ms = delay_ms;
item->timer = timer;
QTAILQ_INSERT_TAIL(queue, item, node);
+ queue_count++;
if (start_timer) {
timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)
@@ -298,6 +302,7 @@ static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
item->src = src;
item->evt = evt;
QTAILQ_INSERT_TAIL(queue, item, node);
+ queue_count++;
}
static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
@@ -306,6 +311,7 @@ static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
item->type = QEMU_INPUT_QUEUE_SYNC;
QTAILQ_INSERT_TAIL(queue, item, node);
+ queue_count++;
}
void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt)
@@ -381,7 +387,7 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
qemu_input_event_send(src, evt);
qemu_input_event_sync();
qapi_free_InputEvent(evt);
- } else {
+ } else if (queue_count < queue_limit) {
qemu_input_queue_event(&kbd_queue, src, evt);
qemu_input_queue_sync(&kbd_queue);
}
@@ -409,8 +415,10 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms)
kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process,
&kbd_queue);
}
- qemu_input_queue_delay(&kbd_queue, kbd_timer,
- delay_ms ? delay_ms : kbd_default_delay_ms);
+ if (queue_count < queue_limit) {
+ qemu_input_queue_delay(&kbd_queue, kbd_timer,
+ delay_ms ? delay_ms : kbd_default_delay_ms);
+ }
}
InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
--
2.11.0

View File

@ -0,0 +1,61 @@
From fff4299fb7be857e93ff5c6ea0f871c62d159c1d Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Thu, 7 Sep 2017 12:02:56 +0530
Subject: [PATCH 13/13] multiboot: validate multiboot header address values
While loading kernel via multiboot-v1 image, (flags & 0x00010000)
indicates that multiboot header contains valid addresses to load
the kernel image. These addresses are used to compute kernel
size and kernel text offset in the OS image. Validate these
address values to avoid an OOB access issue.
This is CVE-2017-14167.
Reported-by: Thomas Garnier <thgarnie@google.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
---
hw/i386/multiboot.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index f13e23139b..22688d376d 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -221,15 +221,34 @@ int load_multiboot(FWCfgState *fw_cfg,
uint32_t mh_header_addr = ldl_p(header+i+12);
uint32_t mh_load_end_addr = ldl_p(header+i+20);
uint32_t mh_bss_end_addr = ldl_p(header+i+24);
+
mh_load_addr = ldl_p(header+i+16);
+ if (mh_header_addr < mh_load_addr) {
+ fprintf(stderr, "invalid mh_load_addr address\n");
+ exit(1);
+ }
+
uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
uint32_t mb_load_size = 0;
mh_entry_addr = ldl_p(header+i+28);
if (mh_load_end_addr) {
+ if (mh_bss_end_addr < mh_load_addr) {
+ fprintf(stderr, "invalid mh_bss_end_addr address\n");
+ exit(1);
+ }
mb_kernel_size = mh_bss_end_addr - mh_load_addr;
+
+ if (mh_load_end_addr < mh_load_addr) {
+ fprintf(stderr, "invalid mh_load_end_addr address\n");
+ exit(1);
+ }
mb_load_size = mh_load_end_addr - mh_load_addr;
} else {
+ if (kernel_file_size < mb_kernel_text_offset) {
+ fprintf(stderr, "invalid kernel_file_size\n");
+ exit(1);
+ }
mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
mb_load_size = mb_kernel_size;
}
--
2.11.0

View File

@ -1,45 +0,0 @@
From c442fb4a11d8dc527c90bf90a1fd1b15646f4c57 Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Mon, 24 Apr 2017 17:36:34 +0530
Subject: [PATCH 14/23] scsi: avoid an off-by-one error in megasas_mmio_write
While reading magic sequence(MFI_SEQ) in megasas_mmio_write,
an off-by-one error could occur as 's->adp_reset' index is not
reset after reading the last sequence.
Reported-by: YY Z <bigbird475958471@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <20170424120634.12268-1-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/megasas.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 84b8caf901..804122ab05 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2138,15 +2138,15 @@ static void megasas_mmio_write(void *opaque, hwaddr addr,
case MFI_SEQ:
trace_megasas_mmio_writel("MFI_SEQ", val);
/* Magic sequence to start ADP reset */
- if (adp_reset_seq[s->adp_reset] == val) {
- s->adp_reset++;
+ if (adp_reset_seq[s->adp_reset++] == val) {
+ if (s->adp_reset == 6) {
+ s->adp_reset = 0;
+ s->diag = MFI_DIAG_WRITE_ENABLE;
+ }
} else {
s->adp_reset = 0;
s->diag = 0;
}
- if (s->adp_reset == 6) {
- s->diag = MFI_DIAG_WRITE_ENABLE;
- }
break;
case MFI_DIAG:
trace_megasas_mmio_writel("MFI_DIAG", val);
--
2.11.0

View File

@ -1,175 +0,0 @@
From 209fb3054000bd3a45da63e3758b9c220fba0a25 Mon Sep 17 00:00:00 2001
From: Greg Kurz <groug@kaod.org>
Date: Fri, 5 May 2017 14:48:08 +0200
Subject: [PATCH 15/23] 9pfs: local: forbid client access to metadata
(CVE-2017-7493)
When using the mapped-file security mode, we shouldn't let the client mess
with the metadata. The current code already tries to hide the metadata dir
from the client by skipping it in local_readdir(). But the client can still
access or modify it through several other operations. This can be used to
escalate privileges in the guest.
Affected backend operations are:
- local_mknod()
- local_mkdir()
- local_open2()
- local_symlink()
- local_link()
- local_unlinkat()
- local_renameat()
- local_rename()
- local_name_to_path()
Other operations are safe because they are only passed a fid path, which
is computed internally in local_name_to_path().
This patch converts all the functions listed above to fail and return
EINVAL when being passed the name of the metadata dir. This may look
like a poor choice for errno, but there's no such thing as an illegal
path name on Linux and I could not think of anything better.
This fixes CVE-2017-7493.
Reported-by: Leo Gaspard <leo@gaspard.io>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
hw/9pfs/9p-local.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 56 insertions(+), 2 deletions(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 7a0c383e7e..226234d386 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -452,6 +452,11 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
return telldir(fs->dir.stream);
}
+static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name)
+{
+ return !strcmp(name, VIRTFS_META_DIR);
+}
+
static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
{
struct dirent *entry;
@@ -465,8 +470,8 @@ again:
if (ctx->export_flags & V9FS_SM_MAPPED) {
entry->d_type = DT_UNKNOWN;
} else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
- if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
- /* skp the meta data directory */
+ if (local_is_mapped_file_metadata(ctx, entry->d_name)) {
+ /* skip the meta data directory */
goto again;
}
entry->d_type = DT_UNKNOWN;
@@ -559,6 +564,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -605,6 +616,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -694,6 +711,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
/*
* Mark all the open to not follow symlinks
*/
@@ -752,6 +775,12 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -826,6 +855,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
int ret = -1;
int odirfd, ndirfd;
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
odirfd = local_opendir_nofollow(ctx, odirpath);
if (odirfd == -1) {
goto out;
@@ -1092,6 +1127,12 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
const char *name, V9fsPath *target)
{
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (dir_path) {
v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
} else if (strcmp(name, "/")) {
@@ -1112,6 +1153,13 @@ static int local_renameat(FsContext *ctx, V9fsPath *olddir,
int ret;
int odirfd, ndirfd;
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ (local_is_mapped_file_metadata(ctx, old_name) ||
+ local_is_mapped_file_metadata(ctx, new_name))) {
+ errno = EINVAL;
+ return -1;
+ }
+
odirfd = local_opendir_nofollow(ctx, olddir->data);
if (odirfd == -1) {
return -1;
@@ -1202,6 +1250,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
int ret;
int dirfd;
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(ctx, dir->data);
if (dirfd == -1) {
return -1;
--
2.11.0

View File

@ -1,115 +0,0 @@
From 95a82526f2bfd3e9f0ac65a1f2ed505b2429d9de Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 1 Jun 2017 17:18:23 +0200
Subject: [PATCH 16/23] megasas: do not read DCMD opcode more than once from
frame
Avoid TOC-TOU bugs by storing the DCMD opcode in the MegasasCmd
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/megasas.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 804122ab05..887958481b 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -63,6 +63,7 @@ typedef struct MegasasCmd {
hwaddr pa;
hwaddr pa_size;
+ uint32_t dcmd_opcode;
union mfi_frame *frame;
SCSIRequest *req;
QEMUSGList qsg;
@@ -511,6 +512,7 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
cmd->context &= (uint64_t)0xFFFFFFFF;
}
cmd->count = count;
+ cmd->dcmd_opcode = -1;
s->busy++;
if (s->consumer_pa) {
@@ -1559,22 +1561,21 @@ static const struct dcmd_cmd_tbl_t {
static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
{
- int opcode;
int retval = 0;
size_t len;
const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl;
- opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
- trace_megasas_handle_dcmd(cmd->index, opcode);
+ cmd->dcmd_opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+ trace_megasas_handle_dcmd(cmd->index, cmd->dcmd_opcode);
if (megasas_map_dcmd(s, cmd) < 0) {
return MFI_STAT_MEMORY_NOT_AVAILABLE;
}
- while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) {
+ while (cmdptr->opcode != -1 && cmdptr->opcode != cmd->dcmd_opcode) {
cmdptr++;
}
len = cmd->iov_size;
if (cmdptr->opcode == -1) {
- trace_megasas_dcmd_unhandled(cmd->index, opcode, len);
+ trace_megasas_dcmd_unhandled(cmd->index, cmd->dcmd_opcode, len);
retval = megasas_dcmd_dummy(s, cmd);
} else {
trace_megasas_dcmd_enter(cmd->index, cmdptr->desc, len);
@@ -1589,13 +1590,11 @@ static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
static int megasas_finish_internal_dcmd(MegasasCmd *cmd,
SCSIRequest *req)
{
- int opcode;
int retval = MFI_STAT_OK;
int lun = req->lun;
- opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
- trace_megasas_dcmd_internal_finish(cmd->index, opcode, lun);
- switch (opcode) {
+ trace_megasas_dcmd_internal_finish(cmd->index, cmd->dcmd_opcode, lun);
+ switch (cmd->dcmd_opcode) {
case MFI_DCMD_PD_GET_INFO:
retval = megasas_pd_get_info_submit(req->dev, lun, cmd);
break;
@@ -1603,7 +1602,7 @@ static int megasas_finish_internal_dcmd(MegasasCmd *cmd,
retval = megasas_ld_get_info_submit(req->dev, lun, cmd);
break;
default:
- trace_megasas_dcmd_internal_invalid(cmd->index, opcode);
+ trace_megasas_dcmd_internal_invalid(cmd->index, cmd->dcmd_opcode);
retval = MFI_STAT_INVALID_DCMD;
break;
}
@@ -1824,7 +1823,6 @@ static void megasas_xfer_complete(SCSIRequest *req, uint32_t len)
{
MegasasCmd *cmd = req->hba_private;
uint8_t *buf;
- uint32_t opcode;
trace_megasas_io_complete(cmd->index, len);
@@ -1834,8 +1832,7 @@ static void megasas_xfer_complete(SCSIRequest *req, uint32_t len)
}
buf = scsi_req_get_buf(req);
- opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
- if (opcode == MFI_DCMD_PD_GET_INFO && cmd->iov_buf) {
+ if (cmd->dcmd_opcode == MFI_DCMD_PD_GET_INFO && cmd->iov_buf) {
struct mfi_pd_info *info = cmd->iov_buf;
if (info->inquiry_data[0] == 0x7f) {
@@ -1846,7 +1843,7 @@ static void megasas_xfer_complete(SCSIRequest *req, uint32_t len)
memcpy(info->vpd_page83, buf, len);
}
scsi_req_continue(req);
- } else if (opcode == MFI_DCMD_LD_GET_INFO) {
+ } else if (cmd->dcmd_opcode == MFI_DCMD_LD_GET_INFO) {
struct mfi_ld_info *info = cmd->iov_buf;
if (cmd->iov_buf) {
--
2.11.0

View File

@ -1,81 +0,0 @@
From 4dbc47f9d71b8a17b174ffed314988aa99dc4775 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 26 May 2017 22:04:21 -0500
Subject: [PATCH 18/23] nbd: Fully initialize client in case of failed
negotiation
If a non-NBD client connects to qemu-nbd, we would end up with
a SIGSEGV in nbd_client_put() because we were trying to
unregister the client's association to the export, even though
we skipped inserting the client into that list. Easy trigger
in two terminals:
$ qemu-nbd -p 30001 --format=raw file
$ nmap 127.0.0.1 -p 30001
nmap claims that it thinks it connected to a pago-services1
server (which probably means nmap could be updated to learn the
NBD protocol and give a more accurate diagnosis of the open
port - but that's not our problem), then terminates immediately,
so our call to nbd_negotiate() fails. The fix is to reorder
nbd_co_client_start() to ensure that all initialization occurs
before we ever try talking to a client in nbd_negotiate(), so
that the teardown sequence on negotiation failure doesn't fault
while dereferencing a half-initialized object.
While debugging this, I also noticed that nbd_update_server_watch()
called by nbd_client_closed() was still adding a channel to accept
the next client, even when the state was no longer RUNNING. That
is fixed by making nbd_can_accept() pay attention to the current
state.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170527030421.28366-1-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
nbd/server.c | 8 +++-----
qemu-nbd.c | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/nbd/server.c b/nbd/server.c
index 924a1fe2db..edfda84d43 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1376,16 +1376,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
if (exp) {
nbd_export_get(exp);
+ QTAILQ_INSERT_TAIL(&exp->clients, client, next);
}
+ qemu_co_mutex_init(&client->send_lock);
+
if (nbd_negotiate(data)) {
client_close(client);
goto out;
}
- qemu_co_mutex_init(&client->send_lock);
-
- if (exp) {
- QTAILQ_INSERT_TAIL(&exp->clients, client, next);
- }
nbd_client_receive_next_request(client);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index e080fb7c75..b44764eb87 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -324,7 +324,7 @@ out:
static int nbd_can_accept(void)
{
- return nb_fds < shared;
+ return state == RUNNING && nb_fds < shared;
}
static void nbd_export_closed(NBDExport *exp)
--
2.11.0

View File

@ -1,197 +0,0 @@
From 97c7e46a9f8ae03e24df1d18d3b5e9df420f39ce Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 8 Jun 2017 17:26:17 -0500
Subject: [PATCH 19/23] nbd: Fix regression on resiliency to port scan
Back in qemu 2.5, qemu-nbd was immune to port probes (a transient
server would not quit, regardless of how many probe connections
came and went, until a connection actually negotiated). But we
broke that in commit ee7d7aa when removing the return value to
nbd_client_new(), although that patch also introduced a bug causing
an assertion failure on a client that fails negotiation. We then
made it worse during refactoring in commit 1a6245a (a segfault
before we could even assert); the (masked) assertion was cleaned
up in d3780c2 (still in 2.6), and just recently we finally fixed
the segfault ("nbd: Fully intialize client in case of failed
negotiation"). But that still means that ever since we added
TLS support to qemu-nbd, we have been vulnerable to an ill-timed
port-scan being able to cause a denial of service by taking down
qemu-nbd before a real client has a chance to connect.
Since negotiation is now handled asynchronously via coroutines,
we no longer have a synchronous point of return by re-adding a
return value to nbd_client_new(). So this patch instead wires
things up to pass the negotiation status through the close_fn
callback function.
Simple test across two terminals:
$ qemu-nbd -f raw -p 30001 file
$ nmap 127.0.0.1 -p 30001 && \
qemu-io -c 'r 0 512' -f raw nbd://localhost:30001
Note that this patch does not change what constitutes successful
negotiation (thus, a client must enter transmission phase before
that client can be considered as a reason to terminate the server
when the connection ends). Perhaps we may want to tweak things
in a later patch to also treat a client that uses NBD_OPT_ABORT
as being a 'successful' negotiation (the client correctly talked
the NBD protocol, and informed us it was not going to use our
export after all), but that's a discussion for another day.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170608222617.20376-1-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
blockdev-nbd.c | 6 +++++-
include/block/nbd.h | 2 +-
nbd/server.c | 24 +++++++++++++++---------
qemu-nbd.c | 4 ++--
4 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 8a11807df3..8d7284ac56 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -27,6 +27,10 @@ typedef struct NBDServerData {
static NBDServerData *nbd_server;
+static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
+{
+ nbd_client_put(client);
+}
static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
gpointer opaque)
@@ -46,7 +50,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
nbd_client_new(NULL, cioc,
nbd_server->tlscreds, NULL,
- nbd_client_put);
+ nbd_blockdev_client_closed);
object_unref(OBJECT(cioc));
return TRUE;
}
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 3e373f0498..b69c30d063 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -160,7 +160,7 @@ void nbd_client_new(NBDExport *exp,
QIOChannelSocket *sioc,
QCryptoTLSCreds *tlscreds,
const char *tlsaclname,
- void (*close)(NBDClient *));
+ void (*close_fn)(NBDClient *, bool));
void nbd_client_get(NBDClient *client);
void nbd_client_put(NBDClient *client);
diff --git a/nbd/server.c b/nbd/server.c
index edfda84d43..a98bb21a0a 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -81,7 +81,7 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
struct NBDClient {
int refcount;
- void (*close)(NBDClient *client);
+ void (*close_fn)(NBDClient *client, bool negotiated);
bool no_zeroes;
NBDExport *exp;
@@ -796,7 +796,7 @@ void nbd_client_put(NBDClient *client)
}
}
-static void client_close(NBDClient *client)
+static void client_close(NBDClient *client, bool negotiated)
{
if (client->closing) {
return;
@@ -811,8 +811,8 @@ static void client_close(NBDClient *client)
NULL);
/* Also tell the client, so that they release their reference. */
- if (client->close) {
- client->close(client);
+ if (client->close_fn) {
+ client->close_fn(client, negotiated);
}
}
@@ -993,7 +993,7 @@ void nbd_export_close(NBDExport *exp)
nbd_export_get(exp);
QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
- client_close(client);
+ client_close(client, true);
}
nbd_export_set_name(exp, NULL);
nbd_export_set_description(exp, NULL);
@@ -1355,7 +1355,7 @@ done:
out:
nbd_request_put(req);
- client_close(client);
+ client_close(client, true);
nbd_client_put(client);
}
@@ -1381,7 +1381,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
qemu_co_mutex_init(&client->send_lock);
if (nbd_negotiate(data)) {
- client_close(client);
+ client_close(client, false);
goto out;
}
@@ -1391,11 +1391,17 @@ out:
g_free(data);
}
+/*
+ * Create a new client listener on the given export @exp, using the
+ * given channel @sioc. Begin servicing it in a coroutine. When the
+ * connection closes, call @close_fn with an indication of whether the
+ * client completed negotiation.
+ */
void nbd_client_new(NBDExport *exp,
QIOChannelSocket *sioc,
QCryptoTLSCreds *tlscreds,
const char *tlsaclname,
- void (*close_fn)(NBDClient *))
+ void (*close_fn)(NBDClient *, bool))
{
NBDClient *client;
NBDClientNewData *data = g_new(NBDClientNewData, 1);
@@ -1412,7 +1418,7 @@ void nbd_client_new(NBDExport *exp,
object_ref(OBJECT(client->sioc));
client->ioc = QIO_CHANNEL(sioc);
object_ref(OBJECT(client->ioc));
- client->close = close_fn;
+ client->close_fn = close_fn;
data->client = client;
data->co = qemu_coroutine_create(nbd_co_client_start, data);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index b44764eb87..483dd77a77 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -335,10 +335,10 @@ static void nbd_export_closed(NBDExport *exp)
static void nbd_update_server_watch(void);
-static void nbd_client_closed(NBDClient *client)
+static void nbd_client_closed(NBDClient *client, bool negotiated)
{
nb_fds--;
- if (nb_fds == 0 && !persistent && state == RUNNING) {
+ if (negotiated && nb_fds == 0 && !persistent && state == RUNNING) {
state = TERMINATE;
}
nbd_update_server_watch();
--
2.11.0

View File

@ -1,47 +0,0 @@
From 36d48727155c4a440ee23c703778533f87002964 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Sun, 11 Jun 2017 14:37:14 +0200
Subject: [PATCH 20/23] qemu-nbd: Ignore SIGPIPE
qemu proper has done so for 13 years
(8a7ddc38a60648257dc0645ab4a05b33d6040063), qemu-img and qemu-io have
done so for four years (526eda14a68d5b3596be715505289b541288ef2a).
Ignoring this signal is especially important in qemu-nbd because
otherwise a client can easily take down the qemu-nbd server by dropping
the connection when the server wants to send something, for example:
$ qemu-nbd -x foo -f raw -t null-co:// &
[1] 12726
$ qemu-io -c quit nbd://localhost/bar
can't open device nbd://localhost/bar: No export with name 'bar' available
[1] + 12726 broken pipe qemu-nbd -x foo -f raw -t null-co://
In this case, the client sends an NBD_OPT_ABORT and closes the
connection (because it is not required to wait for a reply), but the
server replies with an NBD_REP_ACK (because it is required to reply).
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20170611123714.31292-1-mreitz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-nbd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 483dd77a77..5deb37e03e 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -581,6 +581,10 @@ int main(int argc, char **argv)
sa_sigterm.sa_handler = termsig_handler;
sigaction(SIGTERM, &sa_sigterm, NULL);
+#ifdef CONFIG_POSIX
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
module_call_init(MODULE_INIT_TRACE);
qcrypto_init(&error_fatal);
--
2.11.0

View File

@ -1,50 +0,0 @@
From ce2b5a53421794394fc81d155837b1c8ac79ea15 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 9 May 2017 13:01:28 +0200
Subject: [PATCH 21/23] usb-redir: fix stack overflow in usbredir_log_data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Don't reinvent a broken wheel, just use the hexdump function we have.
Impact: low, broken code doesn't run unless you have debug logging
enabled.
Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170509110128.27261-1-kraxel@redhat.com
---
hw/usb/redirect.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 0efe62f725..eb70dc7218 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -229,21 +229,10 @@ static void usbredir_log(void *priv, int level, const char *msg)
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
const uint8_t *data, int len)
{
- int i, j, n;
-
if (dev->debug < usbredirparser_debug_data) {
return;
}
-
- for (i = 0; i < len; i += j) {
- char buf[128];
-
- n = sprintf(buf, "%s", desc);
- for (j = 0; j < 8 && i + j < len; j++) {
- n += sprintf(buf + n, " %02X", data[i + j]);
- }
- error_report("%s", buf);
- }
+ qemu_hexdump((char *)data, stderr, desc, len);
}
/*
--
2.11.0

View File

@ -1,43 +0,0 @@
From d587bf95f1099fd253e6a7b768bf73d4e25de07c Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 12 Jul 2017 18:08:40 +0530
Subject: [PATCH 22/23] exec: use qemu_ram_ptr_length to access guest ram
When accessing guest's ram block during DMA operation, use
'qemu_ram_ptr_length' to get ram block pointer. It ensures
that DMA operation of given length is possible; And avoids
any OOB memory access situations.
Reported-by: Alex <broscutamaker@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <20170712123840.29328-1-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
exec.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/exec.c b/exec.c
index c97ef4a8da..72d636a4fb 100644
--- a/exec.c
+++ b/exec.c
@@ -2765,7 +2765,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
- ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(mr, addr1, l);
}
@@ -2856,7 +2856,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
- ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
memcpy(buf, ptr, l);
}
--
2.11.0

View File

@ -1,4 +1,4 @@
From 926ac2ae6be8a7971e4c24d45345981e3a62d560 Mon Sep 17 00:00:00 2001
From 5f03cca26a4ba9c08d6f6e19b97b6c6c1f0f236a Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:15:49 +0100
Subject: [PATCH 01/28] fr-ca keymap corrections

View File

@ -1,4 +1,4 @@
From 65a038b874c5770f48077cf77742ac10bb083922 Mon Sep 17 00:00:00 2001
From 499c1880a00cd772bf85167cb2bb3f5ff4eb4d33 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:16:49 +0100
Subject: [PATCH 02/28] Adjust network script path to /etc/kvm/

View File

@ -1,4 +1,4 @@
From 034ee9d08002e8e57c4d09e9a9750aad547f65f1 Mon Sep 17 00:00:00 2001
From 99ae84628c46f29cfce39c753801f91efe102a8c Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:18:46 +0100
Subject: [PATCH 03/28] qemu-img: return success on info without snapshots
@ -8,7 +8,7 @@ Subject: [PATCH 03/28] qemu-img: return success on info without snapshots
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/qemu-img.c b/qemu-img.c
index b220cf71d7..4f7f458dd2 100644
index e4a2686f56..c7804d63ee 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2596,7 +2596,8 @@ static int img_info(int argc, char **argv)

View File

@ -1,4 +1,4 @@
From 0203288ce982ea135ff82cf4ea6a7868ef053470 Mon Sep 17 00:00:00 2001
From f1e0cc0d0f287a8072a0f69fe1a10a0cf1cd6b49 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:27:05 +0100
Subject: [PATCH 04/28] use kvm by default

View File

@ -1,4 +1,4 @@
From d91355991605106e86f246e0e9091ffc1275b52f Mon Sep 17 00:00:00 2001
From 6b88624be0e6018ad674abdb01d6cb04fabc703e Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:27:49 +0100
Subject: [PATCH 05/28] virtio-balloon: fix query

View File

@ -1,4 +1,4 @@
From 99d1d87c126c630afed3885a26b5c4c6ca6e050b Mon Sep 17 00:00:00 2001
From f321f239eb7d28861a16d6f941bd3b756621147c Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:30:21 +0100
Subject: [PATCH 06/28] set the CPU model to kvm64/32 instead of qemu64/32
@ -8,7 +8,7 @@ Subject: [PATCH 06/28] set the CPU model to kvm64/32 instead of qemu64/32
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d24388e05f..81e91a4897 100644
index 610050eb4f..e96901435a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1151,9 +1151,9 @@ void pc_cpus_init(PCMachineState *pcms)

View File

@ -1,4 +1,4 @@
From a761848c2ded6eb644c0e0e5d9184f54db59828a Mon Sep 17 00:00:00 2001
From ba17137d9645c421717b20aef09fed3945dc6d14 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:31:18 +0100
Subject: [PATCH 07/28] qapi: modify query machines
@ -32,7 +32,7 @@ index f38b85bf6a..51e150c6c1 100644
##
diff --git a/vl.c b/vl.c
index 0b4ed5241c..868c4893df 100644
index b719cc432e..46de1b9087 100644
--- a/vl.c
+++ b/vl.c
@@ -1518,6 +1518,11 @@ MachineInfoList *qmp_query_machines(Error **errp)

View File

@ -1,4 +1,4 @@
From 7215cf5a1ef31a3b0470c16d0b2a3585edf5dbc5 Mon Sep 17 00:00:00 2001
From d31b55269adad7b160a0942e7c887d3ec754f7d3 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:32:11 +0100
Subject: [PATCH 08/28] qapi: modify spice query

View File

@ -1,4 +1,4 @@
From 3ea2b6f80c46456be2ed339dc2338a61cc7b7bfe Mon Sep 17 00:00:00 2001
From 6eb3751cbdb888cf3a0b8e481ef7faa3f58f67cb Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:33:34 +0100
Subject: [PATCH 09/28] ui/spice: default to pve certs unless otherwise

View File

@ -1,23 +1,21 @@
From 1f5a5623052ba8d593e4356f9fda0281e607be76 Mon Sep 17 00:00:00 2001
From 27d7cf1b94244a56cd0e8a408af3e40a84dace81 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 16:04:32 +0100
Subject: [PATCH 10/28] internal snapshot async
---
Makefile.objs | 1 +
block.c | 2 +-
hmp-commands-info.hx | 13 ++
hmp-commands.hx | 32 +++
hmp.c | 57 ++++++
hmp.h | 5 +
include/block/block.h | 1 +
include/sysemu/sysemu.h | 5 +-
migration/savevm.c | 12 +-
qapi-schema.json | 68 +++++++
qemu-options.hx | 13 ++
savevm-async.c | 523 ++++++++++++++++++++++++++++++++++++++++++++++++
vl.c | 8 +
13 files changed, 732 insertions(+), 8 deletions(-)
11 files changed, 730 insertions(+), 7 deletions(-)
create mode 100644 savevm-async.c
diff --git a/Makefile.objs b/Makefile.objs
@ -32,19 +30,6 @@ index 6167e7b17d..fbfbbb7f70 100644
common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
diff --git a/block.c b/block.c
index 1fbbb8d606..6ea9ed1c62 100644
--- a/block.c
+++ b/block.c
@@ -3091,7 +3091,7 @@ out:
bdrv_unref(bs_new);
}
-static void bdrv_delete(BlockDriverState *bs)
+void bdrv_delete(BlockDriverState *bs)
{
assert(!bs->job);
assert(bdrv_op_blocker_is_empty(bs));
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index a53f105c52..5fc57a2210 100644
--- a/hmp-commands-info.hx
@ -200,18 +185,6 @@ index 799fd371fa..0497afbf65 100644
void hmp_sendkey(Monitor *mon, const QDict *qdict);
void hmp_screendump(Monitor *mon, const QDict *qdict);
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
diff --git a/include/block/block.h b/include/block/block.h
index 5ddc0cf21b..7eff87c7dd 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -295,6 +295,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
int bdrv_get_backing_file_depth(BlockDriverState *bs);
void bdrv_refresh_filename(BlockDriverState *bs);
int bdrv_truncate(BdrvChild *child, int64_t offset);
+void bdrv_delete(BlockDriverState *bs);
int64_t bdrv_nb_sectors(BlockDriverState *bs);
int64_t bdrv_getlength(BlockDriverState *bs);
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 576c7ce640..74623de16c 100644
--- a/include/sysemu/sysemu.h
@ -388,7 +361,7 @@ index 1b14ff2476..361700d37c 100644
#
# An enumeration of key name.
diff --git a/qemu-options.hx b/qemu-options.hx
index 99af8edf5f..10f0e81f9b 100644
index 48dfffd86a..cbcb27da9a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3396,6 +3396,19 @@ STEXI
@ -413,7 +386,7 @@ index 99af8edf5f..10f0e81f9b 100644
"-daemonize daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
diff --git a/savevm-async.c b/savevm-async.c
new file mode 100644
index 0000000000..2f4766cf6c
index 0000000000..5fcb56d373
--- /dev/null
+++ b/savevm-async.c
@@ -0,0 +1,523 @@
@ -525,7 +498,7 @@ index 0000000000..2f4766cf6c
+ * note: bdrv_read() need whole blocks, so we round up
+ */
+ size_t size = (snap_state.bs_pos + BDRV_SECTOR_SIZE) & BDRV_SECTOR_MASK;
+ blk_truncate(snap_state.target, size);
+ blk_truncate(snap_state.target, size, NULL);
+ blk_op_unblock_all(snap_state.target, snap_state.blocker);
+ error_free(snap_state.blocker);
+ snap_state.blocker = NULL;
@ -941,7 +914,7 @@ index 0000000000..2f4766cf6c
+ return ret;
+}
diff --git a/vl.c b/vl.c
index 868c4893df..19afd47871 100644
index 46de1b9087..2132a77129 100644
--- a/vl.c
+++ b/vl.c
@@ -2960,6 +2960,7 @@ int main(int argc, char **argv, char **envp)
@ -952,7 +925,7 @@ index 868c4893df..19afd47871 100644
MachineClass *machine_class;
const char *cpu_model;
const char *vga_model = NULL;
@@ -3631,6 +3632,9 @@ int main(int argc, char **argv, char **envp)
@@ -3635,6 +3636,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_loadvm:
loadvm = optarg;
break;
@ -962,7 +935,7 @@ index 868c4893df..19afd47871 100644
case QEMU_OPTION_full_screen:
full_screen = 1;
break;
@@ -4689,6 +4693,10 @@ int main(int argc, char **argv, char **envp)
@@ -4693,6 +4697,10 @@ int main(int argc, char **argv, char **envp)
if (load_vmstate(loadvm) < 0) {
autostart = 0;
}

View File

@ -1,4 +1,4 @@
From 1a92a719b15ed17e57999e009bc0fb4cf94ef468 Mon Sep 17 00:00:00 2001
From bed6817c14a520409f4ffee05e635c988c8b5994 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Tue, 8 Nov 2016 11:13:06 +0100
Subject: [PATCH 11/28] convert savevm-async to threads
@ -8,7 +8,7 @@ Subject: [PATCH 11/28] convert savevm-async to threads
1 file changed, 88 insertions(+), 56 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
index 2f4766cf6c..624e3a34b4 100644
index 5fcb56d373..97d51d3edd 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -48,6 +48,8 @@ static struct SnapshotState {

View File

@ -1,4 +1,4 @@
From 6c70ffe629c678a110d311fab784d65836a7917e Mon Sep 17 00:00:00 2001
From a43e451816ebd6d961412b0d88597c79eb6dd478 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 16:34:41 +0100
Subject: [PATCH 12/28] qmp: add get_link_status

View File

@ -1,4 +1,4 @@
From 3afb3d14378cc401e37dafd8437cfc45cce2aaea Mon Sep 17 00:00:00 2001
From 8d4dc658bad2438d6225d261aae8647088b853a1 Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Tue, 29 Sep 2015 15:37:44 +0200
Subject: [PATCH 13/28] smm_available = false
@ -9,7 +9,7 @@ Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 81e91a4897..4161a45dc0 100644
index e96901435a..f049bbca9a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2123,7 +2123,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms)

View File

@ -1,4 +1,4 @@
From 8f6787a80cafc259d2247a294ea657aee0928488 Mon Sep 17 00:00:00 2001
From 4c989793d0df71e8f90da8c8f883d42a8aa92191 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 16:50:05 +0100
Subject: [PATCH 14/28] use whitespace between VERSION and PKGVERSION
@ -10,7 +10,7 @@ the version string, see PVE::QemuServer::kvm_user_version()
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/vl.c b/vl.c
index 19afd47871..d0780a41b4 100644
index 2132a77129..5d888cd179 100644
--- a/vl.c
+++ b/vl.c
@@ -1909,7 +1909,7 @@ static void main_loop(void)

View File

@ -1,4 +1,4 @@
From 8c4c8041d0cb8523af453e1d1a8408215db6964f Mon Sep 17 00:00:00 2001
From 9082b919824dbedc5c3aa04369abb2f433ef6ec1 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 14:17:38 +0100
Subject: [PATCH 15/28] vnc: altgr emulation
@ -8,7 +8,7 @@ Subject: [PATCH 15/28] vnc: altgr emulation
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 349cfc9d86..9c8ab42eea 100644
index b0314441c4..f30687884b 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1631,6 +1631,10 @@ static void kbd_leds(void *opaque, int ledstate)

View File

@ -1,4 +1,4 @@
From e90d84abb42bc2befe9a48a9be2873d5dce68236 Mon Sep 17 00:00:00 2001
From 78f096b96d63ed2e7eefd5826c5b8ef62f1244eb Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Tue, 12 Jan 2016 09:09:49 +0100
Subject: [PATCH 16/28] vnc: make x509 imply tls again
@ -8,7 +8,7 @@ Subject: [PATCH 16/28] vnc: make x509 imply tls again
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 9c8ab42eea..eb9420e830 100644
index f30687884b..a345bf0d78 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3881,9 +3881,8 @@ void vnc_display_open(const char *id, Error **errp)

View File

@ -1,4 +1,4 @@
From e9712692a0a336bf56025e1bc8056636cbd3931e Mon Sep 17 00:00:00 2001
From 981ee6783da6e4d5905fcc972950296187a55c0d Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Mon, 11 Jan 2016 10:40:31 +0100
Subject: [PATCH 17/28] vnc: PVE VNC authentication
@ -180,7 +180,7 @@ index d759338816..69f010e1db 100644
void vnc_display_open(const char *id, Error **errp);
void vnc_display_add_client(const char *id, int csock, bool skipauth);
diff --git a/qemu-options.hx b/qemu-options.hx
index 10f0e81f9b..fbd1a1cecf 100644
index cbcb27da9a..0b1957c034 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -513,6 +513,9 @@ STEXI
@ -434,7 +434,7 @@ index ffaab57550..594ca737a9 100644
vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
}
diff --git a/ui/vnc.c b/ui/vnc.c
index eb9420e830..2710614a72 100644
index a345bf0d78..42db7e386b 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -56,6 +56,125 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
@ -654,7 +654,7 @@ index 694cf32ca9..78d622ab84 100644
+
#endif /* QEMU_VNC_H */
diff --git a/vl.c b/vl.c
index d0780a41b4..2496b066b7 100644
index 5d888cd179..1000a4a259 100644
--- a/vl.c
+++ b/vl.c
@@ -2947,6 +2947,7 @@ static int qemu_read_default_config_file(void)
@ -665,7 +665,7 @@ index d0780a41b4..2496b066b7 100644
int snapshot, linux_boot;
const char *initrd_filename;
const char *kernel_filename, *kernel_cmdline;
@@ -3774,6 +3775,14 @@ int main(int argc, char **argv, char **envp)
@@ -3778,6 +3779,14 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
break;

View File

@ -1,4 +1,4 @@
From 0b8732d8e19f69471e2f9b8c9a654de62482915a Mon Sep 17 00:00:00 2001
From 9398ed96d5c02451ec85a3fcea2284b6efd4b7a8 Mon Sep 17 00:00:00 2001
From: Thomas Lamprecht <t.lamprecht@proxmox.com>
Date: Wed, 6 Apr 2016 16:45:15 +0200
Subject: [PATCH 18/28] migrate: fix possible unitialised return value

View File

@ -1,4 +1,4 @@
From b0603dbd9bd127305472e8162e9b3289b866b824 Mon Sep 17 00:00:00 2001
From 24fea0d7356b39d70dde9eb683183ed5c67a4ac9 Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Tue, 26 Jul 2016 16:51:00 +0200
Subject: [PATCH 19/28] block: rbd: disable rbd_cache_writethrough_until_flush
@ -10,7 +10,7 @@ Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
1 file changed, 4 insertions(+)
diff --git a/block/rbd.c b/block/rbd.c
index 1ceeeb5a60..30fe179585 100644
index 2354ffcc64..b7700648ff 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -623,6 +623,10 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,

View File

@ -1,4 +1,4 @@
From 976296684d224ab866fc8b7ebe0d2de4b5b39170 Mon Sep 17 00:00:00 2001
From dccd9887366b5df7eeb8394cc0476536ebc8dd45 Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Tue, 13 Sep 2016 01:57:56 +0200
Subject: [PATCH 20/28] block: snapshot: qmp_snapshot_drive: add aiocontext
@ -9,7 +9,7 @@ Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
index 624e3a34b4..95995eab31 100644
index 97d51d3edd..ece193a065 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -377,6 +377,7 @@ void qmp_snapshot_drive(const char *device, const char *name, Error **errp)

View File

@ -1,4 +1,4 @@
From 1540187ba7716d502908a1815298d7c3fc8db6a6 Mon Sep 17 00:00:00 2001
From e46b7bfe99cf88021d65b7796318066b1326ad53 Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Mon, 7 Nov 2016 11:47:50 +0100
Subject: [PATCH 21/28] block: snapshot: qmp_delete_drive_snapshot : add
@ -12,7 +12,7 @@ Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
index 95995eab31..9f839faab5 100644
index ece193a065..716dd2d7a1 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -459,6 +459,7 @@ void qmp_delete_drive_snapshot(const char *device, const char *name,

View File

@ -1,4 +1,4 @@
From 26129edb715505ae35207eff2477cffec50af13e Mon Sep 17 00:00:00 2001
From a53fb2c9746d90e6020a0d7e5e8e2e346c81fb99 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Mon, 24 Oct 2016 09:32:36 +0200
Subject: [PATCH 22/28] glusterfs: no default logfile if daemonized

View File

@ -1,4 +1,4 @@
From 113e86e08a88805de1fb3aa88327174c8fa1d437 Mon Sep 17 00:00:00 2001
From b7b68751ac7a5779872611ee1084be52b7645988 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 30 Nov 2016 10:27:47 +0100
Subject: [PATCH 23/28] glusterfs: allow partial reads

View File

@ -1,4 +1,4 @@
From f5ec823838e35470f0c9ff6bf7968ac02fa08b4d Mon Sep 17 00:00:00 2001
From 728c38cd3035da76df02cf955c0452c3401eb3f3 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Thu, 17 Mar 2016 11:33:37 +0100
Subject: [PATCH 24/28] block: add the zeroinit block driver filter
@ -23,7 +23,7 @@ index de96f8ee80..8cdac08db5 100644
block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.o
diff --git a/block/zeroinit.c b/block/zeroinit.c
new file mode 100644
index 0000000000..a857ec3c62
index 0000000000..305185512e
--- /dev/null
+++ b/block/zeroinit.c
@@ -0,0 +1,220 @@
@ -203,7 +203,7 @@ index 0000000000..a857ec3c62
+
+static int zeroinit_truncate(BlockDriverState *bs, int64_t offset)
+{
+ return bdrv_truncate(bs->file, offset);
+ return bdrv_truncate(bs->file, offset, NULL);
+}
+
+static int zeroinit_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)

View File

@ -1,4 +1,4 @@
From 3bd6a30a92ecb420bac469ec977fbcc0ad918d1c Mon Sep 17 00:00:00 2001
From e1031eef2db9f19cd09c21ba36f0d106528d8df0 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Fri, 23 Jun 2017 12:01:43 +0200
Subject: [PATCH 25/28] qemu-img dd: add osize and read from/to stdin/stdout
@ -51,10 +51,10 @@ index 8ac78222af..16bee83987 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 4f7f458dd2..b9d1ef7bb8 100644
index c7804d63ee..ee7816e727 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4035,10 +4035,12 @@ out:
@@ -4026,10 +4026,12 @@ out:
#define C_IF 04
#define C_OF 010
#define C_SKIP 020
@ -67,7 +67,7 @@ index 4f7f458dd2..b9d1ef7bb8 100644
};
struct DdIo {
@@ -4117,6 +4119,20 @@ static int img_dd_skip(const char *arg,
@@ -4108,6 +4110,20 @@ static int img_dd_skip(const char *arg,
return 0;
}
@ -88,7 +88,7 @@ index 4f7f458dd2..b9d1ef7bb8 100644
static int img_dd(int argc, char **argv)
{
int ret = 0;
@@ -4156,6 +4172,7 @@ static int img_dd(int argc, char **argv)
@@ -4147,6 +4163,7 @@ static int img_dd(int argc, char **argv)
{ "if", img_dd_if, C_IF },
{ "of", img_dd_of, C_OF },
{ "skip", img_dd_skip, C_SKIP },
@ -96,7 +96,7 @@ index 4f7f458dd2..b9d1ef7bb8 100644
{ NULL, NULL, 0 }
};
const struct option long_options[] = {
@@ -4223,84 +4240,106 @@ static int img_dd(int argc, char **argv)
@@ -4214,84 +4231,106 @@ static int img_dd(int argc, char **argv)
arg = NULL;
}
@ -261,7 +261,7 @@ index 4f7f458dd2..b9d1ef7bb8 100644
}
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
@@ -4318,11 +4357,18 @@ static int img_dd(int argc, char **argv)
@@ -4309,11 +4348,18 @@ static int img_dd(int argc, char **argv)
for (out_pos = 0; in_pos < size; block_count++) {
int in_ret, out_ret;
@ -283,7 +283,7 @@ index 4f7f458dd2..b9d1ef7bb8 100644
}
if (in_ret < 0) {
error_report("error while reading from input image file: %s",
@@ -4332,9 +4378,13 @@ static int img_dd(int argc, char **argv)
@@ -4323,9 +4369,13 @@ static int img_dd(int argc, char **argv)
}
in_pos += in_ret;

View File

@ -1,4 +1,4 @@
From 020e2108f7571fac3853c47ba1ea8bafb5eef81e Mon Sep 17 00:00:00 2001
From 6017af4918c9795a7f98a463426e1e21065b15d5 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 9 Dec 2015 15:04:57 +0100
Subject: [PATCH 26/28] backup: modify job api
@ -49,10 +49,10 @@ index bf3c395eb4..1c41d9e6bf 100644
error_propagate(errp, local_err);
backup_job_cleanup(bs);
diff --git a/blockdev.c b/blockdev.c
index 4927914ce3..ec5e931029 100644
index e8a9a65167..9b6cfafd33 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3273,7 +3273,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
@@ -3262,7 +3262,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
backup->sync, bmap, backup->compress,
backup->on_source_error, backup->on_target_error,
@ -61,7 +61,7 @@ index 4927914ce3..ec5e931029 100644
bdrv_unref(target_bs);
if (local_err != NULL) {
error_propagate(errp, local_err);
@@ -3352,7 +3352,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
@@ -3341,7 +3341,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
backup->sync, NULL, backup->compress,
backup->on_source_error, backup->on_target_error,
@ -84,10 +84,10 @@ index 6e489327ff..764d41863e 100644
}
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 59400bd848..2b3ecd0575 100644
index 89d7b458e7..19b84b027f 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -878,6 +878,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
@@ -879,6 +879,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BlockdevOnError on_target_error,
int creation_flags,
BlockCompletionFunc *cb, void *opaque,

View File

@ -1,4 +1,4 @@
From c904f41916fbfa522513267933da3f08ec74215f Mon Sep 17 00:00:00 2001
From fb4bcaaced8119f2b99d1621fdfe5fce159311f4 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Wed, 2 Aug 2017 13:51:02 +0200
Subject: [PATCH 27/28] backup: introduce vma archive format
@ -19,10 +19,10 @@ Subject: [PATCH 27/28] backup: introduce vma archive format
create mode 100644 block/vma.c
diff --git a/MAINTAINERS b/MAINTAINERS
index c60235eaf6..d95f278eb4 100644
index 430efb0ab7..6a7d338aad 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1810,6 +1810,12 @@ L: qemu-block@nongnu.org
@@ -1811,6 +1811,12 @@ L: qemu-block@nongnu.org
S: Supported
F: block/vvfat.c
@ -484,7 +484,7 @@ index 0000000000..7151514f94
+
+block_init(bdrv_vma_init);
diff --git a/blockdev.c b/blockdev.c
index ec5e931029..981276692a 100644
index 9b6cfafd33..e23eb16fc8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -31,10 +31,12 @@
@ -500,7 +500,7 @@ index ec5e931029..981276692a 100644
#include "block/throttle-groups.h"
#include "monitor/monitor.h"
#include "qemu/error-report.h"
@@ -2956,6 +2958,503 @@ out:
@@ -2932,6 +2934,503 @@ out:
aio_context_release(aio_context);
}
@ -1351,10 +1351,10 @@ index 5e82933ca1..b20020a054 100644
#
# Detailed migration status.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 033457ce86..891afe5eaa 100644
index 7ce90ec940..b0ffd3de4d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2116,7 +2116,7 @@
@@ -2118,7 +2118,7 @@
'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
'null-aio', 'null-co', 'parallels', 'qcow', 'qcow2', 'qed',
'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh',
@ -1363,7 +1363,7 @@ index 033457ce86..891afe5eaa 100644
##
# @BlockdevOptionsFile:
@@ -2866,6 +2866,21 @@
@@ -2895,6 +2895,21 @@
'data': { '*offset': 'int', '*size': 'int' } }
##
@ -1385,7 +1385,7 @@ index 033457ce86..891afe5eaa 100644
# @BlockdevOptions:
#
# Options for creating a block device. Many options are available for all
@@ -2927,7 +2942,8 @@
@@ -2956,7 +2971,8 @@
'vhdx': 'BlockdevOptionsGenericFormat',
'vmdk': 'BlockdevOptionsGenericCOWFormat',
'vpc': 'BlockdevOptionsGenericFormat',

View File

@ -1,4 +1,4 @@
From 19761ee4aa12da9a3e4028cc611a18d972559de0 Mon Sep 17 00:00:00 2001
From bda9612a0dc8b39b73c8e99a149f2aa967a056a3 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Mon, 7 Aug 2017 08:51:16 +0200
Subject: [PATCH 28/28] adding old vma files
@ -295,7 +295,7 @@ index 1c41d9e6bf..60c6524417 100644
if (local_err) {
error_propagate(errp, local_err);
diff --git a/blockdev.c b/blockdev.c
index 981276692a..76a7103743 100644
index e23eb16fc8..19a82e8774 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -31,7 +31,6 @@
@ -314,7 +314,7 @@ index 981276692a..76a7103743 100644
static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
@@ -2958,20 +2958,44 @@ out:
@@ -2934,20 +2934,44 @@ out:
aio_context_release(aio_context);
}
@ -362,7 +362,7 @@ index 981276692a..76a7103743 100644
size_t total;
size_t transferred;
size_t zero_bytes;
@@ -2981,6 +3005,7 @@ typedef struct PVEBackupDevInfo {
@@ -2957,6 +2981,7 @@ typedef struct PVEBackupDevInfo {
BlockDriverState *bs;
size_t size;
uint8_t dev_id;
@ -370,7 +370,7 @@ index 981276692a..76a7103743 100644
bool completed;
char targetfile[PATH_MAX];
BlockDriverState *target;
@@ -2988,13 +3013,79 @@ typedef struct PVEBackupDevInfo {
@@ -2964,13 +2989,79 @@ typedef struct PVEBackupDevInfo {
static void pvebackup_run_next_job(void);
@ -453,7 +453,7 @@ index 981276692a..76a7103743 100644
}
if (backup_state.di_list) {
@@ -3009,6 +3100,13 @@ static void pvebackup_cleanup(void)
@@ -2985,6 +3076,13 @@ static void pvebackup_cleanup(void)
}
}
@ -467,7 +467,7 @@ index 981276692a..76a7103743 100644
static void pvebackup_complete_cb(void *opaque, int ret)
{
PVEBackupDevInfo *di = opaque;
@@ -3020,14 +3118,18 @@ static void pvebackup_complete_cb(void *opaque, int ret)
@@ -2996,14 +3094,18 @@ static void pvebackup_complete_cb(void *opaque, int ret)
ret, strerror(-ret));
}
@ -489,7 +489,7 @@ index 981276692a..76a7103743 100644
if (!backup_state.cancel) {
pvebackup_run_next_job();
}
@@ -3041,14 +3143,9 @@ static void pvebackup_cancel(void *opaque)
@@ -3017,14 +3119,9 @@ static void pvebackup_cancel(void *opaque)
error_setg(&backup_state.error, "backup cancelled");
}
@ -506,7 +506,7 @@ index 981276692a..76a7103743 100644
}
GList *l = backup_state.di_list;
@@ -3073,19 +3170,15 @@ void qmp_backup_cancel(Error **errp)
@@ -3049,19 +3146,15 @@ void qmp_backup_cancel(Error **errp)
Coroutine *co = qemu_coroutine_create(pvebackup_cancel, NULL);
qemu_coroutine_enter(co);
@ -530,7 +530,7 @@ index 981276692a..76a7103743 100644
{
char *cdata = NULL;
gsize clen = 0;
@@ -3098,12 +3191,17 @@ static int config_to_vma(const char *file, BackupFormat format,
@@ -3074,12 +3167,17 @@ static int config_to_vma(const char *file, BackupFormat format,
char *basename = g_path_get_basename(file);
if (format == BACKUP_FORMAT_VMA) {
@ -550,7 +550,7 @@ index 981276692a..76a7103743 100644
g_free(cdata);
g_free(basename);
return 1;
@@ -3113,35 +3211,37 @@ static int config_to_vma(const char *file, BackupFormat format,
@@ -3089,35 +3187,37 @@ static int config_to_vma(const char *file, BackupFormat format,
g_free(basename);
g_free(cdata);
@ -601,7 +601,7 @@ index 981276692a..76a7103743 100644
bool has_devlist, const char *devlist,
bool has_speed, int64_t speed, Error **errp)
{
@@ -3149,14 +3249,15 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
@@ -3125,14 +3225,15 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
BlockDriverState *bs = NULL;
const char *backup_dir = NULL;
Error *local_err = NULL;
@ -619,7 +619,7 @@ index 981276692a..76a7103743 100644
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
"previous backup not finished");
return NULL;
@@ -3231,40 +3332,28 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
@@ -3207,40 +3308,28 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
total += size;
}
@ -668,7 +668,7 @@ index 981276692a..76a7103743 100644
goto err;
}
}
@@ -3305,15 +3394,15 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
@@ -3281,15 +3370,15 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
/* add configuration file to archive */
if (has_config_file) {
@ -688,7 +688,7 @@ index 981276692a..76a7103743 100644
}
}
/* initialize global backup_state now */
@@ -3335,11 +3424,12 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
@@ -3311,11 +3400,12 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
}
backup_state.backup_file = g_strdup(backup_file);
@ -704,7 +704,7 @@ index 981276692a..76a7103743 100644
backup_state.total = total;
backup_state.transferred = 0;
@@ -3350,21 +3440,16 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
@@ -3326,21 +3416,16 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
while (l) {
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
l = g_list_next(l);
@ -729,7 +729,7 @@ index 981276692a..76a7103743 100644
}
if (!backup_state.error) {
@@ -3398,9 +3483,10 @@ err:
@@ -3374,9 +3459,10 @@ err:
g_strfreev(devs);
}
@ -743,7 +743,7 @@ index 981276692a..76a7103743 100644
}
if (backup_dir) {
@@ -3772,7 +3858,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
@@ -3761,7 +3847,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
backup->sync, bmap, backup->compress,
backup->on_source_error, backup->on_target_error,
@ -752,7 +752,7 @@ index 981276692a..76a7103743 100644
bdrv_unref(target_bs);
if (local_err != NULL) {
error_propagate(errp, local_err);
@@ -3851,7 +3937,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
@@ -3840,7 +3926,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
backup->sync, NULL, backup->compress,
backup->on_source_error, backup->on_target_error,
@ -805,7 +805,7 @@ index 764d41863e..cb3741f6dd 100644
if (block_job_is_internal(job)) {
return;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 2b3ecd0575..278da161fb 100644
index 19b84b027f..fc1c53a059 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -59,6 +59,9 @@
@ -818,7 +818,7 @@ index 2b3ecd0575..278da161fb 100644
enum BdrvTrackedRequestType {
BDRV_TRACKED_READ,
BDRV_TRACKED_WRITE,
@@ -877,6 +880,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
@@ -878,6 +881,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
int creation_flags,

34
debian/patches/series vendored
View File

@ -27,25 +27,15 @@ pve/0026-backup-modify-job-api.patch
pve/0027-backup-introduce-vma-archive-format.patch
pve/0028-adding-old-vma-files.patch
extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch
extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch
extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch
extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch
extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch
extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch
extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch
extra/0008-virtio-serial-fix-segfault-on-disconnect.patch
extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch
extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch
extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch
extra/0012-audio-release-capture-buffers.patch
extra/0013-input-limit-kbd-queue-depth.patch
extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch
extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch
extra/0016-megasas-do-not-read-DCMD-opcode-more-than-once-from-.patch
extra/0017-megasas-always-store-SCSIRequest-into-MegasasCmd.patch
extra/0018-nbd-Fully-initialize-client-in-case-of-failed-negoti.patch
extra/0019-nbd-Fix-regression-on-resiliency-to-port-scan.patch
extra/0020-qemu-nbd-Ignore-SIGPIPE.patch
extra/0021-usb-redir-fix-stack-overflow-in-usbredir_log_data.patch
extra/0022-exec-use-qemu_ram_ptr_length-to-access-guest-ram.patch
extra/0023-slirp-check-len-against-dhcp-options-array-end.patch
extra/0002-virtio-serial-fix-segfault-on-disconnect.patch
extra/0003-megasas-always-store-SCSIRequest-into-MegasasCmd.patch
extra/0004-slirp-check-len-against-dhcp-options-array-end.patch
extra/0005-IDE-Do-not-flush-empty-CDROM-drives.patch
extra/0006-bitmap-add-bitmap_copy_and_clear_atomic.patch
extra/0007-memory-add-support-getting-and-using-a-dirty-bitmap-.patch
extra/0008-vga-add-vga_scanline_invalidated-helper.patch
extra/0009-vga-make-display-updates-thread-safe.patch
extra/0010-vga-fix-display-update-region-calculation.patch
extra/0011-vga-fix-display-update-region-calculation-split-scre.patch
extra/0012-vga-stop-passing-pointers-to-vga_draw_line-functions.patch
extra/0013-multiboot-validate-multiboot-header-address-values.patch

2
qemu

@ -1 +1 @@
Subproject commit 359c41abe32638adad503e386969fa428cecff52
Subproject commit 4cd42653f5c1df326a2678a84f24a78fb9601277