a83cc2
From 80e9b92048e6fe7c7aef0e64cbc0f855bd3a6272 Mon Sep 17 00:00:00 2001
a83cc2
From: Miroslav Rezanina <mrezanin@redhat.com>
a83cc2
Date: Fri, 11 Jan 2019 09:54:45 +0100
a83cc2
Subject: Machine type related general changes
a83cc2
a83cc2
This patch is first part of original "Add RHEL machine types" patch we
a83cc2
split to allow easier review. It contains changes not related to any
a83cc2
architecture.
a83cc2
a83cc2
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
a83cc2
---
a83cc2
 hw/acpi/ich9.c               |  15 +++
a83cc2
 hw/acpi/piix4.c              |   5 +-
a83cc2
 hw/arm/virt.c                |   2 +-
a83cc2
 hw/char/serial.c             |  16 +++
a83cc2
 hw/core/machine.c            | 251 +++++++++++++++++++++++++++++++++++
a83cc2
 hw/display/vga-isa.c         |   2 +-
a83cc2
 hw/i386/pc_piix.c            |   2 +
a83cc2
 hw/i386/pc_q35.c             |   2 +
a83cc2
 hw/net/e1000e.c              |  21 +++
a83cc2
 hw/net/rtl8139.c             |   4 +-
a83cc2
 hw/rtc/mc146818rtc.c         |   6 +
a83cc2
 hw/smbios/smbios.c           |  46 ++++++-
a83cc2
 hw/timer/i8254_common.c      |   2 +-
a83cc2
 hw/usb/hcd-uhci.c            |   4 +-
a83cc2
 hw/usb/hcd-xhci-pci.c        |  59 ++++++--
a83cc2
 hw/usb/hcd-xhci-pci.h        |   1 +
a83cc2
 hw/usb/hcd-xhci.c            |  20 +++
a83cc2
 hw/usb/hcd-xhci.h            |   2 +
a83cc2
 include/hw/acpi/ich9.h       |   3 +
a83cc2
 include/hw/boards.h          |  33 +++++
a83cc2
 include/hw/firmware/smbios.h |   5 +-
a83cc2
 include/hw/i386/pc.h         |   3 +
a83cc2
 include/hw/usb.h             |   3 +
a83cc2
 migration/migration.c        |   2 +
a83cc2
 migration/migration.h        |   5 +
a83cc2
 25 files changed, 489 insertions(+), 25 deletions(-)
a83cc2
a83cc2
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
a83cc2
index 7f01fad64c..33b0c6e33c 100644
a83cc2
--- a/hw/acpi/ich9.c
a83cc2
+++ b/hw/acpi/ich9.c
a83cc2
@@ -369,6 +369,18 @@ static void ich9_pm_set_enable_tco(Object *obj, bool value, Error **errp)
a83cc2
     s->pm.enable_tco = value;
a83cc2
 }
a83cc2
 
a83cc2
+static bool ich9_pm_get_force_rev1_fadt(Object *obj, Error **errp)
a83cc2
+{
a83cc2
+    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
a83cc2
+    return s->pm.force_rev1_fadt;
a83cc2
+}
a83cc2
+
a83cc2
+static void ich9_pm_set_force_rev1_fadt(Object *obj, bool value, Error **errp)
a83cc2
+{
a83cc2
+    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
a83cc2
+    s->pm.force_rev1_fadt = value;
a83cc2
+}
a83cc2
+
a83cc2
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
a83cc2
 {
a83cc2
     static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
a83cc2
@@ -391,6 +403,9 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
a83cc2
     object_property_add_bool(obj, "cpu-hotplug-legacy",
a83cc2
                              ich9_pm_get_cpu_hotplug_legacy,
a83cc2
                              ich9_pm_set_cpu_hotplug_legacy);
a83cc2
+    object_property_add_bool(obj, "__com.redhat_force-rev1-fadt",
a83cc2
+                             ich9_pm_get_force_rev1_fadt,
a83cc2
+                             ich9_pm_set_force_rev1_fadt);
a83cc2
     object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S3_DISABLED,
a83cc2
                                   &pm->disable_s3, OBJ_PROP_FLAG_READWRITE);
a83cc2
     object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S4_DISABLED,
a83cc2
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
a83cc2
index 8f8b0e95e5..9865d1a349 100644
a83cc2
--- a/hw/acpi/piix4.c
a83cc2
+++ b/hw/acpi/piix4.c
a83cc2
@@ -278,6 +278,7 @@ static const VMStateDescription vmstate_acpi = {
a83cc2
     .name = "piix4_pm",
a83cc2
     .version_id = 3,
a83cc2
     .minimum_version_id = 3,
a83cc2
+    .minimum_version_id = 2,
a83cc2
     .post_load = vmstate_acpi_post_load,
a83cc2
     .fields = (VMStateField[]) {
a83cc2
         VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
a83cc2
@@ -643,8 +644,8 @@ static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
a83cc2
 
a83cc2
 static Property piix4_pm_properties[] = {
a83cc2
     DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
a83cc2
-    DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
a83cc2
-    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
a83cc2
+    DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 1),
a83cc2
+    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 1),
a83cc2
     DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
a83cc2
     DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
a83cc2
                      use_acpi_hotplug_bridge, true),
a83cc2
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
a83cc2
index 9f01d9041b..f904d3e98e 100644
a83cc2
--- a/hw/arm/virt.c
a83cc2
+++ b/hw/arm/virt.c
a83cc2
@@ -1522,7 +1522,7 @@ static void virt_build_smbios(VirtMachineState *vms)
a83cc2
 
a83cc2
     smbios_set_defaults("QEMU", product,
a83cc2
                         vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
a83cc2
-                        true, SMBIOS_ENTRY_POINT_30);
a83cc2
+                        true, NULL, NULL, SMBIOS_ENTRY_POINT_30);
a83cc2
 
a83cc2
     smbios_get_tables(MACHINE(vms), NULL, 0, &smbios_tables, &smbios_tables_len,
a83cc2
                       &smbios_anchor, &smbios_anchor_len);
a83cc2
diff --git a/hw/char/serial.c b/hw/char/serial.c
a83cc2
index bc2e322970..cc378142a3 100644
a83cc2
--- a/hw/char/serial.c
a83cc2
+++ b/hw/char/serial.c
a83cc2
@@ -37,6 +37,7 @@
a83cc2
 #include "trace.h"
a83cc2
 #include "hw/qdev-properties.h"
a83cc2
 #include "hw/qdev-properties-system.h"
a83cc2
+#include "migration/migration.h"
a83cc2
 
a83cc2
 #define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
a83cc2
 
a83cc2
@@ -689,6 +690,9 @@ static int serial_post_load(void *opaque, int version_id)
a83cc2
 static bool serial_thr_ipending_needed(void *opaque)
a83cc2
 {
a83cc2
     SerialState *s = opaque;
a83cc2
+    if (migrate_pre_2_2) {
a83cc2
+        return false;
a83cc2
+    }
a83cc2
 
a83cc2
     if (s->ier & UART_IER_THRI) {
a83cc2
         bool expected_value = ((s->iir & UART_IIR_ID) == UART_IIR_THRI);
a83cc2
@@ -770,6 +774,10 @@ static const VMStateDescription vmstate_serial_xmit_fifo = {
a83cc2
 static bool serial_fifo_timeout_timer_needed(void *opaque)
a83cc2
 {
a83cc2
     SerialState *s = (SerialState *)opaque;
a83cc2
+    if (migrate_pre_2_2) {
a83cc2
+        return false;
a83cc2
+    }
a83cc2
+
a83cc2
     return timer_pending(s->fifo_timeout_timer);
a83cc2
 }
a83cc2
 
a83cc2
@@ -787,6 +795,10 @@ static const VMStateDescription vmstate_serial_fifo_timeout_timer = {
a83cc2
 static bool serial_timeout_ipending_needed(void *opaque)
a83cc2
 {
a83cc2
     SerialState *s = (SerialState *)opaque;
a83cc2
+    if (migrate_pre_2_2) {
a83cc2
+        return false;
a83cc2
+    }
a83cc2
+
a83cc2
     return s->timeout_ipending != 0;
a83cc2
 }
a83cc2
 
a83cc2
@@ -804,6 +816,10 @@ static const VMStateDescription vmstate_serial_timeout_ipending = {
a83cc2
 static bool serial_poll_needed(void *opaque)
a83cc2
 {
a83cc2
     SerialState *s = (SerialState *)opaque;
a83cc2
+    if (migrate_pre_2_2) {
a83cc2
+        return false;
a83cc2
+    }
a83cc2
+
a83cc2
     return s->poll_msl >= 0;
a83cc2
 }
a83cc2
 
a83cc2
diff --git a/hw/core/machine.c b/hw/core/machine.c
a83cc2
index 40def78183..848e7fdff6 100644
a83cc2
--- a/hw/core/machine.c
a83cc2
+++ b/hw/core/machine.c
a83cc2
@@ -36,6 +36,257 @@
a83cc2
 #include "hw/virtio/virtio.h"
a83cc2
 #include "hw/virtio/virtio-pci.h"
a83cc2
 
a83cc2
+/*
a83cc2
+ * Mostly the same as hw_compat_5_2
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_8_4[] = {
a83cc2
+    /* hw_compat_rhel_8_4 from hw_compat_5_2 */
a83cc2
+    { "ICH9-LPC", "smm-compat", "on"},
a83cc2
+    /* hw_compat_rhel_8_4 from hw_compat_5_2 */
a83cc2
+    { "PIIX4_PM", "smm-compat", "on"},
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_8_4_len = G_N_ELEMENTS(hw_compat_rhel_8_4);
a83cc2
+
a83cc2
+/*
a83cc2
+ * Mostly the same as hw_compat_5_1
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_8_3[] = {
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "vhost-scsi", "num_queues", "1"},
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "vhost-user-blk", "num-queues", "1"},
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "vhost-user-scsi", "num_queues", "1"},
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "virtio-blk-device", "num-queues", "1"},
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "virtio-scsi-device", "num_queues", "1"},
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "nvme", "use-intel-id", "on"},
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */
a83cc2
+    /* hw_compat_rhel_8_3 bz 1912846 */
a83cc2
+    { "pci-xhci", "x-rh-late-msi-cap", "off" },
a83cc2
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
a83cc2
+    { "virtio-pci", "x-ats-page-aligned", "off"},
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_8_3_len = G_N_ELEMENTS(hw_compat_rhel_8_3);
a83cc2
+
a83cc2
+/*
a83cc2
+ * The same as hw_compat_4_2 + hw_compat_5_0
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_8_2[] = {
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "virtio-blk-device", "queue-size", "128"},
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "virtio-scsi-device", "virtqueue_size", "128"},
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "virtio-blk-device", "x-enable-wce-if-config-wce", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "virtio-blk-device", "seg-max-adjust", "off"},
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "virtio-scsi-device", "seg_max_adjust", "off"},
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "vhost-blk-device", "seg_max_adjust", "off"},
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "usb-host", "suppress-remote-wake", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "usb-redir", "suppress-remote-wake", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "qxl", "revision", "4" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "qxl-vga", "revision", "4" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "fw_cfg", "acpi-mr-restore", "false" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
a83cc2
+    { "virtio-device", "use-disabled-flag", "false" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
a83cc2
+    { "pci-host-bridge", "x-config-reg-migration-enabled", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
a83cc2
+    { "virtio-balloon-device", "page-poison", "false" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
a83cc2
+    { "vmport", "x-read-set-eax", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
a83cc2
+    { "vmport", "x-signal-unsupported-cmd", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
a83cc2
+    { "vmport", "x-report-vmx-type", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
a83cc2
+    { "vmport", "x-cmds-v2", "off" },
a83cc2
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
a83cc2
+    { "virtio-device", "x-disable-legacy-check", "true" },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_8_2_len = G_N_ELEMENTS(hw_compat_rhel_8_2);
a83cc2
+
a83cc2
+/*
a83cc2
+ * The same as hw_compat_4_1
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_8_1[] = {
a83cc2
+    /* hw_compat_rhel_8_1 from hw_compat_4_1 */
a83cc2
+    { "virtio-pci", "x-pcie-flr-init", "off" },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_8_1_len = G_N_ELEMENTS(hw_compat_rhel_8_1);
a83cc2
+
a83cc2
+/* The same as hw_compat_3_1
a83cc2
+ * format of array has been changed by:
a83cc2
+ *     6c36bddf5340 ("machine: Use shorter format for GlobalProperty arrays")
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_8_0[] = {
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "pcie-root-port", "x-speed", "2_5" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "pcie-root-port", "x-width", "1" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "tpm-crb", "ppi", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "tpm-tis", "ppi", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "usb-kbd", "serial", "42" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "usb-mouse", "serial", "42" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "usb-tablet", "serial", "42" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "virtio-blk-device", "discard", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
a83cc2
+    { "virtio-blk-device", "write-zeroes", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
a83cc2
+    { "VGA",            "edid", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
a83cc2
+    { "secondary-vga",  "edid", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
a83cc2
+    { "bochs-display",  "edid", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
a83cc2
+    { "virtio-vga",     "edid", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
a83cc2
+    { "virtio-gpu-device", "edid", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
a83cc2
+    { "virtio-device", "use-started", "false" },
a83cc2
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 - that was added in 4.1 */
a83cc2
+    { "pcie-root-port-base", "disable-acs", "true" },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_8_0_len = G_N_ELEMENTS(hw_compat_rhel_8_0);
a83cc2
+
a83cc2
+/* The same as hw_compat_3_0 + hw_compat_2_12
a83cc2
+ * except that
a83cc2
+ *   there's nothing in 3_0
a83cc2
+ *   migration.decompress-error-check=off was in 7.5 from bz 1584139
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_7_6[] = {
a83cc2
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
a83cc2
+    { "hda-audio", "use-timer", "false" },
a83cc2
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
a83cc2
+    { "cirrus-vga", "global-vmstate", "true" },
a83cc2
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
a83cc2
+    { "VGA", "global-vmstate", "true" },
a83cc2
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
a83cc2
+    { "vmware-svga", "global-vmstate", "true" },
a83cc2
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
a83cc2
+    { "qxl-vga", "global-vmstate",  "true" },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_7_6_len = G_N_ELEMENTS(hw_compat_rhel_7_6);
a83cc2
+
a83cc2
+/* The same as hw_compat_2_11 + hw_compat_2_10 */
a83cc2
+GlobalProperty hw_compat_rhel_7_5[] = {
a83cc2
+    /* hw_compat_rhel_7_5 from hw_compat_2_11 */
a83cc2
+    { "hpet", "hpet-offset-saved", "false" },
a83cc2
+    /* hw_compat_rhel_7_5 from hw_compat_2_11 */
a83cc2
+    { "virtio-blk-pci", "vectors", "2" },
a83cc2
+    /* hw_compat_rhel_7_5 from hw_compat_2_11 */
a83cc2
+    { "vhost-user-blk-pci", "vectors", "2" },
a83cc2
+    /* hw_compat_rhel_7_5 from hw_compat_2_11
a83cc2
+       bz 1608778 modified for our naming */
a83cc2
+    { "e1000-82540em", "migrate_tso_props", "off" },
a83cc2
+    /* hw_compat_rhel_7_5 from hw_compat_2_10 */
a83cc2
+    { "virtio-mouse-device", "wheel-axis", "false" },
a83cc2
+    /* hw_compat_rhel_7_5 from hw_compat_2_10 */
a83cc2
+    { "virtio-tablet-device", "wheel-axis", "false" },
a83cc2
+    { "cirrus-vga", "vgamem_mb", "16" },
a83cc2
+    { "migration", "decompress-error-check", "off" },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_7_5_len = G_N_ELEMENTS(hw_compat_rhel_7_5);
a83cc2
+
a83cc2
+/* Mostly like hw_compat_2_9 except
a83cc2
+ * x-mtu-bypass-backend, x-migrate-msix has already been
a83cc2
+ * backported to RHEL7.4. shpc was already on in 7.4.
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_7_4[] = {
a83cc2
+    { "intel-iommu", "pt", "off" },
a83cc2
+};
a83cc2
+
a83cc2
+const size_t hw_compat_rhel_7_4_len = G_N_ELEMENTS(hw_compat_rhel_7_4);
a83cc2
+/* Mostly like HW_COMPAT_2_6 + HW_COMPAT_2_7 + HW_COMPAT_2_8 except
a83cc2
+ * disable-modern, disable-legacy, page-per-vq have already been
a83cc2
+ * backported to RHEL7.3
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_7_3[] = {
a83cc2
+    { "virtio-mmio", "format_transport_address", "off" },
a83cc2
+    { "virtio-serial-device", "emergency-write", "off" },
a83cc2
+    { "ioapic", "version", "0x11" },
a83cc2
+    { "intel-iommu", "x-buggy-eim", "true" },
a83cc2
+    { "virtio-pci", "x-ignore-backend-features", "on" },
a83cc2
+    { "fw_cfg_mem", "x-file-slots", stringify(0x10) },
a83cc2
+    { "fw_cfg_io", "x-file-slots", stringify(0x10) },
a83cc2
+    { "pflash_cfi01", "old-multiple-chip-handling", "on" },
a83cc2
+    { TYPE_PCI_DEVICE, "x-pcie-extcap-init", "off" },
a83cc2
+    { "virtio-pci", "x-pcie-deverr-init", "off" },
a83cc2
+    { "virtio-pci", "x-pcie-lnkctl-init", "off" },
a83cc2
+    { "virtio-pci", "x-pcie-pm-init", "off" },
a83cc2
+    { "virtio-net-device", "x-mtu-bypass-backend", "off" },
a83cc2
+    { "e1000e", "__redhat_e1000e_7_3_intr_state", "on" },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_7_3_len = G_N_ELEMENTS(hw_compat_rhel_7_3);
a83cc2
+
a83cc2
+/* Mostly like hw_compat_2_4 + 2_3 but:
a83cc2
+ *  we don't need "any_layout" as it has been backported to 7.2
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_7_2[] = {
a83cc2
+        { "virtio-blk-device", "scsi", "true" },
a83cc2
+        { "e1000-82540em", "extra_mac_registers", "off" },
a83cc2
+        { "virtio-pci", "x-disable-pcie", "on" },
a83cc2
+        { "virtio-pci", "migrate-extra", "off" },
a83cc2
+        { "fw_cfg_mem", "dma_enabled", "off" },
a83cc2
+        { "fw_cfg_io", "dma_enabled", "off" },
a83cc2
+        { "isa-fdc", "fallback", "144" },
a83cc2
+        /* Optional because not all virtio-pci devices support legacy mode */
a83cc2
+        { "virtio-pci", "disable-modern", "on", .optional = true },
a83cc2
+        { "virtio-pci", "disable-legacy", "off", .optional = true },
a83cc2
+        { TYPE_PCI_DEVICE, "x-pcie-lnksta-dllla", "off" },
a83cc2
+        { "virtio-pci", "page-per-vq", "on" },
a83cc2
+        /* hw_compat_rhel_7_2 - introduced with 2.10.0 */
a83cc2
+        { "migration", "send-section-footer", "off" },
a83cc2
+        /* hw_compat_rhel_7_2 - introduced with 2.10.0 */
a83cc2
+        { "migration", "store-global-state", "off",
a83cc2
+        },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_7_2_len = G_N_ELEMENTS(hw_compat_rhel_7_2);
a83cc2
+
a83cc2
+/* Mostly like hw_compat_2_1 but:
a83cc2
+ *    we don't need virtio-scsi-pci since 7.0 already had that on
a83cc2
+ *
a83cc2
+ * RH: Note, qemu-extended-regs should have been enabled in the 7.1
a83cc2
+ * machine type, but was accidentally turned off in 7.2 onwards.
a83cc2
+ */
a83cc2
+GlobalProperty hw_compat_rhel_7_1[] = {
a83cc2
+    { "intel-hda-generic", "old_msi_addr", "on" },
a83cc2
+    { "VGA", "qemu-extended-regs", "off" },
a83cc2
+    { "secondary-vga", "qemu-extended-regs", "off" },
a83cc2
+    { "usb-mouse", "usb_version", stringify(1) },
a83cc2
+    { "usb-kbd", "usb_version", stringify(1) },
a83cc2
+    { "virtio-pci",  "virtio-pci-bus-master-bug-migration", "on" },
a83cc2
+    { "virtio-blk-pci", "any_layout", "off" },
a83cc2
+    { "virtio-balloon-pci", "any_layout", "off" },
a83cc2
+    { "virtio-serial-pci", "any_layout", "off" },
a83cc2
+    { "virtio-9p-pci", "any_layout", "off" },
a83cc2
+    { "virtio-rng-pci", "any_layout", "off" },
a83cc2
+    /* HW_COMPAT_RHEL7_1 - introduced with 2.10.0 */
a83cc2
+    { "migration", "send-configuration", "off" },
a83cc2
+};
a83cc2
+const size_t hw_compat_rhel_7_1_len = G_N_ELEMENTS(hw_compat_rhel_7_1);
a83cc2
+
a83cc2
 GlobalProperty hw_compat_5_2[] = {
a83cc2
     { "ICH9-LPC", "smm-compat", "on"},
a83cc2
     { "PIIX4_PM", "smm-compat", "on"},
a83cc2
diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
a83cc2
index 90851e730b..a91c5d7467 100644
a83cc2
--- a/hw/display/vga-isa.c
a83cc2
+++ b/hw/display/vga-isa.c
a83cc2
@@ -85,7 +85,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
a83cc2
 }
a83cc2
 
a83cc2
 static Property vga_isa_properties[] = {
a83cc2
-    DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8),
a83cc2
+    DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 16),
a83cc2
     DEFINE_PROP_END_OF_LIST(),
a83cc2
 };
a83cc2
 
a83cc2
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
a83cc2
index 46cc951073..62433d8022 100644
a83cc2
--- a/hw/i386/pc_piix.c
a83cc2
+++ b/hw/i386/pc_piix.c
a83cc2
@@ -179,6 +179,8 @@ static void pc_init1(MachineState *machine,
a83cc2
         smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)",
a83cc2
                             mc->name, pcmc->smbios_legacy_mode,
a83cc2
                             pcmc->smbios_uuid_encoded,
a83cc2
+                            pcmc->smbios_stream_product,
a83cc2
+                            pcmc->smbios_stream_version,
a83cc2
                             SMBIOS_ENTRY_POINT_21);
a83cc2
     }
a83cc2
 
a83cc2
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
a83cc2
index 53450190f5..fce52ca70b 100644
a83cc2
--- a/hw/i386/pc_q35.c
a83cc2
+++ b/hw/i386/pc_q35.c
a83cc2
@@ -198,6 +198,8 @@ static void pc_q35_init(MachineState *machine)
a83cc2
         smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)",
a83cc2
                             mc->name, pcmc->smbios_legacy_mode,
a83cc2
                             pcmc->smbios_uuid_encoded,
a83cc2
+                            pcmc->smbios_stream_product,
a83cc2
+                            pcmc->smbios_stream_version,
a83cc2
                             SMBIOS_ENTRY_POINT_21);
a83cc2
     }
a83cc2
 
a83cc2
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
a83cc2
index a8a77eca95..6d39c1f1c4 100644
a83cc2
--- a/hw/net/e1000e.c
a83cc2
+++ b/hw/net/e1000e.c
a83cc2
@@ -80,6 +80,11 @@ struct E1000EState {
a83cc2
 
a83cc2
     E1000ECore core;
a83cc2
 
a83cc2
+    /* 7.3 had the intr_state field that was in the original e1000e code
a83cc2
+     * but that was removed prior to 2.7's release
a83cc2
+     */
a83cc2
+    bool redhat_7_3_intr_state_enable;
a83cc2
+    uint32_t redhat_7_3_intr_state;
a83cc2
 };
a83cc2
 
a83cc2
 #define E1000E_MMIO_IDX     0
a83cc2
@@ -95,6 +100,10 @@ struct E1000EState {
a83cc2
 #define E1000E_MSIX_TABLE   (0x0000)
a83cc2
 #define E1000E_MSIX_PBA     (0x2000)
a83cc2
 
a83cc2
+/* Values as in RHEL 7.3 build and original upstream */
a83cc2
+#define RH_E1000E_USE_MSI     BIT(0)
a83cc2
+#define RH_E1000E_USE_MSIX    BIT(1)
a83cc2
+
a83cc2
 static uint64_t
a83cc2
 e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size)
a83cc2
 {
a83cc2
@@ -306,6 +315,8 @@ e1000e_init_msix(E1000EState *s)
a83cc2
     } else {
a83cc2
         if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) {
a83cc2
             msix_uninit(d, &s->msix, &s->msix);
a83cc2
+        } else {
a83cc2
+            s->redhat_7_3_intr_state |= RH_E1000E_USE_MSIX;
a83cc2
         }
a83cc2
     }
a83cc2
 }
a83cc2
@@ -477,6 +488,8 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp)
a83cc2
     ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL);
a83cc2
     if (ret) {
a83cc2
         trace_e1000e_msi_init_fail(ret);
a83cc2
+    } else {
a83cc2
+        s->redhat_7_3_intr_state |= RH_E1000E_USE_MSI;
a83cc2
     }
a83cc2
 
a83cc2
     if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset,
a83cc2
@@ -600,6 +613,11 @@ static const VMStateDescription e1000e_vmstate_intr_timer = {
a83cc2
     VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0,                           \
a83cc2
                          e1000e_vmstate_intr_timer, E1000IntrDelayTimer)
a83cc2
 
a83cc2
+static bool rhel_7_3_check(void *opaque, int version_id)
a83cc2
+{
a83cc2
+    return ((E1000EState *)opaque)->redhat_7_3_intr_state_enable;
a83cc2
+}
a83cc2
+
a83cc2
 static const VMStateDescription e1000e_vmstate = {
a83cc2
     .name = "e1000e",
a83cc2
     .version_id = 1,
a83cc2
@@ -611,6 +629,7 @@ static const VMStateDescription e1000e_vmstate = {
a83cc2
         VMSTATE_MSIX(parent_obj, E1000EState),
a83cc2
 
a83cc2
         VMSTATE_UINT32(ioaddr, E1000EState),
a83cc2
+        VMSTATE_UINT32_TEST(redhat_7_3_intr_state, E1000EState, rhel_7_3_check),
a83cc2
         VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState),
a83cc2
         VMSTATE_UINT8(core.rx_desc_len, E1000EState),
a83cc2
         VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState,
a83cc2
@@ -659,6 +678,8 @@ static PropertyInfo e1000e_prop_disable_vnet,
a83cc2
 
a83cc2
 static Property e1000e_properties[] = {
a83cc2
     DEFINE_NIC_PROPERTIES(E1000EState, conf),
a83cc2
+    DEFINE_PROP_BOOL("__redhat_e1000e_7_3_intr_state", E1000EState,
a83cc2
+                        redhat_7_3_intr_state_enable, false),
a83cc2
     DEFINE_PROP_SIGNED("disable_vnet_hdr", E1000EState, disable_vnet, false,
a83cc2
                         e1000e_prop_disable_vnet, bool),
a83cc2
     DEFINE_PROP_SIGNED("subsys_ven", E1000EState, subsys_ven,
a83cc2
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
a83cc2
index 90b4fc63ce..3ffb9dd22c 100644
a83cc2
--- a/hw/net/rtl8139.c
a83cc2
+++ b/hw/net/rtl8139.c
a83cc2
@@ -3179,7 +3179,7 @@ static int rtl8139_pre_save(void *opaque)
a83cc2
 
a83cc2
 static const VMStateDescription vmstate_rtl8139 = {
a83cc2
     .name = "rtl8139",
a83cc2
-    .version_id = 5,
a83cc2
+    .version_id = 4,
a83cc2
     .minimum_version_id = 3,
a83cc2
     .post_load = rtl8139_post_load,
a83cc2
     .pre_save  = rtl8139_pre_save,
a83cc2
@@ -3260,7 +3260,9 @@ static const VMStateDescription vmstate_rtl8139 = {
a83cc2
         VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
a83cc2
         VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
a83cc2
         VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
a83cc2
+#if 0 /* Disabled for Red Hat Enterprise Linux bz 1420195 */
a83cc2
         VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5),
a83cc2
+#endif
a83cc2
         VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State),
a83cc2
         VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
a83cc2
 
a83cc2
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
a83cc2
index 5d0fcacd0c..4a2e52031b 100644
a83cc2
--- a/hw/rtc/mc146818rtc.c
a83cc2
+++ b/hw/rtc/mc146818rtc.c
a83cc2
@@ -44,6 +44,7 @@
a83cc2
 #include "qapi/visitor.h"
a83cc2
 #include "exec/address-spaces.h"
a83cc2
 #include "hw/rtc/mc146818rtc_regs.h"
a83cc2
+#include "migration/migration.h"
a83cc2
 
a83cc2
 #ifdef TARGET_I386
a83cc2
 #include "qapi/qapi-commands-misc-target.h"
a83cc2
@@ -822,6 +823,11 @@ static int rtc_post_load(void *opaque, int version_id)
a83cc2
 static bool rtc_irq_reinject_on_ack_count_needed(void *opaque)
a83cc2
 {
a83cc2
     RTCState *s = (RTCState *)opaque;
a83cc2
+
a83cc2
+    if (migrate_pre_2_2) {
a83cc2
+        return false;
a83cc2
+    }
a83cc2
+
a83cc2
     return s->irq_reinject_on_ack_count != 0;
a83cc2
 }
a83cc2
 
a83cc2
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
a83cc2
index f22c4f5b73..a305a4bcea 100644
a83cc2
--- a/hw/smbios/smbios.c
a83cc2
+++ b/hw/smbios/smbios.c
a83cc2
@@ -56,6 +56,9 @@ static bool smbios_legacy = true;
a83cc2
 static bool smbios_uuid_encoded = true;
a83cc2
 /* end: legacy structures & constants for <= 2.0 machines */
a83cc2
 
a83cc2
+/* Set to true for modern Windows 10 HardwareID-6 compat */
a83cc2
+static bool smbios_type2_required;
a83cc2
+
a83cc2
 
a83cc2
 uint8_t *smbios_tables;
a83cc2
 size_t smbios_tables_len;
a83cc2
@@ -570,7 +573,7 @@ static void smbios_build_type_1_table(void)
a83cc2
 
a83cc2
 static void smbios_build_type_2_table(void)
a83cc2
 {
a83cc2
-    SMBIOS_BUILD_TABLE_PRE(2, 0x200, false); /* optional */
a83cc2
+    SMBIOS_BUILD_TABLE_PRE(2, 0x200, smbios_type2_required);
a83cc2
 
a83cc2
     SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer);
a83cc2
     SMBIOS_TABLE_SET_STR(2, product_str, type2.product);
a83cc2
@@ -792,7 +795,10 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
a83cc2
 
a83cc2
 void smbios_set_defaults(const char *manufacturer, const char *product,
a83cc2
                          const char *version, bool legacy_mode,
a83cc2
-                         bool uuid_encoded, SmbiosEntryPointType ep_type)
a83cc2
+                         bool uuid_encoded,
a83cc2
+                         const char *stream_product,
a83cc2
+                         const char *stream_version,
a83cc2
+                         SmbiosEntryPointType ep_type)
a83cc2
 {
a83cc2
     smbios_have_defaults = true;
a83cc2
     smbios_legacy = legacy_mode;
a83cc2
@@ -813,11 +819,45 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
a83cc2
         g_free(smbios_entries);
a83cc2
     }
a83cc2
 
a83cc2
+    /*
a83cc2
+     * If @stream_product & @stream_version are non-NULL, then
a83cc2
+     * we're following rules for new Windows driver support.
a83cc2
+     * The data we have to report is defined in this doc:
a83cc2
+     *
a83cc2
+     * https://docs.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer
a83cc2
+     *
a83cc2
+     * The Windows drivers are written to expect use of the
a83cc2
+     * scheme documented as "HardwareID-6" against Windows 10,
a83cc2
+     * which uses SMBIOS System (Type 1) and Base Board (Type 2)
a83cc2
+     * tables and will match on
a83cc2
+     *
a83cc2
+     *   System Manufacturer = Red Hat     (@manufacturer)
a83cc2
+     *   System SKU Number = 8.2.0         (@stream_version)
a83cc2
+     *   Baseboard Manufacturer = Red Hat  (@manufacturer)
a83cc2
+     *   Baseboard Product = RHEL-AV       (@stream_product)
a83cc2
+     *
a83cc2
+     * NB, SKU must be changed with each RHEL-AV release
a83cc2
+     *
a83cc2
+     * Other fields can be freely used by applications using
a83cc2
+     * QEMU. For example apps can use the "System product"
a83cc2
+     * and "System version" to identify themselves.
a83cc2
+     *
a83cc2
+     * We get 'System Manufacturer' and 'Baseboard Manufacturer'
a83cc2
+     */
a83cc2
     SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
a83cc2
     SMBIOS_SET_DEFAULT(type1.product, product);
a83cc2
     SMBIOS_SET_DEFAULT(type1.version, version);
a83cc2
+    SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux");
a83cc2
+    if (stream_version != NULL) {
a83cc2
+        SMBIOS_SET_DEFAULT(type1.sku, stream_version);
a83cc2
+    }
a83cc2
     SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
a83cc2
-    SMBIOS_SET_DEFAULT(type2.product, product);
a83cc2
+    if (stream_product != NULL) {
a83cc2
+        SMBIOS_SET_DEFAULT(type2.product, stream_product);
a83cc2
+        smbios_type2_required = true;
a83cc2
+    } else {
a83cc2
+        SMBIOS_SET_DEFAULT(type2.product, product);
a83cc2
+    }
a83cc2
     SMBIOS_SET_DEFAULT(type2.version, version);
a83cc2
     SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer);
a83cc2
     SMBIOS_SET_DEFAULT(type3.version, version);
a83cc2
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
a83cc2
index 050875b497..32935da46c 100644
a83cc2
--- a/hw/timer/i8254_common.c
a83cc2
+++ b/hw/timer/i8254_common.c
a83cc2
@@ -231,7 +231,7 @@ static const VMStateDescription vmstate_pit_common = {
a83cc2
     .pre_save = pit_dispatch_pre_save,
a83cc2
     .post_load = pit_dispatch_post_load,
a83cc2
     .fields = (VMStateField[]) {
a83cc2
-        VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
a83cc2
+        VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */
a83cc2
         VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
a83cc2
                              vmstate_pit_channel, PITChannelState),
a83cc2
         VMSTATE_INT64(channels[0].next_transition_time,
a83cc2
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
a83cc2
index 0cb02a6432..962a9622e5 100644
a83cc2
--- a/hw/usb/hcd-uhci.c
a83cc2
+++ b/hw/usb/hcd-uhci.c
a83cc2
@@ -1167,12 +1167,14 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
a83cc2
     UHCIState *s = UHCI(dev);
a83cc2
     uint8_t *pci_conf = s->dev.config;
a83cc2
     int i;
a83cc2
+    int irq_pin;
a83cc2
 
a83cc2
     pci_conf[PCI_CLASS_PROG] = 0x00;
a83cc2
     /* TODO: reset value should be 0. */
a83cc2
     pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
a83cc2
 
a83cc2
-    pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1);
a83cc2
+    irq_pin = u->info.irq_pin;
a83cc2
+    pci_config_set_interrupt_pin(pci_conf, irq_pin + 1);
a83cc2
 
a83cc2
     if (s->masterbus) {
a83cc2
         USBPort *ports[NB_PORTS];
a83cc2
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
a83cc2
index 9421734d0f..9bfe236a7d 100644
a83cc2
--- a/hw/usb/hcd-xhci-pci.c
a83cc2
+++ b/hw/usb/hcd-xhci-pci.c
a83cc2
@@ -101,6 +101,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
a83cc2
    return 0;
a83cc2
 }
a83cc2
 
a83cc2
+/* RH bz 1912846 */
a83cc2
+static bool usb_xhci_pci_add_msi(struct PCIDevice *dev, Error **errp)
a83cc2
+{
a83cc2
+    int ret;
a83cc2
+    Error *err = NULL;
a83cc2
+    XHCIPciState *s = XHCI_PCI(dev);
a83cc2
+
a83cc2
+    ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err;;
a83cc2
+    /*
a83cc2
+     * Any error other than -ENOTSUP(board's MSI support is broken)
a83cc2
+     * is a programming error
a83cc2
+     */
a83cc2
+    assert(!ret || ret == -ENOTSUP);
a83cc2
+    if (ret && s->msi == ON_OFF_AUTO_ON) {
a83cc2
+        /* Can't satisfy user's explicit msi=on request, fail */
a83cc2
+        error_append_hint(&err, "You have to use msi=auto (default) or "
a83cc2
+                "msi=off with this machine type.\n");
a83cc2
+        error_propagate(errp, err);
a83cc2
+        return true;
a83cc2
+    }
a83cc2
+    assert(!err || s->msi == ON_OFF_AUTO_AUTO);
a83cc2
+    /* With msi=auto, we fall back to MSI off silently */
a83cc2
+    error_free(err);
a83cc2
+
a83cc2
+    return false;
a83cc2
+}
a83cc2
+
a83cc2
 static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
a83cc2
 {
a83cc2
     int ret;
a83cc2
@@ -122,23 +149,12 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
a83cc2
         s->xhci.nec_quirks = true;
a83cc2
     }
a83cc2
 
a83cc2
-    if (s->msi != ON_OFF_AUTO_OFF) {
a83cc2
-        ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err;;
a83cc2
-        /*
a83cc2
-         * Any error other than -ENOTSUP(board's MSI support is broken)
a83cc2
-         * is a programming error
a83cc2
-         */
a83cc2
-        assert(!ret || ret == -ENOTSUP);
a83cc2
-        if (ret && s->msi == ON_OFF_AUTO_ON) {
a83cc2
-            /* Can't satisfy user's explicit msi=on request, fail */
a83cc2
-            error_append_hint(&err, "You have to use msi=auto (default) or "
a83cc2
-                    "msi=off with this machine type.\n");
a83cc2
+    if (s->msi != ON_OFF_AUTO_OFF && s->rh_late_msi_cap) {
a83cc2
+        /* This gives the behaviour from 5.2.0 onwards, lspci shows 90,a0,70 */
a83cc2
+        if (usb_xhci_pci_add_msi(dev, &err)) {
a83cc2
             error_propagate(errp, err);
a83cc2
             return;
a83cc2
         }
a83cc2
-        assert(!err || s->msi == ON_OFF_AUTO_AUTO);
a83cc2
-        /* With msi=auto, we fall back to MSI off silently */
a83cc2
-        error_free(err);
a83cc2
     }
a83cc2
     pci_register_bar(dev, 0,
a83cc2
                      PCI_BASE_ADDRESS_SPACE_MEMORY |
a83cc2
@@ -151,6 +167,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
a83cc2
         assert(ret > 0);
a83cc2
     }
a83cc2
 
a83cc2
+    /* RH bz 1912846 */
a83cc2
+    if (s->msi != ON_OFF_AUTO_OFF && !s->rh_late_msi_cap) {
a83cc2
+        /* This gives the older RH machine behaviour, lspci shows 90,70,a0 */
a83cc2
+        if (usb_xhci_pci_add_msi(dev, &err)) {
a83cc2
+            error_propagate(errp, err);
a83cc2
+            return;
a83cc2
+        }
a83cc2
+    }
a83cc2
     if (s->msix != ON_OFF_AUTO_OFF) {
a83cc2
         /* TODO check for errors, and should fail when msix=on */
a83cc2
         msix_init(dev, s->xhci.numintrs,
a83cc2
@@ -195,11 +219,18 @@ static void xhci_instance_init(Object *obj)
a83cc2
     qdev_alias_all_properties(DEVICE(&s->xhci), obj);
a83cc2
 }
a83cc2
 
a83cc2
+static Property xhci_pci_properties[] = {
a83cc2
+    /* RH bz 1912846 */
a83cc2
+    DEFINE_PROP_BOOL("x-rh-late-msi-cap", XHCIPciState, rh_late_msi_cap, true),
a83cc2
+    DEFINE_PROP_END_OF_LIST()
a83cc2
+};
a83cc2
+
a83cc2
 static void xhci_class_init(ObjectClass *klass, void *data)
a83cc2
 {
a83cc2
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
a83cc2
     DeviceClass *dc = DEVICE_CLASS(klass);
a83cc2
 
a83cc2
+    device_class_set_props(dc, xhci_pci_properties);
a83cc2
     dc->reset   = xhci_pci_reset;
a83cc2
     dc->vmsd    = &vmstate_xhci_pci;
a83cc2
     set_bit(DEVICE_CATEGORY_USB, dc->categories);
a83cc2
diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h
a83cc2
index c193f79443..086a1feb1e 100644
a83cc2
--- a/hw/usb/hcd-xhci-pci.h
a83cc2
+++ b/hw/usb/hcd-xhci-pci.h
a83cc2
@@ -39,6 +39,7 @@ typedef struct XHCIPciState {
a83cc2
     XHCIState xhci;
a83cc2
     OnOffAuto msi;
a83cc2
     OnOffAuto msix;
a83cc2
+    bool      rh_late_msi_cap;  /* bz 1912846 */
a83cc2
 } XHCIPciState;
a83cc2
 
a83cc2
 #endif
a83cc2
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
a83cc2
index 46212b1e69..6d1f278aad 100644
a83cc2
--- a/hw/usb/hcd-xhci.c
a83cc2
+++ b/hw/usb/hcd-xhci.c
a83cc2
@@ -3490,9 +3490,27 @@ static const VMStateDescription vmstate_xhci_slot = {
a83cc2
     }
a83cc2
 };
a83cc2
 
a83cc2
+static int xhci_event_pre_save(void *opaque)
a83cc2
+{
a83cc2
+    XHCIEvent *s = opaque;
a83cc2
+
a83cc2
+    s->cve_2014_5263_a = ((uint8_t *)&s->type)[0];
a83cc2
+    s->cve_2014_5263_b = ((uint8_t *)&s->type)[1];
a83cc2
+
a83cc2
+    return 0;
a83cc2
+}
a83cc2
+
a83cc2
+bool migrate_cve_2014_5263_xhci_fields;
a83cc2
+
a83cc2
+static bool xhci_event_cve_2014_5263(void *opaque, int version_id)
a83cc2
+{
a83cc2
+    return migrate_cve_2014_5263_xhci_fields;
a83cc2
+}
a83cc2
+
a83cc2
 static const VMStateDescription vmstate_xhci_event = {
a83cc2
     .name = "xhci-event",
a83cc2
     .version_id = 1,
a83cc2
+    .pre_save = xhci_event_pre_save,
a83cc2
     .fields = (VMStateField[]) {
a83cc2
         VMSTATE_UINT32(type,   XHCIEvent),
a83cc2
         VMSTATE_UINT32(ccode,  XHCIEvent),
a83cc2
@@ -3501,6 +3519,8 @@ static const VMStateDescription vmstate_xhci_event = {
a83cc2
         VMSTATE_UINT32(flags,  XHCIEvent),
a83cc2
         VMSTATE_UINT8(slotid,  XHCIEvent),
a83cc2
         VMSTATE_UINT8(epid,    XHCIEvent),
a83cc2
+        VMSTATE_UINT8_TEST(cve_2014_5263_a, XHCIEvent, xhci_event_cve_2014_5263),
a83cc2
+        VMSTATE_UINT8_TEST(cve_2014_5263_b, XHCIEvent, xhci_event_cve_2014_5263),
a83cc2
         VMSTATE_END_OF_LIST()
a83cc2
     }
a83cc2
 };
a83cc2
diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h
a83cc2
index 7bba361f3b..f450ffd13b 100644
a83cc2
--- a/hw/usb/hcd-xhci.h
a83cc2
+++ b/hw/usb/hcd-xhci.h
a83cc2
@@ -149,6 +149,8 @@ typedef struct XHCIEvent {
a83cc2
     uint32_t flags;
a83cc2
     uint8_t slotid;
a83cc2
     uint8_t epid;
a83cc2
+    uint8_t cve_2014_5263_a;
a83cc2
+    uint8_t cve_2014_5263_b;
a83cc2
 } XHCIEvent;
a83cc2
 
a83cc2
 typedef struct XHCIInterrupter {
a83cc2
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
a83cc2
index df519e40b5..e1ecfbaf1f 100644
a83cc2
--- a/include/hw/acpi/ich9.h
a83cc2
+++ b/include/hw/acpi/ich9.h
a83cc2
@@ -62,6 +62,9 @@ typedef struct ICH9LPCPMRegs {
a83cc2
     bool smm_compat;
a83cc2
     bool enable_tco;
a83cc2
     TCOIORegs tco_regs;
a83cc2
+
a83cc2
+    /* RH addition, see bz 1489800 */
a83cc2
+    bool force_rev1_fadt;
a83cc2
 } ICH9LPCPMRegs;
a83cc2
 
a83cc2
 #define ACPI_PM_PROP_TCO_ENABLED "enable_tco"
a83cc2
diff --git a/include/hw/boards.h b/include/hw/boards.h
a83cc2
index ad6c8fd537..2d7a65724a 100644
a83cc2
--- a/include/hw/boards.h
a83cc2
+++ b/include/hw/boards.h
a83cc2
@@ -413,4 +413,37 @@ extern const size_t hw_compat_2_2_len;
a83cc2
 extern GlobalProperty hw_compat_2_1[];
a83cc2
 extern const size_t hw_compat_2_1_len;
a83cc2
 
a83cc2
+extern GlobalProperty hw_compat_rhel_8_4[];
a83cc2
+extern const size_t hw_compat_rhel_8_4_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_8_3[];
a83cc2
+extern const size_t hw_compat_rhel_8_3_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_8_2[];
a83cc2
+extern const size_t hw_compat_rhel_8_2_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_8_1[];
a83cc2
+extern const size_t hw_compat_rhel_8_1_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_8_0[];
a83cc2
+extern const size_t hw_compat_rhel_8_0_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_7_6[];
a83cc2
+extern const size_t hw_compat_rhel_7_6_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_7_5[];
a83cc2
+extern const size_t hw_compat_rhel_7_5_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_7_4[];
a83cc2
+extern const size_t hw_compat_rhel_7_4_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_7_3[];
a83cc2
+extern const size_t hw_compat_rhel_7_3_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_7_2[];
a83cc2
+extern const size_t hw_compat_rhel_7_2_len;
a83cc2
+
a83cc2
+extern GlobalProperty hw_compat_rhel_7_1[];
a83cc2
+extern const size_t hw_compat_rhel_7_1_len;
a83cc2
+
a83cc2
 #endif
a83cc2
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
a83cc2
index 02a0ced0a0..67e38a1b13 100644
a83cc2
--- a/include/hw/firmware/smbios.h
a83cc2
+++ b/include/hw/firmware/smbios.h
a83cc2
@@ -267,7 +267,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp);
a83cc2
 void smbios_set_cpuid(uint32_t version, uint32_t features);
a83cc2
 void smbios_set_defaults(const char *manufacturer, const char *product,
a83cc2
                          const char *version, bool legacy_mode,
a83cc2
-                         bool uuid_encoded, SmbiosEntryPointType ep_type);
a83cc2
+                         bool uuid_encoded,
a83cc2
+                         const char *stream_product,
a83cc2
+                         const char *stream_version,
a83cc2
+                         SmbiosEntryPointType ep_type);
a83cc2
 uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length);
a83cc2
 void smbios_get_tables(MachineState *ms,
a83cc2
                        const struct smbios_phys_mem_area *mem_array,
a83cc2
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
a83cc2
index dcf060b791..93c012ac95 100644
a83cc2
--- a/include/hw/i386/pc.h
a83cc2
+++ b/include/hw/i386/pc.h
a83cc2
@@ -107,6 +107,9 @@ struct PCMachineClass {
a83cc2
     bool smbios_defaults;
a83cc2
     bool smbios_legacy_mode;
a83cc2
     bool smbios_uuid_encoded;
a83cc2
+    /* New fields needed for Windows HardwareID-6 matching */
a83cc2
+    const char *smbios_stream_product;
a83cc2
+    const char *smbios_stream_version;
a83cc2
 
a83cc2
     /* RAM / address space compat: */
a83cc2
     bool gigabyte_align;
a83cc2
diff --git a/include/hw/usb.h b/include/hw/usb.h
a83cc2
index 436e07b304..edb2cd94b6 100644
a83cc2
--- a/include/hw/usb.h
a83cc2
+++ b/include/hw/usb.h
a83cc2
@@ -577,4 +577,7 @@ void usb_pcap_init(FILE *fp);
a83cc2
 void usb_pcap_ctrl(USBPacket *p, bool setup);
a83cc2
 void usb_pcap_data(USBPacket *p, bool setup);
a83cc2
 
a83cc2
+/* hcd-xhci.c -- rhel7.0.0 machine type compatibility */
a83cc2
+extern bool migrate_cve_2014_5263_xhci_fields;
a83cc2
+
a83cc2
 #endif
a83cc2
diff --git a/migration/migration.c b/migration/migration.c
a83cc2
index 8ca034136b..4afc6069b6 100644
a83cc2
--- a/migration/migration.c
a83cc2
+++ b/migration/migration.c
a83cc2
@@ -167,6 +167,8 @@ INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
a83cc2
     MIGRATION_CAPABILITY_X_COLO,
a83cc2
     MIGRATION_CAPABILITY_VALIDATE_UUID);
a83cc2
 
a83cc2
+bool migrate_pre_2_2;
a83cc2
+
a83cc2
 /* When we add fault tolerance, we could have several
a83cc2
    migrations at once.  For now we don't need to add
a83cc2
    dynamic creation of migration */
a83cc2
diff --git a/migration/migration.h b/migration/migration.h
a83cc2
index db6708326b..1b6c69751c 100644
a83cc2
--- a/migration/migration.h
a83cc2
+++ b/migration/migration.h
a83cc2
@@ -368,6 +368,11 @@ bool check_dirty_bitmap_mig_alias_map(const BitmapMigrationNodeAliasList *bbm,
a83cc2
 void migrate_add_address(SocketAddress *address);
a83cc2
 
a83cc2
 int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
a83cc2
+/*
a83cc2
+ * Disables a load of subsections that were added in 2.2/rh7.2 for backwards
a83cc2
+ * migration compatibility.
a83cc2
+ */
a83cc2
+extern bool migrate_pre_2_2;
a83cc2
 
a83cc2
 #define qemu_ram_foreach_block \
a83cc2
   #warning "Use foreach_not_ignored_block in migration code"
a83cc2
-- 
a83cc2
2.27.0
a83cc2