diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf index e1cd0b3500..159b4d16ed 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -24,10 +24,12 @@ [Sources.IA32] Ia32/AmdSev.c Ia32/MpFuncs.nasm + MpLibTdxNull.c [Sources.X64] X64/AmdSev.c X64/MpFuncs.nasm + MpLibTdx.c [Sources.common] AmdSev.c @@ -36,6 +38,7 @@ MpLib.c MpLib.h Microcode.c + MpIntelTdx.h [Packages] MdePkg/MdePkg.dec diff --git a/UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h b/UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h new file mode 100644 index 0000000000..8a26f6c19f --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h @@ -0,0 +1,69 @@ +/** @file + CPU MP Initialize Library header file for Td guest. + + Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MP_INTEL_TDX_H_ +#define MP_INTEL_TDX_H_ + +#include +#include +#include +#include +#include + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + @param[out] HealthData Return processor health data. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +TdxMpInitLibGetProcessorInfo ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, + OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL + ); + +/** + Retrieves the number of logical processor in the platform and the number of + those logical processors that are enabled on this boot. This service may only + be called from the BSP. + + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors + is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +TdxMpInitLibGetNumberOfProcessors ( + OUT UINTN *NumberOfProcessors, OPTIONAL + OUT UINTN *NumberOfEnabledProcessors OPTIONAL + ); + +#endif diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 4a73787ee4..91c7afaeb2 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -9,9 +9,11 @@ **/ #include "MpLib.h" +#include "MpIntelTdx.h" #include #include #include +#include EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID; @@ -1803,6 +1805,10 @@ MpInitLibInitialize ( UINTN BackupBufferAddr; UINTN ApIdtBase; + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + return EFI_SUCCESS; + } + OldCpuMpData = GetCpuMpDataFromGuidedHob (); if (OldCpuMpData == NULL) { MaxLogicalProcessorNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); @@ -2073,6 +2079,10 @@ MpInitLibGetProcessorInfo ( CPU_INFO_IN_HOB *CpuInfoInHob; UINTN OriginalProcessorNumber; + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + return TdxMpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, HealthData); + } + CpuMpData = GetCpuMpData (); CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; @@ -2167,6 +2177,10 @@ SwitchBSPWorker ( BOOLEAN OldInterruptState; BOOLEAN OldTimerInterruptState; + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + return EFI_UNSUPPORTED; + } + // // Save and Disable Local APIC timer interrupt // @@ -2307,6 +2321,10 @@ EnableDisableApWorker ( CPU_MP_DATA *CpuMpData; UINTN CallerNumber; + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + return EFI_UNSUPPORTED; + } + CpuMpData = GetCpuMpData (); // @@ -2367,6 +2385,11 @@ MpInitLibWhoAmI ( return EFI_INVALID_PARAMETER; } + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + *ProcessorNumber = 0; + return EFI_SUCCESS; + } + CpuMpData = GetCpuMpData (); return GetProcessorNumber (CpuMpData, ProcessorNumber); @@ -2405,12 +2428,16 @@ MpInitLibGetNumberOfProcessors ( UINTN EnabledProcessorNumber; UINTN Index; - CpuMpData = GetCpuMpData (); - if ((NumberOfProcessors == NULL) && (NumberOfEnabledProcessors == NULL)) { return EFI_INVALID_PARAMETER; } + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + return TdxMpInitLibGetNumberOfProcessors (NumberOfProcessors, NumberOfEnabledProcessors); + } + + CpuMpData = GetCpuMpData (); + // // Check whether caller processor is BSP // @@ -2490,13 +2517,16 @@ StartupAllCPUsWorker ( BOOLEAN HasEnabledAp; CPU_STATE ApState; - CpuMpData = GetCpuMpData (); - if (FailedCpuList != NULL) { *FailedCpuList = NULL; } - if ((CpuMpData->CpuCount == 1) && ExcludeBsp) { + Status = MpInitLibGetNumberOfProcessors (&ProcessorCount, NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + if ((ProcessorCount == 1) && ExcludeBsp) { return EFI_NOT_STARTED; } @@ -2504,6 +2534,22 @@ StartupAllCPUsWorker ( return EFI_INVALID_PARAMETER; } + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + // + // For Td guest ExcludeBsp must be FALSE. Otherwise it will return in above checks. + // + ASSERT (!ExcludeBsp); + + // + // Start BSP. + // + Procedure (ProcedureArgument); + + return EFI_SUCCESS; + } + + CpuMpData = GetCpuMpData (); + // // Check whether caller processor is BSP // @@ -2643,6 +2689,13 @@ StartupThisAPWorker ( CPU_AP_DATA *CpuData; UINTN CallerNumber; + // + // In Td guest, startup of AP is not supported in current stage. + // + if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + return EFI_UNSUPPORTED; + } + CpuMpData = GetCpuMpData (); if (Finished != NULL) { diff --git a/UefiCpuPkg/Library/MpInitLib/MpLibTdx.c b/UefiCpuPkg/Library/MpInitLib/MpLibTdx.c new file mode 100644 index 0000000000..fdb58fba93 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/MpLibTdx.c @@ -0,0 +1,106 @@ +/** @file + CPU MP Initialize Library common functions for Td guest. + + Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" +#include "MpIntelTdx.h" + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + In current stage only the BSP is workable. So ProcessorNumber should be 0. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + @param[out] HealthData Return processor health data. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL or ProcessorNumber is not 0. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +TdxMpInitLibGetProcessorInfo ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, + OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL + ) +{ + UINTN OriginalProcessorNumber; + + // + // Lower 24 bits contains the actual processor number. + // + OriginalProcessorNumber = ProcessorNumber; + ProcessorNumber &= BIT24 - 1; + + if ((ProcessorInfoBuffer == NULL) || (ProcessorNumber != 0)) { + return EFI_INVALID_PARAMETER; + } + + ProcessorInfoBuffer->ProcessorId = 0; + ProcessorInfoBuffer->StatusFlag = PROCESSOR_AS_BSP_BIT | PROCESSOR_ENABLED_BIT; + ZeroMem (&ProcessorInfoBuffer->Location, sizeof (EFI_CPU_PHYSICAL_LOCATION)); + + if ((OriginalProcessorNumber & CPU_V2_EXTENDED_TOPOLOGY) != 0) { + ZeroMem (&ProcessorInfoBuffer->ExtendedInformation.Location2, sizeof (EFI_CPU_PHYSICAL_LOCATION2)); + } + + if (HealthData != NULL) { + HealthData->Uint32 = 0; + } + + return EFI_SUCCESS; +} + +/** + Retrieves the number of logical processor in the platform and the number of + those logical processors that are enabled on this boot. This service may only + be called from the BSP. + + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors + is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +TdxMpInitLibGetNumberOfProcessors ( + OUT UINTN *NumberOfProcessors, OPTIONAL + OUT UINTN *NumberOfEnabledProcessors OPTIONAL + ) +{ + ASSERT (NumberOfProcessors != NULL || NumberOfEnabledProcessors != NULL); + // + // In current stage only the BSP is workable. So NumberOfProcessors + // & NumberOfEnableddProcessors are both 1. + // + if (NumberOfProcessors != NULL) { + *NumberOfProcessors = 1; + } + + if (NumberOfEnabledProcessors != NULL) { + *NumberOfEnabledProcessors = 1; + } + + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c b/UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c new file mode 100644 index 0000000000..b5aaf6df28 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c @@ -0,0 +1,69 @@ +/** @file + CPU MP Initialize Library common functions (NULL instance) for Td guest. + + Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" +#include "MpIntelTdx.h" + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + @param[out] HealthData Return processor health data. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +TdxMpInitLibGetProcessorInfo ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, + OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +/** + Retrieves the number of logical processor in the platform and the number of + those logical processors that are enabled on this boot. This service may only + be called from the BSP. + + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors + is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +TdxMpInitLibGetNumberOfProcessors ( + OUT UINTN *NumberOfProcessors, OPTIONAL + OUT UINTN *NumberOfEnabledProcessors OPTIONAL + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf index 5facf4db94..894be0f8da 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -24,10 +24,12 @@ [Sources.IA32] Ia32/AmdSev.c Ia32/MpFuncs.nasm + MpLibTdxNull.c [Sources.X64] X64/AmdSev.c X64/MpFuncs.nasm + MpLibTdx.c [Sources.common] AmdSev.c @@ -36,6 +38,7 @@ MpLib.c MpLib.h Microcode.c + MpIntelTdx.h [Packages] MdePkg/MdePkg.dec