5d360b
From aa757665c90914e69db3f16b11753c6d936b9bf0 Mon Sep 17 00:00:00 2001
840376
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
840376
Date: Thu, 17 Aug 2017 09:45:36 +0200
5d360b
Subject: [PATCH 3/4] Workaround rhel6 ctrl_guest_offloads machine type
840376
 mismatch
840376
840376
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
840376
Message-id: <20170817094536.12740-3-dgilbert@redhat.com>
840376
Patchwork-id: 76022
840376
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
5d360b
Bugzilla: 1480428
840376
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
840376
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
840376
RH-Acked-by: Thomas Huth <thuth@redhat.com>
840376
840376
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
840376
840376
RHEL6's 6.5 and 6.6 machine types enable the ctrl_guest_offloads
840376
feature on virtio-net-pci, unfortunately RHEL7's definition of the
840376
6.5 and 6.6 machine types are missing that flag.
840376
840376
This works around it by allowing an incoming migration with the
840376
guest flag set (for the bad machine types).
840376
840376
Fixing the machine type definitions would break migration from this
840376
version to an earlier 7.x.
840376
840376
Note: Restarting the VM after this import will still keep the old
840376
(broken) machine type and turn the feature off.
840376
840376
(cherry picked from commit 73fe1f6ffd03f49f4be4b0482fdd2611aa9a17ca)
840376
840376
          Heavy conflicts from backport, mostly around structure
840376
          of properties
840376
840376
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
840376
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
840376
---
840376
 hw/i386/pc_piix.c          |  9 +++++++++
840376
 hw/virtio/virtio.c         | 26 +++++++++++++++++++++++++-
840376
 include/hw/virtio/virtio.h |  1 +
840376
 3 files changed, 35 insertions(+), 1 deletion(-)
840376
840376
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
840376
index f4cf2b5..b043124 100644
840376
--- a/hw/i386/pc_piix.c
840376
+++ b/hw/i386/pc_piix.c
840376
@@ -908,8 +908,13 @@ static QEMUMachine pc_machine_rhel700 = {
840376
         .driver   = "virtio-net-pci",\
840376
         .property = "any_layout",\
840376
         .value    = "off",\
840376
+    },{\
840376
+        .driver = "virtio-net-device",\
840376
+        .property = "__com.redhat_rhel6_ctrl_guest_workaround", \
840376
+        .value = "on",\
840376
     }
840376
 
840376
+
840376
 static void pc_compat_rhel660(QEMUMachineInitArgs *args)
840376
 {
840376
     pc_compat_rhel700(args);
840376
@@ -1031,6 +1036,10 @@ static QEMUMachine pc_machine_rhel650 = {
840376
         .driver   = "virtio-net-pci",\
840376
         .property = "ctrl_mac_addr",\
840376
         .value    = "off",\
840376
+    },{\
840376
+        .driver   = "virtio-net-device",\
840376
+        .property = "__com.redhat_rhel6_ctrl_guest_workaround", \
840376
+        .value    = "off",\
840376
     }
840376
 
840376
 static void pc_compat_rhel640(QEMUMachineInitArgs *args)
840376
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
840376
index fe6b032..e3af5ae 100644
840376
--- a/hw/virtio/virtio.c
840376
+++ b/hw/virtio/virtio.c
840376
@@ -18,6 +18,7 @@
840376
 #include "hw/virtio/virtio.h"
840376
 #include "qemu/atomic.h"
840376
 #include "hw/virtio/virtio-bus.h"
840376
+#include "include/hw/virtio/virtio-net.h"
840376
 
840376
 /* The alignment to use between consumer and producer parts of vring.
840376
  * x86 pagesize again. */
840376
@@ -888,8 +889,24 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val)
840376
     VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
840376
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
840376
     uint32_t supported_features = vbusk->get_features(qbus->parent);
840376
-    bool bad = (val & ~supported_features) != 0;
840376
+    bool bad;
840376
+    uint64_t ctrl_guest_mask = 1ull << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS;
840376
+
840376
+    if (vdev->rhel6_ctrl_guest_workaround && (val & ctrl_guest_mask) &&
840376
+          !(supported_features & ctrl_guest_mask)) {
840376
+        /*
840376
+         * This works around a mistake in the definition of the rhel6.[56].0
840376
+         * machinetypes, ctrl-guest-offload was not set in qemu-kvm for
840376
+         * those machine types, but is set on the rhel6 qemu-kvm-rhev build.
840376
+         * If an incoming rhel6 guest uses it then we need to allow it.
840376
+         * Note: There's a small race where a guest read the flag but didn't
840376
+         * declare it's useage yet.
840376
+         */
840376
+        fprintf(stderr, "RHEL6 ctrl_guest_offload workaround\n");
840376
+        supported_features |= ctrl_guest_mask;
840376
+    }
840376
 
840376
+    bad = (val & ~supported_features) != 0;
840376
     val &= supported_features;
840376
     if (k->set_features) {
840376
         k->set_features(vdev, val);
840376
@@ -1223,6 +1240,12 @@ static int virtio_device_exit(DeviceState *qdev)
840376
     return 0;
840376
 }
840376
 
840376
+static Property virtio_properties[] = {
840376
+    DEFINE_PROP_BOOL("__com.redhat_rhel6_ctrl_guest_workaround", VirtIODevice,
840376
+                     rhel6_ctrl_guest_workaround, false),
840376
+    DEFINE_PROP_END_OF_LIST(),
840376
+};
840376
+
840376
 static void virtio_device_class_init(ObjectClass *klass, void *data)
840376
 {
840376
     /* Set the default value here. */
840376
@@ -1230,6 +1253,7 @@ static void virtio_device_class_init(ObjectClass *klass, void *data)
840376
     dc->init = virtio_device_init;
840376
     dc->exit = virtio_device_exit;
840376
     dc->bus_type = TYPE_VIRTIO_BUS;
840376
+    dc->props = virtio_properties;
840376
 }
840376
 
840376
 static const TypeInfo virtio_device_info = {
840376
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
840376
index d9bfe4c..0c4e963 100644
840376
--- a/include/hw/virtio/virtio.h
840376
+++ b/include/hw/virtio/virtio.h
840376
@@ -121,6 +121,7 @@ struct VirtIODevice
840376
     bool vm_running;
840376
     VMChangeStateEntry *vmstate;
840376
     char *bus_name;
840376
+    bool rhel6_ctrl_guest_workaround;
840376
 };
840376
 
840376
 typedef struct VirtioDeviceClass {
840376
-- 
840376
1.8.3.1
840376