Blob Blame History Raw
From fd2a04cf2221d8c541a70a66021c12a9b9c93aaa Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 11 Jan 2019 09:54:45 +0100
Subject: Machine type related general changes

This patch is first part of original "Add RHEL machine types" patch we
split to allow easier review. It contains changes not related to any
architecture.

Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>

Merged patches (6.1.0 RC1):
- f2fb42a3c6 redhat: add missing entries in hw_compat_rhel_8_4
- 1949ec258e hw/arm/virt: Disable PL011 clock migration through hw_compat_rhel_8_3

Merged patches (6.1.0):
- a3995e2eff Remove RHEL 7.0.0 machine type (only generic changes)
- ad3190a79b Remove RHEL 7.1.0 machine type (only generic changes)
- 84bbe15d4e Remove RHEL 7.2.0 machine type (only generic changes)
- 0215eb3356 Remove RHEL 7.3.0 machine types (only generic changes)
- af69d1ca6e Remove RHEL 7.4.0 machine types (only generic changes)
- 8f7a74ab78 Remove RHEL 7.5.0 machine types (only generic changes)
---
 hw/acpi/piix4.c              |   5 +-
 hw/arm/virt.c                |   2 +-
 hw/char/serial.c             |   4 +
 hw/core/machine.c            | 159 +++++++++++++++++++++++++++++++++++
 hw/display/vga-isa.c         |   2 +-
 hw/i386/pc_piix.c            |   2 +
 hw/i386/pc_q35.c             |   2 +
 hw/net/rtl8139.c             |   4 +-
 hw/rtc/mc146818rtc.c         |   2 +
 hw/smbios/smbios.c           |  46 +++++++++-
 hw/timer/i8254_common.c      |   2 +-
 hw/usb/hcd-uhci.c            |   4 +-
 hw/usb/hcd-xhci-pci.c        |  59 ++++++++++---
 hw/usb/hcd-xhci-pci.h        |   1 +
 include/hw/boards.h          |  18 ++++
 include/hw/firmware/smbios.h |   5 +-
 include/hw/i386/pc.h         |   3 +
 17 files changed, 295 insertions(+), 25 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 48f7a1edbc..af21cb4ac3 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -279,6 +279,7 @@ static const VMStateDescription vmstate_acpi = {
     .name = "piix4_pm",
     .version_id = 3,
     .minimum_version_id = 3,
+    .minimum_version_id = 2,
     .post_load = vmstate_acpi_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
@@ -644,8 +645,8 @@ static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
 
 static Property piix4_pm_properties[] = {
     DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
-    DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
-    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
+    DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 1),
+    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 1),
     DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
     DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
                      use_acpi_hotplug_bridge, true),
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 81eda46b0b..cd1a2d985d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1524,7 +1524,7 @@ static void virt_build_smbios(VirtMachineState *vms)
 
     smbios_set_defaults("QEMU", product,
                         vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
-                        true, SMBIOS_ENTRY_POINT_30);
+                        true, NULL, NULL, SMBIOS_ENTRY_POINT_30);
 
     smbios_get_tables(MACHINE(vms), NULL, 0,
                       &smbios_tables, &smbios_tables_len,
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 7061aacbce..8fa5ab1e8e 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -37,6 +37,7 @@
 #include "trace.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
+#include "migration/migration.h"
 
 #define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
 
@@ -770,6 +771,7 @@ static const VMStateDescription vmstate_serial_xmit_fifo = {
 static bool serial_fifo_timeout_timer_needed(void *opaque)
 {
     SerialState *s = (SerialState *)opaque;
+
     return timer_pending(s->fifo_timeout_timer);
 }
 
@@ -787,6 +789,7 @@ static const VMStateDescription vmstate_serial_fifo_timeout_timer = {
 static bool serial_timeout_ipending_needed(void *opaque)
 {
     SerialState *s = (SerialState *)opaque;
+
     return s->timeout_ipending != 0;
 }
 
@@ -804,6 +807,7 @@ static const VMStateDescription vmstate_serial_timeout_ipending = {
 static bool serial_poll_needed(void *opaque)
 {
     SerialState *s = (SerialState *)opaque;
+
     return s->poll_msl >= 0;
 }
 
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 54e040587d..d681a06a47 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -37,6 +37,165 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-pci.h"
 
+/*
+ * Mostly the same as hw_compat_5_2
+ */
+GlobalProperty hw_compat_rhel_8_4[] = {
+    /* hw_compat_rhel_8_4 from hw_compat_5_2 */
+    { "ICH9-LPC", "smm-compat", "on"},
+    /* hw_compat_rhel_8_4 from hw_compat_5_2 */
+    { "PIIX4_PM", "smm-compat", "on"},
+    /* hw_compat_rhel_8_4 from hw_compat_5_2 */
+    { "virtio-blk-device", "report-discard-granularity", "off" },
+    /* hw_compat_rhel_8_4 from hw_compat_5_2 */
+    { "virtio-net-pci", "vectors", "3"},
+};
+const size_t hw_compat_rhel_8_4_len = G_N_ELEMENTS(hw_compat_rhel_8_4);
+
+/*
+ * Mostly the same as hw_compat_5_1
+ */
+GlobalProperty hw_compat_rhel_8_3[] = {
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "vhost-scsi", "num_queues", "1"},
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "vhost-user-blk", "num-queues", "1"},
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "vhost-user-scsi", "num_queues", "1"},
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "virtio-blk-device", "num-queues", "1"},
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "virtio-scsi-device", "num_queues", "1"},
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "nvme", "use-intel-id", "on"},
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "pl011", "migrate-clk", "off" },
+    /* hw_compat_rhel_8_3 bz 1912846 */
+    { "pci-xhci", "x-rh-late-msi-cap", "off" },
+    /* hw_compat_rhel_8_3 from hw_compat_5_1 */
+    { "virtio-pci", "x-ats-page-aligned", "off"},
+};
+const size_t hw_compat_rhel_8_3_len = G_N_ELEMENTS(hw_compat_rhel_8_3);
+
+/*
+ * The same as hw_compat_4_2 + hw_compat_5_0
+ */
+GlobalProperty hw_compat_rhel_8_2[] = {
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "virtio-blk-device", "queue-size", "128"},
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "virtio-scsi-device", "virtqueue_size", "128"},
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "virtio-blk-device", "x-enable-wce-if-config-wce", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "virtio-blk-device", "seg-max-adjust", "off"},
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "virtio-scsi-device", "seg_max_adjust", "off"},
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "vhost-blk-device", "seg_max_adjust", "off"},
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "usb-host", "suppress-remote-wake", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "usb-redir", "suppress-remote-wake", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "qxl", "revision", "4" },
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "qxl-vga", "revision", "4" },
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "fw_cfg", "acpi-mr-restore", "false" },
+    /* hw_compat_rhel_8_2 from hw_compat_4_2 */
+    { "virtio-device", "use-disabled-flag", "false" },
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
+    { "pci-host-bridge", "x-config-reg-migration-enabled", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
+    { "virtio-balloon-device", "page-poison", "false" },
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
+    { "vmport", "x-read-set-eax", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
+    { "vmport", "x-signal-unsupported-cmd", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
+    { "vmport", "x-report-vmx-type", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
+    { "vmport", "x-cmds-v2", "off" },
+    /* hw_compat_rhel_8_2 from hw_compat_5_0 */
+    { "virtio-device", "x-disable-legacy-check", "true" },
+};
+const size_t hw_compat_rhel_8_2_len = G_N_ELEMENTS(hw_compat_rhel_8_2);
+
+/*
+ * The same as hw_compat_4_1
+ */
+GlobalProperty hw_compat_rhel_8_1[] = {
+    /* hw_compat_rhel_8_1 from hw_compat_4_1 */
+    { "virtio-pci", "x-pcie-flr-init", "off" },
+};
+const size_t hw_compat_rhel_8_1_len = G_N_ELEMENTS(hw_compat_rhel_8_1);
+
+/* The same as hw_compat_3_1
+ * format of array has been changed by:
+ *     6c36bddf5340 ("machine: Use shorter format for GlobalProperty arrays")
+ */
+GlobalProperty hw_compat_rhel_8_0[] = {
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "pcie-root-port", "x-speed", "2_5" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "pcie-root-port", "x-width", "1" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "tpm-crb", "ppi", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "tpm-tis", "ppi", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "usb-kbd", "serial", "42" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "usb-mouse", "serial", "42" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "usb-tablet", "serial", "42" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "virtio-blk-device", "discard", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 */
+    { "virtio-blk-device", "write-zeroes", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+    { "VGA",            "edid", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+    { "secondary-vga",  "edid", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+    { "bochs-display",  "edid", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+    { "virtio-vga",     "edid", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+    { "virtio-gpu-device", "edid", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+    { "virtio-device", "use-started", "false" },
+    /* hw_compat_rhel_8_0 from hw_compat_3_1 - that was added in 4.1 */
+    { "pcie-root-port-base", "disable-acs", "true" },
+};
+const size_t hw_compat_rhel_8_0_len = G_N_ELEMENTS(hw_compat_rhel_8_0);
+
+/* The same as hw_compat_3_0 + hw_compat_2_12
+ * except that
+ *   there's nothing in 3_0
+ *   migration.decompress-error-check=off was in 7.5 from bz 1584139
+ */
+GlobalProperty hw_compat_rhel_7_6[] = {
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
+    { "hda-audio", "use-timer", "false" },
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
+    { "cirrus-vga", "global-vmstate", "true" },
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
+    { "VGA", "global-vmstate", "true" },
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
+    { "vmware-svga", "global-vmstate", "true" },
+    /* hw_compat_rhel_7_6 from hw_compat_2_12 */
+    { "qxl-vga", "global-vmstate",  "true" },
+};
+const size_t hw_compat_rhel_7_6_len = G_N_ELEMENTS(hw_compat_rhel_7_6);
+
 GlobalProperty hw_compat_6_0[] = {
     { "gpex-pcihost", "allow-unmapped-accesses", "false" },
     { "i8042", "extended-state", "false"},
diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
index 90851e730b..a91c5d7467 100644
--- a/hw/display/vga-isa.c
+++ b/hw/display/vga-isa.c
@@ -85,7 +85,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
 }
 
 static Property vga_isa_properties[] = {
-    DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8),
+    DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 16),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 30b8bd6ea9..eebb4f3141 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -177,6 +177,8 @@ static void pc_init1(MachineState *machine,
         smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)",
                             mc->name, pcmc->smbios_legacy_mode,
                             pcmc->smbios_uuid_encoded,
+                            pcmc->smbios_stream_product,
+                            pcmc->smbios_stream_version,
                             SMBIOS_ENTRY_POINT_21);
     }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 04b4a4788d..e7724fd02c 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -199,6 +199,8 @@ static void pc_q35_init(MachineState *machine)
         smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)",
                             mc->name, pcmc->smbios_legacy_mode,
                             pcmc->smbios_uuid_encoded,
+                            pcmc->smbios_stream_product,
+                            pcmc->smbios_stream_version,
                             SMBIOS_ENTRY_POINT_21);
     }
 
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 90b4fc63ce..3ffb9dd22c 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3179,7 +3179,7 @@ static int rtl8139_pre_save(void *opaque)
 
 static const VMStateDescription vmstate_rtl8139 = {
     .name = "rtl8139",
-    .version_id = 5,
+    .version_id = 4,
     .minimum_version_id = 3,
     .post_load = rtl8139_post_load,
     .pre_save  = rtl8139_pre_save,
@@ -3260,7 +3260,9 @@ static const VMStateDescription vmstate_rtl8139 = {
         VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
         VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
         VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
+#if 0 /* Disabled for Red Hat Enterprise Linux bz 1420195 */
         VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5),
+#endif
         VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State),
         VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
 
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 4fbafddb22..6c42cc22cd 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -43,6 +43,7 @@
 #include "qapi/qapi-events-misc-target.h"
 #include "qapi/visitor.h"
 #include "hw/rtc/mc146818rtc_regs.h"
+#include "migration/migration.h"
 
 #ifdef TARGET_I386
 #include "qapi/qapi-commands-misc-target.h"
@@ -821,6 +822,7 @@ static int rtc_post_load(void *opaque, int version_id)
 static bool rtc_irq_reinject_on_ack_count_needed(void *opaque)
 {
     RTCState *s = (RTCState *)opaque;
+
     return s->irq_reinject_on_ack_count != 0;
 }
 
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 7397e56737..3a4bb894ba 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -57,6 +57,9 @@ static bool smbios_legacy = true;
 static bool smbios_uuid_encoded = true;
 /* end: legacy structures & constants for <= 2.0 machines */
 
+/* Set to true for modern Windows 10 HardwareID-6 compat */
+static bool smbios_type2_required;
+
 
 uint8_t *smbios_tables;
 size_t smbios_tables_len;
@@ -619,7 +622,7 @@ static void smbios_build_type_1_table(void)
 
 static void smbios_build_type_2_table(void)
 {
-    SMBIOS_BUILD_TABLE_PRE(2, 0x200, false); /* optional */
+    SMBIOS_BUILD_TABLE_PRE(2, 0x200, smbios_type2_required);
 
     SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer);
     SMBIOS_TABLE_SET_STR(2, product_str, type2.product);
@@ -888,7 +891,10 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
 
 void smbios_set_defaults(const char *manufacturer, const char *product,
                          const char *version, bool legacy_mode,
-                         bool uuid_encoded, SmbiosEntryPointType ep_type)
+                         bool uuid_encoded,
+                         const char *stream_product,
+                         const char *stream_version,
+                         SmbiosEntryPointType ep_type)
 {
     smbios_have_defaults = true;
     smbios_legacy = legacy_mode;
@@ -909,11 +915,45 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
         g_free(smbios_entries);
     }
 
+    /*
+     * If @stream_product & @stream_version are non-NULL, then
+     * we're following rules for new Windows driver support.
+     * The data we have to report is defined in this doc:
+     *
+     * https://docs.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer
+     *
+     * The Windows drivers are written to expect use of the
+     * scheme documented as "HardwareID-6" against Windows 10,
+     * which uses SMBIOS System (Type 1) and Base Board (Type 2)
+     * tables and will match on
+     *
+     *   System Manufacturer = Red Hat     (@manufacturer)
+     *   System SKU Number = 8.2.0         (@stream_version)
+     *   Baseboard Manufacturer = Red Hat  (@manufacturer)
+     *   Baseboard Product = RHEL-AV       (@stream_product)
+     *
+     * NB, SKU must be changed with each RHEL-AV release
+     *
+     * Other fields can be freely used by applications using
+     * QEMU. For example apps can use the "System product"
+     * and "System version" to identify themselves.
+     *
+     * We get 'System Manufacturer' and 'Baseboard Manufacturer'
+     */
     SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
     SMBIOS_SET_DEFAULT(type1.product, product);
     SMBIOS_SET_DEFAULT(type1.version, version);
+    SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux");
+    if (stream_version != NULL) {
+        SMBIOS_SET_DEFAULT(type1.sku, stream_version);
+    }
     SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
-    SMBIOS_SET_DEFAULT(type2.product, product);
+    if (stream_product != NULL) {
+        SMBIOS_SET_DEFAULT(type2.product, stream_product);
+        smbios_type2_required = true;
+    } else {
+        SMBIOS_SET_DEFAULT(type2.product, product);
+    }
     SMBIOS_SET_DEFAULT(type2.version, version);
     SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer);
     SMBIOS_SET_DEFAULT(type3.version, version);
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index 050875b497..32935da46c 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -231,7 +231,7 @@ static const VMStateDescription vmstate_pit_common = {
     .pre_save = pit_dispatch_pre_save,
     .post_load = pit_dispatch_post_load,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
+        VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */
         VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
                              vmstate_pit_channel, PITChannelState),
         VMSTATE_INT64(channels[0].next_transition_time,
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 0cb02a6432..962a9622e5 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1167,12 +1167,14 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
     UHCIState *s = UHCI(dev);
     uint8_t *pci_conf = s->dev.config;
     int i;
+    int irq_pin;
 
     pci_conf[PCI_CLASS_PROG] = 0x00;
     /* TODO: reset value should be 0. */
     pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
 
-    pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1);
+    irq_pin = u->info.irq_pin;
+    pci_config_set_interrupt_pin(pci_conf, irq_pin + 1);
 
     if (s->masterbus) {
         USBPort *ports[NB_PORTS];
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
index e934b1a5b1..e18b05e528 100644
--- a/hw/usb/hcd-xhci-pci.c
+++ b/hw/usb/hcd-xhci-pci.c
@@ -104,6 +104,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
    return 0;
 }
 
+/* RH bz 1912846 */
+static bool usb_xhci_pci_add_msi(struct PCIDevice *dev, Error **errp)
+{
+    int ret;
+    Error *err = NULL;
+    XHCIPciState *s = XHCI_PCI(dev);
+
+    ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err);
+    /*
+     * Any error other than -ENOTSUP(board's MSI support is broken)
+     * is a programming error
+     */
+    assert(!ret || ret == -ENOTSUP);
+    if (ret && s->msi == ON_OFF_AUTO_ON) {
+        /* Can't satisfy user's explicit msi=on request, fail */
+        error_append_hint(&err, "You have to use msi=auto (default) or "
+                "msi=off with this machine type.\n");
+        error_propagate(errp, err);
+        return true;
+    }
+    assert(!err || s->msi == ON_OFF_AUTO_AUTO);
+    /* With msi=auto, we fall back to MSI off silently */
+    error_free(err);
+
+    return false;
+}
+
 static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
 {
     int ret;
@@ -125,23 +152,12 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
         s->xhci.nec_quirks = true;
     }
 
-    if (s->msi != ON_OFF_AUTO_OFF) {
-        ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err);
-        /*
-         * Any error other than -ENOTSUP(board's MSI support is broken)
-         * is a programming error
-         */
-        assert(!ret || ret == -ENOTSUP);
-        if (ret && s->msi == ON_OFF_AUTO_ON) {
-            /* Can't satisfy user's explicit msi=on request, fail */
-            error_append_hint(&err, "You have to use msi=auto (default) or "
-                    "msi=off with this machine type.\n");
+    if (s->msi != ON_OFF_AUTO_OFF && s->rh_late_msi_cap) {
+        /* This gives the behaviour from 5.2.0 onwards, lspci shows 90,a0,70 */
+        if (usb_xhci_pci_add_msi(dev, &err)) {
             error_propagate(errp, err);
             return;
         }
-        assert(!err || s->msi == ON_OFF_AUTO_AUTO);
-        /* With msi=auto, we fall back to MSI off silently */
-        error_free(err);
     }
     pci_register_bar(dev, 0,
                      PCI_BASE_ADDRESS_SPACE_MEMORY |
@@ -154,6 +170,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
         assert(ret > 0);
     }
 
+    /* RH bz 1912846 */
+    if (s->msi != ON_OFF_AUTO_OFF && !s->rh_late_msi_cap) {
+        /* This gives the older RH machine behaviour, lspci shows 90,70,a0 */
+        if (usb_xhci_pci_add_msi(dev, &err)) {
+            error_propagate(errp, err);
+            return;
+        }
+    }
     if (s->msix != ON_OFF_AUTO_OFF) {
         /* TODO check for errors, and should fail when msix=on */
         msix_init(dev, s->xhci.numintrs,
@@ -198,11 +222,18 @@ static void xhci_instance_init(Object *obj)
     qdev_alias_all_properties(DEVICE(&s->xhci), obj);
 }
 
+static Property xhci_pci_properties[] = {
+    /* RH bz 1912846 */
+    DEFINE_PROP_BOOL("x-rh-late-msi-cap", XHCIPciState, rh_late_msi_cap, true),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void xhci_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
+    device_class_set_props(dc, xhci_pci_properties);
     dc->reset   = xhci_pci_reset;
     dc->vmsd    = &vmstate_xhci_pci;
     set_bit(DEVICE_CATEGORY_USB, dc->categories);
diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h
index c193f79443..086a1feb1e 100644
--- a/hw/usb/hcd-xhci-pci.h
+++ b/hw/usb/hcd-xhci-pci.h
@@ -39,6 +39,7 @@ typedef struct XHCIPciState {
     XHCIState xhci;
     OnOffAuto msi;
     OnOffAuto msix;
+    bool      rh_late_msi_cap;  /* bz 1912846 */
 } XHCIPciState;
 
 #endif
diff --git a/include/hw/boards.h b/include/hw/boards.h
index accd6eff35..f5423f351a 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -416,4 +416,22 @@ extern const size_t hw_compat_2_2_len;
 extern GlobalProperty hw_compat_2_1[];
 extern const size_t hw_compat_2_1_len;
 
+extern GlobalProperty hw_compat_rhel_8_4[];
+extern const size_t hw_compat_rhel_8_4_len;
+
+extern GlobalProperty hw_compat_rhel_8_3[];
+extern const size_t hw_compat_rhel_8_3_len;
+
+extern GlobalProperty hw_compat_rhel_8_2[];
+extern const size_t hw_compat_rhel_8_2_len;
+
+extern GlobalProperty hw_compat_rhel_8_1[];
+extern const size_t hw_compat_rhel_8_1_len;
+
+extern GlobalProperty hw_compat_rhel_8_0[];
+extern const size_t hw_compat_rhel_8_0_len;
+
+extern GlobalProperty hw_compat_rhel_7_6[];
+extern const size_t hw_compat_rhel_7_6_len;
+
 #endif
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 5a0dd0c8cf..2cb1ec2bab 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -278,7 +278,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp);
 void smbios_set_cpuid(uint32_t version, uint32_t features);
 void smbios_set_defaults(const char *manufacturer, const char *product,
                          const char *version, bool legacy_mode,
-                         bool uuid_encoded, SmbiosEntryPointType ep_type);
+                         bool uuid_encoded,
+                         const char *stream_product,
+                         const char *stream_version,
+                         SmbiosEntryPointType ep_type);
 uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length);
 void smbios_get_tables(MachineState *ms,
                        const struct smbios_phys_mem_area *mem_array,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 88dffe7517..17ad7bfc3a 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -107,6 +107,9 @@ struct PCMachineClass {
     bool smbios_defaults;
     bool smbios_legacy_mode;
     bool smbios_uuid_encoded;
+    /* New fields needed for Windows HardwareID-6 matching */
+    const char *smbios_stream_product;
+    const char *smbios_stream_version;
 
     /* RAM / address space compat: */
     bool gigabyte_align;
-- 
2.27.0