From 7b3c2e676cd62e947e9b020bba9309a171e94c9e Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Thu, 9 Feb 2017 13:06:18 +0100
Subject: migcompat/e1000e: Work around 7.3 msi/intr_state field
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20170209130618.20328-1-dgilbert@redhat.com>
Patchwork-id: 73730
O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH 1/1] migcompat/e1000e: Work around 7.3 msi/intr_state field
Bugzilla: 1420216
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
bz: https://bugzilla.redhat.com/show_bug.cgi?id=1420216
brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=12518741
upstream: No, fixing downstream inconsistency
Our 7.3 e1000e model has an 'intr_state' field that's used
only in the cleanup of msi & msix.
e1000e was introducing in 2.7 but was backported to the 2.6 based
qemu-kvm-rhev 7.3 by backporting 6f3fbe4 and 103916.
During the 2.7rc's the migration structure was changed by
e0af5a0e8 and 66bf7d but we never pulled those into 7.3 which
removed the 'intr_state' field.
For compatibility add the field back (guarded by a property on 7.3)
and populate the values based on the source MSI state.
Since the flags were only used for cleanup I don't think
we need to pay attention to the value we receive.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
(cherry picked from commit 4ed53cd6a385c6dca4a088cf406d03165d17c28d)
(cherry picked from commit ee177ab97e10a60746ec59032d83aa5bd1a26445)
---
hw/net/e1000e.c | 21 +++++++++++++++++++++
include/hw/compat.h | 4 ++++
2 files changed, 25 insertions(+)
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index e849f79..f36f211 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -73,6 +73,11 @@ typedef struct E1000EState {
E1000ECore core;
+ /* 7.3 had the intr_state field that was in the original e1000e code
+ * but that was removed prior to 2.7's release
+ */
+ bool redhat_7_3_intr_state_enable;
+ uint32_t redhat_7_3_intr_state;
} E1000EState;
#define E1000E_MMIO_IDX 0
@@ -88,6 +93,10 @@ typedef struct E1000EState {
#define E1000E_MSIX_TABLE (0x0000)
#define E1000E_MSIX_PBA (0x2000)
+/* Values as in RHEL 7.3 build and original upstream */
+#define RH_E1000E_USE_MSI BIT(0)
+#define RH_E1000E_USE_MSIX BIT(1)
+
static uint64_t
e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size)
{
@@ -299,6 +308,8 @@ e1000e_init_msix(E1000EState *s)
} else {
if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) {
msix_uninit(d, &s->msix, &s->msix);
+ } else {
+ s->redhat_7_3_intr_state |= RH_E1000E_USE_MSIX;
}
}
}
@@ -465,6 +476,8 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp)
ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL);
if (ret) {
trace_e1000e_msi_init_fail(ret);
+ } else {
+ s->redhat_7_3_intr_state |= RH_E1000E_USE_MSI;
}
if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset,
@@ -586,6 +599,11 @@ static const VMStateDescription e1000e_vmstate_intr_timer = {
VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \
e1000e_vmstate_intr_timer, E1000IntrDelayTimer)
+static bool rhel_7_3_check(void *opaque, int version_id)
+{
+ return ((E1000EState *)opaque)->redhat_7_3_intr_state_enable;
+}
+
static const VMStateDescription e1000e_vmstate = {
.name = "e1000e",
.version_id = 1,
@@ -597,6 +615,7 @@ static const VMStateDescription e1000e_vmstate = {
VMSTATE_MSIX(parent_obj, E1000EState),
VMSTATE_UINT32(ioaddr, E1000EState),
+ VMSTATE_UINT32_TEST(redhat_7_3_intr_state, E1000EState, rhel_7_3_check),
VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState),
VMSTATE_UINT8(core.rx_desc_len, E1000EState),
VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState,
@@ -645,6 +664,8 @@ static PropertyInfo e1000e_prop_disable_vnet,
static Property e1000e_properties[] = {
DEFINE_NIC_PROPERTIES(E1000EState, conf),
+ DEFINE_PROP_BOOL("__redhat_e1000e_7_3_intr_state", E1000EState,
+ redhat_7_3_intr_state_enable, false),
DEFINE_PROP_DEFAULT("disable_vnet_hdr", E1000EState, disable_vnet, false,
e1000e_prop_disable_vnet, bool),
DEFINE_PROP_DEFAULT("subsys_ven", E1000EState, subsys_ven,
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 6f64306..66320b5 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -324,6 +324,10 @@
.driver = "virtio-pci",\
.property = "x-ignore-backend-features",\
.value = "on",\
+ },{ /* HW_COMPAT_RHEL7_3 */ \
+ .driver = "e1000e",\
+ .property = "__redhat_e1000e_7_3_intr_state",\
+ .value = "on",\
},
#endif /* HW_COMPAT_H */
--
1.8.3.1