diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c index fd09403eab..5df8c689c6 100644 --- a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c +++ b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c @@ -7,6 +7,7 @@ **/ #include // ICH9_APM_CNT +#include // QEMU_CPUHP_CMD_GET_PENDING #include // CpuDeadLoop() #include // ASSERT() #include // gMmst @@ -14,6 +15,8 @@ #include // EFI_MM_CPU_IO_PROTOCOL #include // EFI_STATUS +#include "QemuCpuhp.h" // QemuCpuhpWriteCpuSelector() + // // We use this protocol for accessing IO Ports. // @@ -168,6 +171,38 @@ CpuHotplugEntry ( goto Fatal; } + // + // Sanity-check the CPU hotplug interface. + // + // Both of the following features are part of QEMU 5.0, introduced primarily + // in commit range 3e08b2b9cb64..3a61c8db9d25: + // + // (a) the QEMU_CPUHP_CMD_GET_ARCH_ID command of the modern CPU hotplug + // interface, + // + // (b) the "SMRAM at default SMBASE" feature. + // + // From these, (b) is restricted to 5.0+ machine type versions, while (a) + // does not depend on machine type version. Because we ensured the stricter + // condition (b) through PcdQ35SmramAtDefaultSmbase above, the (a) + // QEMU_CPUHP_CMD_GET_ARCH_ID command must now be available too. While we + // can't verify the presence of precisely that command, we can still verify + // (sanity-check) that the modern interface is active, at least. + // + // Consult the "Typical usecases | Detecting and enabling modern CPU hotplug + // interface" section in QEMU's "docs/specs/acpi_cpu_hotplug.txt", on the + // following. + // + QemuCpuhpWriteCpuSelector (mMmCpuIo, 0); + QemuCpuhpWriteCpuSelector (mMmCpuIo, 0); + QemuCpuhpWriteCommand (mMmCpuIo, QEMU_CPUHP_CMD_GET_PENDING); + if (QemuCpuhpReadCommandData2 (mMmCpuIo) != 0) { + Status = EFI_NOT_FOUND; + DEBUG ((DEBUG_ERROR, "%a: modern CPU hotplug interface: %r\n", + __FUNCTION__, Status)); + goto Fatal; + } + // // Register the handler for the CPU Hotplug MMI. // diff --git a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h index cf0745610f..3d01363350 100644 --- a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h +++ b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h @@ -39,5 +39,6 @@ #define QEMU_CPUHP_W_CMD 0x5 #define QEMU_CPUHP_CMD_GET_PENDING 0x0 +#define QEMU_CPUHP_CMD_GET_ARCH_ID 0x3 #endif // QEMU_CPU_HOTPLUG_H_