QEMU is a FAST! processor emulator
CentOS Sources
2017-01-17 40b356d416f3c578108bef89f14e8d9f8ccccdbb
import qemu-kvm-1.5.3-126.el7_3.3
11 files added
1 files modified
963 ■■■■■ changed files
SOURCES/kvm-balloon-fix-segfault-and-harden-the-stats-queue.patch 138 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-hw-i386-regenerate-checked-in-AML-payload-RHEL-only.patch 179 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-ide-fix-halted-IO-segfault-at-reset.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-net-check-packet-payload-length.patch 64 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-add-virtqueue_rewind.patch 86 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-balloon-discard-virtqueue-element-on-reset.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-balloon-fix-stats-vq-migration.patch 75 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-decrement-vq-inuse-in-virtqueue_discard.patch 48 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-introduce-virtqueue_discard.patch 66 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-introduce-virtqueue_unmap_sg.patch 70 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-zero-vq-inuse-in-virtio_reset.patch 63 ●●●●● patch | view | raw | blame | history
SPECS/qemu-kvm.spec 66 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-balloon-fix-segfault-and-harden-the-stats-queue.patch
New file
@@ -0,0 +1,138 @@
From 75255574498fad12727529c4ecbd4ccdabe86839 Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Wed, 5 Oct 2016 17:22:26 +0200
Subject: [PATCH 4/8] balloon: fix segfault and harden the stats queue
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1475666548-9186-5-git-send-email-lprosek@redhat.com>
Patchwork-id: 72483
O-Subject: [RHEL-7.4 qemu-kvm v2 PATCH 4/6] balloon: fix segfault and harden the stats queue
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
The segfault here is triggered by the driver notifying the stats queue
twice after adding a buffer to it. This effectively resets stats_vq_elem
back to NULL and QEMU crashes on the next stats timer tick in
balloon_stats_poll_cb.
This is a regression introduced in 51b19ebe4320f3dc, although admittedly
the device assumed too much about the stats queue protocol even before
that commit. This commit adds a few more checks and ensures that the one
stats buffer gets deallocated on device reset.
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>
(cherry picked from commit 4eae2a657d1ff5ada56eb9b4966eae0eff333b0b)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
  * 1.5.3 does not return pointers from virtqueue_pop so only the
    "harden the stats queue" part of the upstream patch description
    applies
  * a new field stats_vq_elem_pending is introduced to keep track
    of the state of stats_vq_elem in lieu of its nullness upstream
  * virtio_balloon_device_reset only resets stats_vq_elem_pending
    because there is nothing to free
---
 hw/virtio/virtio-balloon.c         | 27 +++++++++++++++++++++++----
 include/hw/virtio/virtio-balloon.h |  1 +
 2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 016dc60..17b3029 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -95,13 +95,14 @@ static void balloon_stats_poll_cb(void *opaque)
     VirtIOBalloon *s = opaque;
     VirtIODevice *vdev = VIRTIO_DEVICE(s);
-    if (!balloon_stats_supported(s)) {
+    if (!s->stats_vq_elem_pending || !balloon_stats_supported(s)) {
         /* re-schedule */
         balloon_stats_change_timer(s, s->stats_poll_interval);
         return;
     }
     virtqueue_push(s->svq, &s->stats_vq_elem, s->stats_vq_offset);
+    s->stats_vq_elem_pending = false;
     virtio_notify(vdev, s->svq);
 }
@@ -220,14 +221,22 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
-    VirtQueueElement *elem = &s->stats_vq_elem;
+    VirtQueueElement elem;
     VirtIOBalloonStat stat;
     size_t offset = 0;
     qemu_timeval tv;
-    if (!virtqueue_pop(vq, elem)) {
+    if (!virtqueue_pop(vq, &elem)) {
         goto out;
     }
+    if (s->stats_vq_elem_pending) {
+        /* This should never happen if the driver follows the spec. */
+        virtqueue_push(vq, &s->stats_vq_elem, 0);
+        virtio_notify(vdev, vq);
+    }
+
+    s->stats_vq_elem = elem;
+    s->stats_vq_elem_pending = true;
     /* Initialize the stats to get rid of any stale values.  This is only
      * needed to handle the case where a guest supports fewer stats than it
@@ -235,7 +244,7 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
      */
     reset_stats(s);
-    while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat))
+    while (iov_to_buf(elem.out_sg, elem.out_num, offset, &stat, sizeof(stat))
            == sizeof(stat)) {
         uint16_t tag = tswap16(stat.tag);
         uint64_t val = tswap64(stat.val);
@@ -384,6 +393,15 @@ static void virtio_balloon_device_exit(VirtIODevice *vdev)
     virtio_cleanup(vdev);
 }
+static void virtio_balloon_device_reset(VirtIODevice *vdev)
+{
+    VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
+
+    if (s->stats_vq_elem_pending) {
+        s->stats_vq_elem_pending = false;
+    }
+}
+
 static Property virtio_balloon_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -396,6 +414,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     vdc->init = virtio_balloon_device_init;
     vdc->exit = virtio_balloon_device_exit;
+    vdc->reset = virtio_balloon_device_reset;
     vdc->get_config = virtio_balloon_get_config;
     vdc->set_config = virtio_balloon_set_config;
     vdc->get_features = virtio_balloon_get_features;
diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h
index f863bfe..a84736b 100644
--- a/include/hw/virtio/virtio-balloon.h
+++ b/include/hw/virtio/virtio-balloon.h
@@ -63,6 +63,7 @@ typedef struct VirtIOBalloon {
     uint32_t actual;
     uint64_t stats[VIRTIO_BALLOON_S_NR];
     VirtQueueElement stats_vq_elem;
+    bool stats_vq_elem_pending;
     size_t stats_vq_offset;
     QEMUTimer *stats_timer;
     int64_t stats_last_update;
--
1.8.3.1
SOURCES/kvm-hw-i386-regenerate-checked-in-AML-payload-RHEL-only.patch
New file
@@ -0,0 +1,179 @@
From 4f55d2d2f6efdce59440b57726f09578b8692158 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Fri, 23 Sep 2016 14:39:35 +0200
Subject: [PATCH 2/3] hw/i386: regenerate checked-in AML payload (RHEL only)
RH-Author: Laszlo Ersek <lersek@redhat.com>
Message-id: <20160923143936.25594-2-lersek@redhat.com>
Patchwork-id: 72414
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/2] hw/i386: regenerate checked-in AML payload (RHEL only)
Bugzilla: 1392027
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
In preparation for the next patch, which will flip the build from IASL to
pre-generated AML, rebuild the checked-in AML content, with the last iasl
version that's known -- from Brew -- to generate good AML, namely
"acpica-tools-20150619-3.el7.x86_64".
Only checksums and likely some metadata change in the AML payload. This
proves that our checked-in files have been up to date, and it's safe to
switch the build to them. I actually verified this in a RHEL-7 guest, with
"acpidump -b" and "iasl -d" -- the dumped and disassembled DSL files
remained identical across this change.
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/i386/acpi-dsdt.hex.generated     |  8 ++++----
 hw/i386/q35-acpi-dsdt.hex.generated |  8 ++++----
 hw/i386/ssdt-misc.hex.generated     |  8 ++++----
 hw/i386/ssdt-pcihp.hex.generated    |  8 ++++----
 hw/i386/ssdt-proc.hex.generated     | 12 ++++++------
 5 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated
index 2c01107..b2af8d0 100644
--- a/hw/i386/acpi-dsdt.hex.generated
+++ b/hw/i386/acpi-dsdt.hex.generated
@@ -8,7 +8,7 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x0,
 0x0,
 0x1,
-0xe0,
+0xea,
 0x42,
 0x58,
 0x50,
@@ -31,9 +31,9 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x19,
+0x6,
+0x15,
 0x20,
 0x10,
 0x49,
diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated
index 32c16ff..23ab305 100644
--- a/hw/i386/q35-acpi-dsdt.hex.generated
+++ b/hw/i386/q35-acpi-dsdt.hex.generated
@@ -8,7 +8,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x0,
 0x0,
 0x1,
-0x6,
+0x10,
 0x42,
 0x58,
 0x50,
@@ -31,9 +31,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x19,
+0x6,
+0x15,
 0x20,
 0x10,
 0x49,
diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated
index 55e3bd2..86c5725 100644
--- a/hw/i386/ssdt-misc.hex.generated
+++ b/hw/i386/ssdt-misc.hex.generated
@@ -23,7 +23,7 @@ static unsigned char ssdp_misc_aml[] = {
 0x0,
 0x0,
 0x1,
-0x76,
+0x80,
 0x42,
 0x58,
 0x50,
@@ -46,9 +46,9 @@ static unsigned char ssdp_misc_aml[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x19,
+0x6,
+0x15,
 0x20,
 0x10,
 0x42,
diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated
index b3c2cd5..2f946d5 100644
--- a/hw/i386/ssdt-pcihp.hex.generated
+++ b/hw/i386/ssdt-pcihp.hex.generated
@@ -17,7 +17,7 @@ static unsigned char ssdp_pcihp_aml[] = {
 0x0,
 0x0,
 0x1,
-0x76,
+0x80,
 0x42,
 0x58,
 0x50,
@@ -40,9 +40,9 @@ static unsigned char ssdp_pcihp_aml[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x19,
+0x6,
+0x15,
 0x20,
 0x10,
 0x33,
diff --git a/hw/i386/ssdt-proc.hex.generated b/hw/i386/ssdt-proc.hex.generated
index bb9920d..1b4118a 100644
--- a/hw/i386/ssdt-proc.hex.generated
+++ b/hw/i386/ssdt-proc.hex.generated
@@ -11,7 +11,7 @@ static unsigned char ssdp_proc_aml[] = {
 0x0,
 0x0,
 0x1,
-0xb8,
+0x82,
 0x42,
 0x58,
 0x50,
@@ -34,9 +34,9 @@ static unsigned char ssdp_proc_aml[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x19,
+0x6,
+0x15,
 0x20,
 0x5b,
 0x83,
@@ -47,8 +47,8 @@ static unsigned char ssdp_proc_aml[] = {
 0x41,
 0x41,
 0xaa,
-0x10,
-0xb0,
+0x0,
+0x0,
 0x0,
 0x0,
 0x0,
--
1.8.3.1
SOURCES/kvm-ide-fix-halted-IO-segfault-at-reset.patch
New file
@@ -0,0 +1,54 @@
From 4d3c9646213bdf992af4e28eaf0d57610eb79fec Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Thu, 29 Sep 2016 00:02:14 +0200
Subject: [PATCH 1/3] ide: fix halted IO segfault at reset
RH-Author: John Snow <jsnow@redhat.com>
Message-id: <1475107334-14972-2-git-send-email-jsnow@redhat.com>
Patchwork-id: 72436
O-Subject: [RHEL-7.3.z qemu-kvm PATCH 1/1] ide: fix halted IO segfault at reset
Bugzilla: 1393042
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
If one attempts to perform a system_reset after a failed IO request
that causes the VM to enter a paused state, QEMU will segfault trying
to free up the pending IO requests.
These requests have already been completed and freed, though, so all
we need to do is NULL them before we enter the paused state.
Existing AHCI tests verify that halted requests are still resumed
successfully after a STOP event.
Analyzed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1469635201-11918-2-git-send-email-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 87ac25fd1fed05a30a93d27dbeb2a4c4b83ec95f)
Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
  hw/ide/core.c: Context and formatting of handle_rw_error
---
 hw/ide/core.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 5d40093..5c33735 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -658,6 +658,7 @@ void ide_dma_cb(void *opaque, int ret)
             op |= BM_STATUS_RETRY_TRIM;
         if (ide_handle_rw_error(s, -ret, op)) {
+            s->bus->dma->aiocb = NULL;
             return;
         }
     }
--
1.8.3.1
SOURCES/kvm-net-check-packet-payload-length.patch
New file
@@ -0,0 +1,64 @@
From 6d126da8f958c57413a4505d98cb4a3ff48cbbfe Mon Sep 17 00:00:00 2001
From: "wexu@redhat.com" <wexu@redhat.com>
Date: Wed, 21 Dec 2016 06:04:24 +0100
Subject: [PATCH] net: check packet payload length
RH-Author: wexu@redhat.com
Message-id: <1482300264-29708-2-git-send-email-wexu@redhat.com>
Patchwork-id: 73088
O-Subject: [RHEL-7.4/7.3.z qemu-kvm Patch v2] net: check packet payload length
Bugzilla: 1398217
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Prasad J Pandit <pjp@fedoraproject.org>
While computing IP checksum, 'net_checksum_calculate' reads
payload length from the packet. It could exceed the given 'data'
buffer size. Add a check to avoid it.
This patch is to fix CVE-2016-2857.
https://access.redhat.com/security/cve/CVE-2016-2857
Reported-by: Liu Ling <liuling-it@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 362786f14a753d8a5256ef97d7c10ed576d6572b)
Signed-off-by: Wei Xu <wexu@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 net/checksum.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/checksum.c b/net/checksum.c
index 14c0855..0942437 100644
--- a/net/checksum.c
+++ b/net/checksum.c
@@ -59,6 +59,11 @@ void net_checksum_calculate(uint8_t *data, int length)
     int hlen, plen, proto, csum_offset;
     uint16_t csum;
+    /* Ensure data has complete L2 & L3 headers. */
+    if (length < 14 + 20) {
+        return;
+    }
+
     if ((data[14] & 0xf0) != 0x40)
     return; /* not IPv4 */
     hlen  = (data[14] & 0x0f) * 4;
@@ -76,8 +81,9 @@ void net_checksum_calculate(uint8_t *data, int length)
     return;
     }
-    if (plen < csum_offset+2)
-    return;
+    if (plen < csum_offset + 2 || 14 + hlen + plen > length) {
+        return;
+    }
     data[14+hlen+csum_offset]   = 0;
     data[14+hlen+csum_offset+1] = 0;
--
1.8.3.1
SOURCES/kvm-virtio-add-virtqueue_rewind.patch
New file
@@ -0,0 +1,86 @@
From f7d6a76475d29e0edb5456e62492117b87f4bc41 Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Thu, 10 Nov 2016 23:00:50 +0100
Subject: [PATCH 7/8] virtio: add virtqueue_rewind()
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1478797251-10302-1-git-send-email-lprosek@redhat.com>
Patchwork-id: 72818
O-Subject: [PATCH v2 7/6] virtio: add virtqueue_rewind()
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
virtqueue_discard() requires a VirtQueueElement but virtio-balloon does
not migrate its in-use element.  Introduce a new function that is
similar to virtqueue_discard() but doesn't require a VirtQueueElement.
This will allow virtio-balloon to access element again after migration
with the usual proviso that the guest may have modified the vring since
last time.
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Roman Kagan <rkagan@virtuozzo.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
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>
(cherry picked from commit 297a75e6c55d91db2704a3d6e4029d99c7df51fd)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/virtio/virtio.c         | 22 ++++++++++++++++++++++
 include/hw/virtio/virtio.h |  1 +
 2 files changed, 23 insertions(+)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index cdb21b1..fe6b032 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -259,6 +259,28 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
     virtqueue_unmap_sg(vq, elem, len);
 }
+/* virtqueue_rewind:
+ * @vq: The #VirtQueue
+ * @num: Number of elements to push back
+ *
+ * Pretend that elements weren't popped from the virtqueue.  The next
+ * virtqueue_pop() will refetch the oldest element.
+ *
+ * Use virtqueue_discard() instead if you have a VirtQueueElement.
+ *
+ * Returns: true on success, false if @num is greater than the number of in use
+ * elements.
+ */
+bool virtqueue_rewind(VirtQueue *vq, unsigned int num)
+{
+    if (num > vq->inuse) {
+        return false;
+    }
+    vq->last_avail_idx -= num;
+    vq->inuse -= num;
+    return true;
+}
+
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx)
 {
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index de32425..d9bfe4c 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -167,6 +167,7 @@ void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
 void virtqueue_flush(VirtQueue *vq, unsigned int count);
 void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
                        unsigned int len);
+bool virtqueue_rewind(VirtQueue *vq, unsigned int num);
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx);
--
1.8.3.1
SOURCES/kvm-virtio-balloon-discard-virtqueue-element-on-reset.patch
New file
@@ -0,0 +1,54 @@
From a1c91f04449eea0e678aeef78914213f092b7a19 Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Wed, 5 Oct 2016 17:22:27 +0200
Subject: [PATCH 5/8] virtio-balloon: discard virtqueue element on reset
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1475666548-9186-6-git-send-email-lprosek@redhat.com>
Patchwork-id: 72484
O-Subject: [RHEL-7.4 qemu-kvm v2 PATCH 5/6] virtio-balloon: discard virtqueue element on reset
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
The one pending element is being freed but not discarded on device
reset, which causes svq->inuse to creep up, eventually hitting the
"Virtqueue size exceeded" error.
Properly discarding the element on device reset makes sure that its
buffers are unmapped and the inuse counter stays balanced.
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Roman Kagan <rkagan@virtuozzo.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 104e70cae78bd4afd95d948c6aff188f10508a9c)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
  * s->stats_vq_elem => &s->stats_vq_elem because the field is not
    s pointer in 1.5.3
---
 hw/virtio/virtio-balloon.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 17b3029..faf93f7 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -398,6 +398,7 @@ static void virtio_balloon_device_reset(VirtIODevice *vdev)
     VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
     if (s->stats_vq_elem_pending) {
+        virtqueue_discard(s->svq, &s->stats_vq_elem, 0);
         s->stats_vq_elem_pending = false;
     }
 }
--
1.8.3.1
SOURCES/kvm-virtio-balloon-fix-stats-vq-migration.patch
New file
@@ -0,0 +1,75 @@
From 6d5c0e0e98907244d72e7828337d7ff6160b6b80 Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Thu, 10 Nov 2016 23:00:51 +0100
Subject: [PATCH 8/8] virtio-balloon: fix stats vq migration
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1478797251-10302-2-git-send-email-lprosek@redhat.com>
Patchwork-id: 72819
O-Subject: [PATCH v2 8/6] virtio-balloon: fix stats vq migration
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
The statistics virtqueue is not migrated properly because virtio-balloon
does not include s->stats_vq_elem in the migration stream.
After migration the statistics virtqueue hangs because the host never
completes the last element (s->stats_vq_elem is NULL on the destination
QEMU).  Therefore the guest never submits new elements and the virtqueue
is hung.
Instead of changing the migration stream format in an incompatible way,
detect the migration case and rewind the virtqueue so the last element
can be completed.
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Roman Kagan <rkagan@virtuozzo.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Suggested-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 4a1e48becab81020adfb74b22c76a595f2d02a01)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/virtio/virtio-balloon.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index faf93f7..1a60d3c 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -403,6 +403,18 @@ static void virtio_balloon_device_reset(VirtIODevice *vdev)
     }
 }
+static void virtio_balloon_set_status(VirtIODevice *vdev, uint8_t status)
+{
+    VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
+
+    if (!s->stats_vq_elem_pending && vdev->vm_running &&
+        (status & VIRTIO_CONFIG_S_DRIVER_OK) && virtqueue_rewind(s->svq, 1)) {
+        /* poll stats queue for the element we have discarded when the VM
+         * was stopped */
+        virtio_balloon_receive_stats(vdev, s->svq);
+    }
+}
+
 static Property virtio_balloon_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -419,6 +431,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
     vdc->get_config = virtio_balloon_get_config;
     vdc->set_config = virtio_balloon_set_config;
     vdc->get_features = virtio_balloon_get_features;
+    vdc->set_status = virtio_balloon_set_status;
 }
 static const TypeInfo virtio_balloon_info = {
--
1.8.3.1
SOURCES/kvm-virtio-decrement-vq-inuse-in-virtqueue_discard.patch
New file
@@ -0,0 +1,48 @@
From c24e1c927bad95d84e0ffab665baff98d91fb916 Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Wed, 5 Oct 2016 17:22:25 +0200
Subject: [PATCH 3/8] virtio: decrement vq->inuse in virtqueue_discard()
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1475666548-9186-4-git-send-email-lprosek@redhat.com>
Patchwork-id: 72482
O-Subject: [RHEL-7.4 qemu-kvm v2 PATCH 3/6] virtio: decrement vq->inuse in virtqueue_discard()
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
virtqueue_discard() moves vq->last_avail_idx back so the element can be
popped again.  It's necessary to decrement vq->inuse to avoid "leaking"
the element count.
Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 58a83c61496eeb0d31571a07a51bc1947e3379ac)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/virtio/virtio.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 91c9642..87a7639 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -255,6 +255,7 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
                        unsigned int len)
 {
     vq->last_avail_idx--;
+    vq->inuse--;
     virtqueue_unmap_sg(vq, elem, len);
 }
--
1.8.3.1
SOURCES/kvm-virtio-introduce-virtqueue_discard.patch
New file
@@ -0,0 +1,66 @@
From b5c6f7a910c5c16ac34ef2436d0a56991e0166e3 Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Wed, 5 Oct 2016 17:22:24 +0200
Subject: [PATCH 2/8] virtio: introduce virtqueue_discard()
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1475666548-9186-3-git-send-email-lprosek@redhat.com>
Patchwork-id: 72481
O-Subject: [RHEL-7.4 qemu-kvm v2 PATCH 2/6] virtio: introduce virtqueue_discard()
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Jason Wang <jasowang@redhat.com>
This patch introduces virtqueue_discard() to discard a descriptor and
unmap the sgs. This will be used by the patch that will discard
descriptor when packet is truncated.
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 29b9f5efd78ae0f9cc02dd169b6e80d2c404bade)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/virtio/virtio.c         | 7 +++++++
 include/hw/virtio/virtio.h | 2 ++
 2 files changed, 9 insertions(+)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 5ee899a..91c9642 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -251,6 +251,13 @@ static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
                                   0, elem->out_sg[i].iov_len);
 }
+void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
+                       unsigned int len)
+{
+    vq->last_avail_idx--;
+    virtqueue_unmap_sg(vq, elem, len);
+}
+
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx)
 {
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 9e22865..de32425 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -165,6 +165,8 @@ void virtio_del_queue(VirtIODevice *vdev, int n);
 void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len);
 void virtqueue_flush(VirtQueue *vq, unsigned int count);
+void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
+                       unsigned int len);
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx);
--
1.8.3.1
SOURCES/kvm-virtio-introduce-virtqueue_unmap_sg.patch
New file
@@ -0,0 +1,70 @@
From fc6f666f00182fe587068bd45e4e9e6d135d03fb Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Wed, 5 Oct 2016 17:22:23 +0200
Subject: [PATCH 1/8] virtio: introduce virtqueue_unmap_sg()
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1475666548-9186-2-git-send-email-lprosek@redhat.com>
Patchwork-id: 72480
O-Subject: [RHEL-7.4 qemu-kvm v2 PATCH 1/6] virtio: introduce virtqueue_unmap_sg()
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Jason Wang <jasowang@redhat.com>
Factor out sg unmapping logic. This will be reused by the patch that
can discard descriptor.
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Andrew James <andrew.james@hpe.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit ce317461573bac12b10d67699b4ddf1f97cf066c)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/virtio/virtio.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 0df4ed3..5ee899a 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -228,14 +228,12 @@ int virtio_queue_empty(VirtQueue *vq)
     return vring_avail_idx(vq) == vq->last_avail_idx;
 }
-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
-                    unsigned int len, unsigned int idx)
+static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
+                               unsigned int len)
 {
     unsigned int offset;
     int i;
-    trace_virtqueue_fill(vq, elem, len, idx);
-
     offset = 0;
     for (i = 0; i < elem->in_num; i++) {
         size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
@@ -251,6 +249,14 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
         cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
                                   elem->out_sg[i].iov_len,
                                   0, elem->out_sg[i].iov_len);
+}
+
+void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
+                    unsigned int len, unsigned int idx)
+{
+    trace_virtqueue_fill(vq, elem, len, idx);
+
+    virtqueue_unmap_sg(vq, elem, len);
     idx = (idx + vring_used_idx(vq)) % vq->vring.num;
--
1.8.3.1
SOURCES/kvm-virtio-zero-vq-inuse-in-virtio_reset.patch
New file
@@ -0,0 +1,63 @@
From e3e5226d8ed3907bb818eb8db74175c08c011459 Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com>
Date: Wed, 5 Oct 2016 17:22:28 +0200
Subject: [PATCH 6/8] virtio: zero vq->inuse in virtio_reset()
RH-Author: Ladi Prosek <lprosek@redhat.com>
Message-id: <1475666548-9186-7-git-send-email-lprosek@redhat.com>
Patchwork-id: 72485
O-Subject: [RHEL-7.4 qemu-kvm v2 PATCH 6/6] virtio: zero vq->inuse in virtio_reset()
Bugzilla: 1393484
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
vq->inuse must be zeroed upon device reset like most other virtqueue
fields.
In theory, virtio_reset() just needs assert(vq->inuse == 0) since
devices must clean up in-flight requests during reset (requests cannot
not be leaked!).
In practice, it is difficult to achieve vq->inuse == 0 across reset
because balloon, blk, 9p, etc implement various different strategies for
cleaning up requests.  Most devices call g_free(elem) directly without
telling virtio.c that the VirtQueueElement is cleaned up.  Therefore
vq->inuse is not decremented during reset.
This patch zeroes vq->inuse and trusts that devices are not leaking
VirtQueueElements across reset.
I will send a follow-up series that refactors request life-cycle across
all devices and converts vq->inuse = 0 into assert(vq->inuse == 0) but
this more invasive approach is not appropriate for stable trees.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Ladi Prosek <lprosek@redhat.com>
(cherry picked from commit 4b7f91ed0270a371e1933efa21ba600b6da23ab9)
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/virtio/virtio.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 87a7639..cdb21b1 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -585,6 +585,7 @@ void virtio_reset(void *opaque)
         vdev->vq[i].signalled_used = 0;
         vdev->vq[i].signalled_used_valid = false;
         vdev->vq[i].notification = true;
+        vdev->vq[i].inuse = 0;
     }
 }
--
1.8.3.1
SPECS/qemu-kvm.spec
@@ -76,7 +76,7 @@
Summary: QEMU is a FAST! processor emulator
Name: %{pkgname}%{?pkgsuffix}
Version: 1.5.3
Release: 126%{?dist}
Release: 126%{?dist}.3
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 10
License: GPLv2+ and LGPLv2+ and BSD
@@ -3388,6 +3388,28 @@
Patch1665: kvm-nbd-server-Set-O_NONBLOCK-on-client-fd.patch
# For bz#1376542 - RHSA-2016-1756 breaks migration of instances
Patch1666: kvm-virtio-recalculate-vq-inuse-after-migration.patch
# For bz#1393042 - system_reset should clear pending request for error (IDE)
Patch1667: kvm-ide-fix-halted-IO-segfault-at-reset.patch
# For bz#1392027 - shutdown rhel 5.11 guest failed and stop at "system halted"
Patch1668: kvm-hw-i386-regenerate-checked-in-AML-payload-RHEL-only.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1669: kvm-virtio-introduce-virtqueue_unmap_sg.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1670: kvm-virtio-introduce-virtqueue_discard.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1671: kvm-virtio-decrement-vq-inuse-in-virtqueue_discard.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1672: kvm-balloon-fix-segfault-and-harden-the-stats-queue.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1673: kvm-virtio-balloon-discard-virtqueue-element-on-reset.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1674: kvm-virtio-zero-vq-inuse-in-virtio_reset.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1675: kvm-virtio-add-virtqueue_rewind.patch
# For bz#1393484 - [RHEL7.3] KVM guest shuts itself down after 128th reboot
Patch1676: kvm-virtio-balloon-fix-stats-vq-migration.patch
# For bz#1398217 - CVE-2016-2857 qemu-kvm: Qemu: net: out of bounds read in net_checksum_calculate() [rhel-7.3.z]
Patch1677: kvm-net-check-packet-payload-length.patch
BuildRequires: zlib-devel
@@ -3462,10 +3484,8 @@
%if 0%{?have_librdma:1}
BuildRequires: librdmacm-devel
%endif
# iasl and cpp for acpi generation (not a hard requirement as we can use
# pre-compiled files, but it's better to use this)
# cpp for preprocessing option ROM assembly files
%ifarch %{ix86} x86_64
BuildRequires: iasl
BuildRequires: cpp
%endif
%if 0%{!?build_only_sub:1}
@@ -5236,6 +5256,17 @@
%patch1664 -p1
%patch1665 -p1
%patch1666 -p1
%patch1667 -p1
%patch1668 -p1
%patch1669 -p1
%patch1670 -p1
%patch1671 -p1
%patch1672 -p1
%patch1673 -p1
%patch1674 -p1
%patch1675 -p1
%patch1676 -p1
%patch1677 -p1
%build
buildarch="%{kvm_target}-softmmu"
@@ -5320,6 +5351,7 @@
%endif
        --block-drv-rw-whitelist=qcow2,raw,file,host_device,blkdebug,nbd,iscsi,gluster,rbd \
        --block-drv-ro-whitelist=vmdk,vhdx,vpc,ssh,https \
        --iasl=/bin/false \
        "$@"
    echo "config-host.mak contents:"
@@ -5680,6 +5712,32 @@
%{_mandir}/man8/qemu-nbd.8*
%changelog
* Wed Jan 04 2017 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-126.el7_3.3
- kvm-net-check-packet-payload-length.patch [bz#1398217]
- Resolves: bz#1398217
  (CVE-2016-2857 qemu-kvm: Qemu: net: out of bounds read in net_checksum_calculate() [rhel-7.3.z])
* Thu Nov 24 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-126.el7_3.2
- kvm-virtio-introduce-virtqueue_unmap_sg.patch [bz#1393484]
- kvm-virtio-introduce-virtqueue_discard.patch [bz#1393484]
- kvm-virtio-decrement-vq-inuse-in-virtqueue_discard.patch [bz#1393484]
- kvm-balloon-fix-segfault-and-harden-the-stats-queue.patch [bz#1393484]
- kvm-virtio-balloon-discard-virtqueue-element-on-reset.patch [bz#1393484]
- kvm-virtio-zero-vq-inuse-in-virtio_reset.patch [bz#1393484]
- kvm-virtio-add-virtqueue_rewind.patch [bz#1393484]
- kvm-virtio-balloon-fix-stats-vq-migration.patch [bz#1393484]
- Resolves: bz#1393484
  ([RHEL7.3] KVM guest shuts itself down after 128th reboot)
* Fri Nov 11 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-126.el7_3.1
- kvm-ide-fix-halted-IO-segfault-at-reset.patch [bz#1393042]
- kvm-hw-i386-regenerate-checked-in-AML-payload-RHEL-only.patch [bz#1392027]
- kvm-SPEC-file-flip-the-build-from-IASL-to-checked-in-AML.patch [bz#1392027]
- Resolves: bz#1392027
  (shutdown rhel 5.11 guest failed and stop at "system halted")
- Resolves: bz#1393042
  (system_reset should clear pending request for error (IDE))
* Tue Sep 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-126.el7
- kvm-virtio-recalculate-vq-inuse-after-migration.patch [bz#1376542]
- Resolves: bz#1376542