[edk2-devel] [PATCH v5 2/9] OvmfPkg/CpuHotplugSmm: collect hot-unplug events

Ankur Arora posted 9 patches 3 years, 9 months ago
There is a newer version of this series
[edk2-devel] [PATCH v5 2/9] OvmfPkg/CpuHotplugSmm: collect hot-unplug events
Posted by Ankur Arora 3 years, 9 months ago
Process fw_remove events in QemuCpuhpCollectApicIds() and collect
corresponding APIC IDs for CPUs that are being hot-unplugged.

In addition, we now ignore CPUs which only have remove set. These
CPUs haven't been processed by OSPM yet.

This is based on the QEMU hot-unplug protocol documented here:
  https://lore.kernel.org/qemu-devel/20201204170939.1815522-3-imammedo@redhat.com/

Also define QEMU_CPUHP_STAT_EJECTED while we are at it.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Aaron Young <aaron.young@oracle.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132
Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
---
 OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h |  2 ++
 OvmfPkg/CpuHotplugSmm/QemuCpuhp.c                 | 35 +++++++++++++++++------
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h
index a34a6d3fae61..692e3072598c 100644
--- a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h
+++ b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h
@@ -34,6 +34,8 @@
 #define QEMU_CPUHP_STAT_ENABLED                BIT0

 #define QEMU_CPUHP_STAT_INSERT                 BIT1

 #define QEMU_CPUHP_STAT_REMOVE                 BIT2

+#define QEMU_CPUHP_STAT_EJECTED                BIT3

+#define QEMU_CPUHP_STAT_FW_REMOVE              BIT4

 

 #define QEMU_CPUHP_RW_CMD_DATA               0x8

 

diff --git a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
index 8d4a6693c8d6..2dd783ebf42e 100644
--- a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
+++ b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
@@ -205,7 +205,7 @@ QemuCpuhpCollectApicIds (
     UINT8   CpuStatus;

     APIC_ID *ExtendIds;

     UINT32  *ExtendCount;

-    APIC_ID NewApicId;

+    APIC_ID OpApicId;

 

     //

     // Write CurrentSelector (which is valid) to the CPU selector register.

@@ -245,10 +245,10 @@ QemuCpuhpCollectApicIds (
     if ((CpuStatus & QEMU_CPUHP_STAT_INSERT) != 0) {

       //

       // The "insert" event guarantees the "enabled" status; plus it excludes

-      // the "remove" event.

+      // the "fw_remove" event.

       //

       if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0 ||

-          (CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {

+          (CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) {

         DEBUG ((DEBUG_ERROR, "%a: CurrentSelector=%u CpuStatus=0x%x: "

           "inconsistent CPU status\n", __FUNCTION__, CurrentSelector,

           CpuStatus));

@@ -260,12 +260,31 @@ QemuCpuhpCollectApicIds (
 

       ExtendIds   = PluggedApicIds;

       ExtendCount = PluggedCount;

-    } else if ((CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {

-      DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: remove\n", __FUNCTION__,

+    } else if ((CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) {

+      //

+      // "fw_remove" event guarantees "enabled".

+      //

+      if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0) {

+        DEBUG ((DEBUG_ERROR, "%a: CurrentSelector=%u CpuStatus=0x%x: "

+          "inconsistent CPU status\n", __FUNCTION__, CurrentSelector,

+          CpuStatus));

+        return EFI_PROTOCOL_ERROR;

+      }

+

+      DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: fw_remove\n", __FUNCTION__,

         CurrentSelector));

 

       ExtendIds   = ToUnplugApicIds;

       ExtendCount = ToUnplugCount;

+    } else if ((CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {

+      //

+      // Let the OSPM deal with the "remove" event.

+      //

+      DEBUG ((DEBUG_INFO, "%a: CurrentSelector=%u: remove (ignored)\n", __FUNCTION__,

+        CurrentSelector));

+

+      CurrentSelector++;

+      continue;

     } else {

       DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: no event\n",

         __FUNCTION__, CurrentSelector));

@@ -281,10 +300,10 @@ QemuCpuhpCollectApicIds (
       return EFI_BUFFER_TOO_SMALL;

     }

     QemuCpuhpWriteCommand (MmCpuIo, QEMU_CPUHP_CMD_GET_ARCH_ID);

-    NewApicId = QemuCpuhpReadCommandData (MmCpuIo);

+    OpApicId = QemuCpuhpReadCommandData (MmCpuIo);

     DEBUG ((DEBUG_VERBOSE, "%a: ApicId=" FMT_APIC_ID "\n", __FUNCTION__,

-      NewApicId));

-    ExtendIds[(*ExtendCount)++] = NewApicId;

+      OpApicId, ExtendCount));

+    ExtendIds[(*ExtendCount)++] = OpApicId;

 

     //

     // We've processed the CPU with (known) pending events, but we must never

-- 
2.9.3



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#70761): https://edk2.groups.io/g/devel/message/70761
Mute This Topic: https://groups.io/mt/80125309/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-