QEMU is a FAST! processor emulator
CentOS Sources
2017-09-05 840376c53405e4622409a378e1cebcbd161e8a13
import qemu-kvm-1.5.3-141.el7_4.2
2 files added
1 files modified
416 ■■■■■ changed files
SOURCES/kvm-Workaround-rhel6-ctrl_guest_offloads-machine-type-mi.patch 146 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-net-dynamic-network-offloads-configuration.patch 256 ●●●●● patch | view | raw | blame | history
SPECS/qemu-kvm.spec 14 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-Workaround-rhel6-ctrl_guest_offloads-machine-type-mi.patch
New file
@@ -0,0 +1,146 @@
From fa7ee2210a7da964b111b8d8e7a2639ad6219041 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Thu, 17 Aug 2017 09:45:36 +0200
Subject: [PATCH 2/2] Workaround rhel6 ctrl_guest_offloads machine type
 mismatch
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20170817094536.12740-3-dgilbert@redhat.com>
Patchwork-id: 76022
O-Subject: [RHEL-7.5/7.4.z/7.3.z/7.2.z qemu-kvm PATCH v2 2/2] Workaround rhel6 ctrl_guest_offloads machine type mismatch
Bugzilla: 1482468
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
RHEL6's 6.5 and 6.6 machine types enable the ctrl_guest_offloads
feature on virtio-net-pci, unfortunately RHEL7's definition of the
6.5 and 6.6 machine types are missing that flag.
This works around it by allowing an incoming migration with the
guest flag set (for the bad machine types).
Fixing the machine type definitions would break migration from this
version to an earlier 7.x.
Note: Restarting the VM after this import will still keep the old
(broken) machine type and turn the feature off.
(cherry picked from commit 73fe1f6ffd03f49f4be4b0482fdd2611aa9a17ca)
          Heavy conflicts from backport, mostly around structure
          of properties
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/i386/pc_piix.c          |  9 +++++++++
 hw/virtio/virtio.c         | 26 +++++++++++++++++++++++++-
 include/hw/virtio/virtio.h |  1 +
 3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index f4cf2b5..b043124 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -908,8 +908,13 @@ static QEMUMachine pc_machine_rhel700 = {
         .driver   = "virtio-net-pci",\
         .property = "any_layout",\
         .value    = "off",\
+    },{\
+        .driver = "virtio-net-device",\
+        .property = "__com.redhat_rhel6_ctrl_guest_workaround", \
+        .value = "on",\
     }
+
 static void pc_compat_rhel660(QEMUMachineInitArgs *args)
 {
     pc_compat_rhel700(args);
@@ -1031,6 +1036,10 @@ static QEMUMachine pc_machine_rhel650 = {
         .driver   = "virtio-net-pci",\
         .property = "ctrl_mac_addr",\
         .value    = "off",\
+    },{\
+        .driver   = "virtio-net-device",\
+        .property = "__com.redhat_rhel6_ctrl_guest_workaround", \
+        .value    = "off",\
     }
 static void pc_compat_rhel640(QEMUMachineInitArgs *args)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index fe6b032..e3af5ae 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -18,6 +18,7 @@
 #include "hw/virtio/virtio.h"
 #include "qemu/atomic.h"
 #include "hw/virtio/virtio-bus.h"
+#include "include/hw/virtio/virtio-net.h"
 /* The alignment to use between consumer and producer parts of vring.
  * x86 pagesize again. */
@@ -888,8 +889,24 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val)
     VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
     uint32_t supported_features = vbusk->get_features(qbus->parent);
-    bool bad = (val & ~supported_features) != 0;
+    bool bad;
+    uint64_t ctrl_guest_mask = 1ull << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS;
+
+    if (vdev->rhel6_ctrl_guest_workaround && (val & ctrl_guest_mask) &&
+          !(supported_features & ctrl_guest_mask)) {
+        /*
+         * This works around a mistake in the definition of the rhel6.[56].0
+         * machinetypes, ctrl-guest-offload was not set in qemu-kvm for
+         * those machine types, but is set on the rhel6 qemu-kvm-rhev build.
+         * If an incoming rhel6 guest uses it then we need to allow it.
+         * Note: There's a small race where a guest read the flag but didn't
+         * declare it's useage yet.
+         */
+        fprintf(stderr, "RHEL6 ctrl_guest_offload workaround\n");
+        supported_features |= ctrl_guest_mask;
+    }
+    bad = (val & ~supported_features) != 0;
     val &= supported_features;
     if (k->set_features) {
         k->set_features(vdev, val);
@@ -1223,6 +1240,12 @@ static int virtio_device_exit(DeviceState *qdev)
     return 0;
 }
+static Property virtio_properties[] = {
+    DEFINE_PROP_BOOL("__com.redhat_rhel6_ctrl_guest_workaround", VirtIODevice,
+                     rhel6_ctrl_guest_workaround, false),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void virtio_device_class_init(ObjectClass *klass, void *data)
 {
     /* Set the default value here. */
@@ -1230,6 +1253,7 @@ static void virtio_device_class_init(ObjectClass *klass, void *data)
     dc->init = virtio_device_init;
     dc->exit = virtio_device_exit;
     dc->bus_type = TYPE_VIRTIO_BUS;
+    dc->props = virtio_properties;
 }
 static const TypeInfo virtio_device_info = {
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index d9bfe4c..0c4e963 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -121,6 +121,7 @@ struct VirtIODevice
     bool vm_running;
     VMChangeStateEntry *vmstate;
     char *bus_name;
+    bool rhel6_ctrl_guest_workaround;
 };
 typedef struct VirtioDeviceClass {
--
1.8.3.1
SOURCES/kvm-virtio-net-dynamic-network-offloads-configuration.patch
New file
@@ -0,0 +1,256 @@
From 4fcf18be2584d1e2071b55f0987169a715890cca Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Thu, 17 Aug 2017 09:45:35 +0200
Subject: [PATCH 1/2] virtio-net: dynamic network offloads configuration
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20170817094536.12740-2-dgilbert@redhat.com>
Patchwork-id: 76021
O-Subject: [RHEL-7.5/7.4.z/7.3.z/7.2.z qemu-kvm PATCH v2 1/2] virtio-net: dynamic network offloads configuration
Bugzilla: 1482468
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
From: Dmitry Fleytman <dfleytma@redhat.com>
Virtio-net driver currently negotiates network offloads
on startup via features mechanism and have no ability to
disable and re-enable offloads later.
This patch introduced a new control command that allows
to configure device network offloads state dynamically.
The patch also introduces a new feature flag
VIRTIO_NET_F_CTRL_GUEST_OFFLOADS.
Signed-off-by: Dmitry Fleytman <dfleytma@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 20130520081814.GA8162@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 644c98587d4ccc09e7592e1688e4e7fa363c5a75)
RHEL7.0 qemu-kvm only: Configure ctrl_guest_offloads off
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/net/virtio-net.c            | 99 +++++++++++++++++++++++++++++++++++-------
 include/hw/i386/pc.h           |  4 ++
 include/hw/virtio/virtio-net.h | 14 ++++++
 3 files changed, 102 insertions(+), 15 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3fde455..eb2feaf 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -477,6 +477,34 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
     return features;
 }
+static void virtio_net_apply_guest_offloads(VirtIONet *n)
+{
+    tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
+}
+
+static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
+{
+    static const uint64_t guest_offloads_mask =
+        (1ULL << VIRTIO_NET_F_GUEST_CSUM) |
+        (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
+        (1ULL << VIRTIO_NET_F_GUEST_TSO6) |
+        (1ULL << VIRTIO_NET_F_GUEST_ECN)  |
+        (1ULL << VIRTIO_NET_F_GUEST_UFO);
+
+    return guest_offloads_mask & features;
+}
+
+static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+    return virtio_net_guest_offloads_by_features(vdev->guest_features);
+}
+
 static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
@@ -487,12 +515,9 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
     virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
     if (n->has_vnet_hdr) {
-        tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
-                        (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
-                        (features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
+        n->curr_guest_offloads =
+            virtio_net_guest_offloads_by_features(features);
+        virtio_net_apply_guest_offloads(n);
     }
     for (i = 0;  i < n->max_queues; i++) {
@@ -547,6 +572,43 @@ static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
     return VIRTIO_NET_OK;
 }
+static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
+                                     struct iovec *iov, unsigned int iov_cnt)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+    uint64_t offloads;
+    size_t s;
+
+    if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
+        return VIRTIO_NET_ERR;
+    }
+
+    s = iov_to_buf(iov, iov_cnt, 0, &offloads, sizeof(offloads));
+    if (s != sizeof(offloads)) {
+        return VIRTIO_NET_ERR;
+    }
+
+    if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
+        uint64_t supported_offloads;
+
+        if (!n->has_vnet_hdr) {
+            return VIRTIO_NET_ERR;
+        }
+
+        supported_offloads = virtio_net_supported_guest_offloads(n);
+        if (offloads & ~supported_offloads) {
+            return VIRTIO_NET_ERR;
+        }
+
+        n->curr_guest_offloads = offloads;
+        virtio_net_apply_guest_offloads(n);
+
+        return VIRTIO_NET_OK;
+    } else {
+        return VIRTIO_NET_ERR;
+    }
+}
+
 static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
                                  struct iovec *iov, unsigned int iov_cnt)
 {
@@ -735,6 +797,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
             status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt);
         } else if (ctrl.class == VIRTIO_NET_CTRL_MQ) {
             status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt);
+        } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {
+            status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt);
         }
         s = iov_from_buf(elem.in_sg, elem.in_num, 0, &status, sizeof(status));
@@ -1253,6 +1317,10 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
             qemu_put_be32(f, n->vqs[i].tx_waiting);
         }
     }
+
+    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+        qemu_put_be64(f, n->curr_guest_offloads);
+    }
 }
 static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
@@ -1317,15 +1385,6 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
             error_report("virtio-net: saved image requires vnet_hdr=on");
             return -1;
         }
-
-        if (n->has_vnet_hdr) {
-            tap_set_offload(qemu_get_queue(n->nic)->peer,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
-        }
     }
     if (version_id >= 9) {
@@ -1364,6 +1423,16 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
         }
     }
+    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+        n->curr_guest_offloads = qemu_get_be64(f);
+    } else {
+        n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
+    }
+
+    if (peer_has_vnet_hdr(n)) {
+        virtio_net_apply_guest_offloads(n);
+    }
+
     virtio_net_set_queues(n);
     /* Find the first multicast entry in the saved MAC filter */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3b8f7d8..89bb458 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -318,6 +318,10 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
             .property = "vectors",\
             /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\
             .value    = stringify(0xFFFFFFFF),\
+        },{ \
+            .driver   = "virtio-net-pci", \
+            .property = "ctrl_guest_offloads", \
+            .value    = "off", \
         },{\
             .driver   = "e1000",\
             .property = "romfile",\
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index a02fc50..02fa5c5 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -31,6 +31,8 @@
 /* The feature bitmap for virtio net */
 #define VIRTIO_NET_F_CSUM       0       /* Host handles pkts w/ partial csum */
 #define VIRTIO_NET_F_GUEST_CSUM 1       /* Guest handles pkts w/ partial csum */
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Control channel offload
+                                         * configuration support */
 #define VIRTIO_NET_F_MAC        5       /* Host has given MAC address. */
 #define VIRTIO_NET_F_GSO        6       /* Host handles pkts w/ any GSO type */
 #define VIRTIO_NET_F_GUEST_TSO4 7       /* Guest can handle TSOv4 in. */
@@ -190,6 +192,7 @@ typedef struct VirtIONet {
     size_t config_size;
     char *netclient_name;
     char *netclient_type;
+    uint64_t curr_guest_offloads;
 } VirtIONet;
 #define VIRTIO_NET_CTRL_MAC    1
@@ -229,6 +232,15 @@ struct virtio_net_ctrl_mq {
  #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN        1
  #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX        0x8000
+/*
+ * Control network offloads
+ *
+ * Dynamic offloads are available with the
+ * VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS   5
+ #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET        0
+
 #define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
         DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
         DEFINE_PROP_BIT("any_layout", _state, _field, VIRTIO_F_ANY_LAYOUT, true), \
@@ -250,6 +262,8 @@ struct virtio_net_ctrl_mq {
         DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
         DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
         DEFINE_PROP_BIT("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
+        /* RHEL 7.0 qemu-kvm: ctrl_guest_offloads always configured off */ \
+        DEFINE_PROP_BIT("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, false), \
         DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, false)
 #define DEFINE_VIRTIO_NET_PROPERTIES(_state, _field)                           \
--
1.8.3.1
SPECS/qemu-kvm.spec
@@ -76,7 +76,7 @@
Summary: QEMU is a machine emulator and virtualizer
Name: %{pkgname}%{?pkgsuffix}
Version: 1.5.3
Release: 141%{?dist}.1
Release: 141%{?dist}.2
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 10
License: GPLv2+ and LGPLv2+ and BSD
@@ -3596,6 +3596,10 @@
Patch1770: kvm-nbd-Fix-regression-on-resiliency-to-port-scan.patch
# For bz#1468107 - CVE-2017-10664 qemu-kvm: Qemu: qemu-nbd: server breaks with SIGPIPE upon client abort [rhel-7.4.z]
Patch1771: kvm-qemu-nbd-Ignore-SIGPIPE.patch
# For bz#1482468 - KVM: windows guest migration from EL6 to EL7 fails. [rhel-7.4.z]
Patch1772: kvm-virtio-net-dynamic-network-offloads-configuration.patch
# For bz#1482468 - KVM: windows guest migration from EL6 to EL7 fails. [rhel-7.4.z]
Patch1773: kvm-Workaround-rhel6-ctrl_guest_offloads-machine-type-mi.patch
BuildRequires: zlib-devel
@@ -5545,6 +5549,8 @@
%patch1769 -p1
%patch1770 -p1
%patch1771 -p1
%patch1772 -p1
%patch1773 -p1
%build
buildarch="%{kvm_target}-softmmu"
@@ -5990,6 +5996,12 @@
%{_mandir}/man8/qemu-nbd.8*
%changelog
* Mon Aug 21 2017 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-141.el7_4.2
- kvm-virtio-net-dynamic-network-offloads-configuration.patch [bz#1482468]
- kvm-Workaround-rhel6-ctrl_guest_offloads-machine-type-mi.patch [bz#1482468]
- Resolves: bz#1482468
  (KVM: windows guest migration from EL6 to EL7 fails. [rhel-7.4.z])
* Tue Jul 11 2017 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-141.el7_4.1
- kvm-qemu-nbd-Ignore-SIGPIPE.patch [bz#1468107]
- Resolves: bz#1468107