OvmfPkg/PlatformInitLib: factor out PlatformCpuCountBugCheck()

Move the QEMU v2.7 reset bug check/workaround to a separate function, as
we'll need to detect further issues.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Michael Brown <mcb30@ipxe.org>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Oliver Steffen <osteffen@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4250
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20230119110131.91923-2-lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Hugely-appreciated-by: Michael Brown <mcb30@ipxe.org>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Laszlo Ersek 2023-01-19 12:01:30 +01:00 committed by mergify[bot]
parent 3beb8c9654
commit c3e128a4cd
1 changed files with 58 additions and 23 deletions

View File

@ -404,6 +404,61 @@ PlatformMiscInitialization (
} }
} }
/**
Check for various QEMU bugs concerning CPU numbers.
Compensate for those bugs if various conditions are satisfied, by updating a
suitable subset of the input-output parameters. The function may not return
(it may hang deliberately), even in RELEASE builds, if the QEMU bug is
impossible to cover up.
@param[in,out] BootCpuCount On input, the boot CPU count reported by QEMU via
fw_cfg (QemuFwCfgItemSmpCpuCount). The caller is
responsible for ensuring (BootCpuCount > 0); that
is, if QEMU does not provide the boot CPU count
via fw_cfg *at all*, then this function must not
be called.
@param[in,out] Present On input, the number of present-at-boot CPUs, as
reported by QEMU through the modern CPU hotplug
register block.
@param[in,out] Possible On input, the number of possible CPUs, as
reported by QEMU through the modern CPU hotplug
register block.
**/
STATIC
VOID
PlatformCpuCountBugCheck (
IN OUT UINT16 *BootCpuCount,
IN OUT UINT32 *Present,
IN OUT UINT32 *Possible
)
{
ASSERT (*BootCpuCount > 0);
//
// Sanity check: fw_cfg and the modern CPU hotplug interface should expose the
// same boot CPU count.
//
if (*BootCpuCount != *Present) {
DEBUG ((
DEBUG_WARN,
"%a: QEMU v2.7 reset bug: BootCpuCount=%d Present=%u\n",
__FUNCTION__,
*BootCpuCount,
*Present
));
//
// The handling of QemuFwCfgItemSmpCpuCount, across CPU hotplug plus
// platform reset (including S3), was corrected in QEMU commit e3cadac073a9
// ("pc: fix FW_CFG_NB_CPUS to account for -device added CPUs", 2016-11-16),
// part of release v2.8.0.
//
*BootCpuCount = (UINT16)*Present;
}
}
/** /**
Fetch the boot CPU count and the possible CPU count from QEMU, and expose Fetch the boot CPU count and the possible CPU count from QEMU, and expose
them to UefiCpuPkg modules. them to UefiCpuPkg modules.
@ -518,8 +573,8 @@ PlatformMaxCpuCountInitialization (
UINT8 CpuStatus; UINT8 CpuStatus;
// //
// Read the status of the currently selected CPU. This will help with a // Read the status of the currently selected CPU. This will help with
// sanity check against "BootCpuCount". // various CPU count sanity checks.
// //
CpuStatus = IoRead8 (CpuHpBase + QEMU_CPUHP_R_CPU_STAT); CpuStatus = IoRead8 (CpuHpBase + QEMU_CPUHP_R_CPU_STAT);
if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) != 0) { if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) != 0) {
@ -540,27 +595,7 @@ PlatformMaxCpuCountInitialization (
ASSERT (Selected == Possible || Selected == 0); ASSERT (Selected == Possible || Selected == 0);
} while (Selected > 0); } while (Selected > 0);
// PlatformCpuCountBugCheck (&BootCpuCount, &Present, &Possible);
// Sanity check: fw_cfg and the modern CPU hotplug interface should
// return the same boot CPU count.
//
if (BootCpuCount != Present) {
DEBUG ((
DEBUG_WARN,
"%a: QEMU v2.7 reset bug: BootCpuCount=%d "
"Present=%u\n",
__FUNCTION__,
BootCpuCount,
Present
));
//
// The handling of QemuFwCfgItemSmpCpuCount, across CPU hotplug plus
// platform reset (including S3), was corrected in QEMU commit
// e3cadac073a9 ("pc: fix FW_CFG_NB_CPUS to account for -device added
// CPUs", 2016-11-16), part of release v2.8.0.
//
BootCpuCount = (UINT16)Present;
}
MaxCpuCount = Possible; MaxCpuCount = Possible;
} }