yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-acpi-pc-revert-back-to-v5.2-PCI-slot-enumeration.patch

a83cc2
From 456bb6cb658b9d332fa0b5b91946916b48ed449e Mon Sep 17 00:00:00 2001
a83cc2
From: Igor Mammedov <imammedo@redhat.com>
a83cc2
Date: Thu, 29 Jul 2021 07:42:10 -0400
a83cc2
Subject: [PATCH 09/39] acpi: pc: revert back to v5.2 PCI slot enumeration
a83cc2
a83cc2
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
a83cc2
RH-MergeRequest: 32: Synchronize with RHEL-AV 8.5 release 27 to RHEL 9
a83cc2
RH-Commit: [1/15] 57222343ccae17b99b4e166798d4d0eecca2e22b (mrezanin/centos-src-qemu-kvm)
a83cc2
RH-Bugzilla: 1957194
a83cc2
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
a83cc2
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
a83cc2
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
a83cc2
RH-Acked-by: Andrew Jones <drjones@redhat.com>
a83cc2
a83cc2
Commit [1] moved _SUN variable from only hot-pluggable to
a83cc2
all devices. This made linux kernel enumerate extra slots
a83cc2
that weren't present before. If extra slot happens to be
a83cc2
be enumerated first and there is a device in th same slot
a83cc2
but on other bridge, linux kernel will add -N suffix to
a83cc2
slot name of the later, thus changing NIC name compared to
a83cc2
QEMU 5.2. This in some case confuses systemd, if it is
a83cc2
using SLOT NIC naming scheme and interface name becomes
a83cc2
not the same as it was under QEMU-5.2.
a83cc2
a83cc2
Reproducer QEMU CLI:
a83cc2
  -M pc-i440fx-5.2 -nodefaults \
a83cc2
  -device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x3 \
a83cc2
  -device virtio-net-pci,id=nic1,bus=pci.1,addr=0x1 \
a83cc2
  -device virtio-net-pci,id=nic2,bus=pci.1,addr=0x2 \
a83cc2
  -device virtio-net-pci,id=nic3,bus=pci.1,addr=0x3
a83cc2
a83cc2
with RHEL8 guest produces following results:
a83cc2
  v5.2:
a83cc2
     kernel: virtio_net virtio0 ens1: renamed from eth0
a83cc2
     kernel: virtio_net virtio2 ens3: renamed from eth2
a83cc2
     kernel: virtio_net virtio1 enp1s2: renamed from eth1
a83cc2
      (slot 2 is assigned to empty bus 0 slot and virtio1
a83cc2
       is assigned to 2-2 slot, and renaming falls back,
a83cc2
       for some reason, to path based naming scheme)
a83cc2
a83cc2
  v6.0:
a83cc2
     kernel: virtio_net virtio0 ens1: renamed from eth0
a83cc2
     kernel: virtio_net virtio2 ens3: renamed from eth2
a83cc2
     systemd-udevd[299]: Error changing net interface name 'eth1' to 'ens3': File exists
a83cc2
     systemd-udevd[299]: could not rename interface '3' from 'eth1' to 'ens3': File exists
a83cc2
      (with commit [1] kernel assigns virtio2 to 3-2 slot
a83cc2
       since bridge advertises _SUN=0x3 and kernel assigns
a83cc2
       slot 3 to bridge. Still it manages to rename virtio2
a83cc2
       correctly to ens3, however systemd gets confused with virtio1
a83cc2
       where slot allocation exactly the same (2-2) as in 5.2 case
a83cc2
       and tries to rename it to ens3 which is rightfully taken by
a83cc2
       virtio2)
a83cc2
a83cc2
I'm not sure what breaks in systemd interface renaming (it probably
a83cc2
should be investigated), but on QEMU side we can safely revert
a83cc2
_SUN to 5.2 behavior (i.e. avoid cold-plugged bridges and non
a83cc2
hot-pluggable device classes), without breaking acpi-index, which uses
a83cc2
slot numbers but it doesn't have to use _SUN, it could use an arbitrary
a83cc2
variable name that has the same slot value).
a83cc2
It will help existing VMs to keep networking with non trivial
a83cc2
configs in working order since systemd will do its interface
a83cc2
renaming magic as it used to do.
a83cc2
a83cc2
1)
a83cc2
Fixes: b7f23f62e40 (pci: acpi: add _DSM method to PCI devices)
a83cc2
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
a83cc2
Message-Id: <20210624204229.998824-3-imammedo@redhat.com>
a83cc2
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
a83cc2
Tested-by: John Sucaet <john.sucaet@ekinops.com>
a83cc2
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
a83cc2
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
a83cc2
(cherry picked from commit 7193d7cdd93e50f0e5f09803b98d27d3f9b147ac)
a83cc2
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
a83cc2
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
a83cc2
---
a83cc2
 hw/i386/acpi-build.c | 9 +++++++--
a83cc2
 1 file changed, 7 insertions(+), 2 deletions(-)
a83cc2
a83cc2
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
a83cc2
index de98750aef..dbee0cd3bc 100644
a83cc2
--- a/hw/i386/acpi-build.c
a83cc2
+++ b/hw/i386/acpi-build.c
a83cc2
@@ -432,11 +432,15 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
a83cc2
         aml_append(dev, aml_name_decl("_ADR", aml_int(slot << 16)));
a83cc2
 
a83cc2
         if (bsel) {
a83cc2
-            aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
a83cc2
+            /*
a83cc2
+             * Can't declare _SUN here for every device as it changes 'slot'
a83cc2
+             * enumeration order in linux kernel, so use another variable for it
a83cc2
+             */
a83cc2
+            aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
a83cc2
             method = aml_method("_DSM", 4, AML_SERIALIZED);
a83cc2
             aml_append(method, aml_return(
a83cc2
                 aml_call6("PDSM", aml_arg(0), aml_arg(1), aml_arg(2),
a83cc2
-                          aml_arg(3), aml_name("BSEL"), aml_name("_SUN"))
a83cc2
+                          aml_arg(3), aml_name("BSEL"), aml_name("ASUN"))
a83cc2
             ));
a83cc2
             aml_append(dev, method);
a83cc2
         }
a83cc2
@@ -463,6 +467,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
a83cc2
             aml_append(method, aml_return(aml_int(s3d)));
a83cc2
             aml_append(dev, method);
a83cc2
         } else if (hotplug_enabled_dev) {
a83cc2
+            aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
a83cc2
             /* add _EJ0 to make slot hotpluggable  */
a83cc2
             method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
a83cc2
             aml_append(method,
a83cc2
-- 
a83cc2
2.27.0
a83cc2