123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /**@file
- Install a callback when necessary for setting the Feature Control MSR on all
- processors.
- Copyright (C) 2016, Red Hat, Inc.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Library/DebugLib.h>
- #include <Library/HobLib.h>
- #include <Library/PeiServicesLib.h>
- #include <Library/QemuFwCfgLib.h>
- #include <Ppi/MpServices.h>
- #include <Register/ArchitecturalMsr.h>
- #include <IndustryStandard/Tdx.h>
- #include "Platform.h"
- /**
- Write the Feature Control MSR on an Application Processor or the Boot
- Processor.
- All APs execute this function in parallel. The BSP executes the function
- separately.
- @param[in,out] WorkSpace Pointer to the input/output argument workspace
- shared by all processors.
- **/
- STATIC
- VOID
- EFIAPI
- WriteFeatureControl (
- IN OUT VOID *WorkSpace
- )
- {
- EFI_HOB_PLATFORM_INFO *PlatformInfoHob = WorkSpace;
- if (TdIsEnabled ()) {
- TdVmCall (
- TDVMCALL_WRMSR,
- (UINT64)MSR_IA32_FEATURE_CONTROL,
- PlatformInfoHob->FeatureControlValue,
- 0,
- 0,
- 0
- );
- } else {
- AsmWriteMsr64 (
- MSR_IA32_FEATURE_CONTROL,
- PlatformInfoHob->FeatureControlValue
- );
- }
- }
- /**
- Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
- @param[in] PeiServices Indirect reference to the PEI Services Table.
- @param[in] NotifyDescriptor Address of the notification descriptor data
- structure.
- @param[in] Ppi Address of the PPI that was installed.
- @return Status of the notification. The status code returned from this
- function is ignored.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- OnMpServicesAvailable (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *Ppi
- )
- {
- EFI_PEI_MP_SERVICES_PPI *MpServices;
- EFI_STATUS Status;
- EFI_HOB_PLATFORM_INFO *PlatformInfoHob;
- EFI_HOB_GUID_TYPE *GuidHob;
- GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);
- if (GuidHob == NULL) {
- return EFI_UNSUPPORTED;
- }
- PlatformInfoHob = (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);
- DEBUG ((DEBUG_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
- //
- // Write the MSR on all the APs in parallel.
- //
- MpServices = Ppi;
- Status = MpServices->StartupAllAPs (
- (CONST EFI_PEI_SERVICES **)PeiServices,
- MpServices,
- WriteFeatureControl, // Procedure
- FALSE, // SingleThread
- 0, // TimeoutInMicroSeconds: inf.
- PlatformInfoHob // ProcedureArgument
- );
- if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
- DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
- return Status;
- }
- //
- // Now write the MSR on the BSP too.
- //
- WriteFeatureControl (PlatformInfoHob);
- return EFI_SUCCESS;
- }
- //
- // Notification object for registering the callback, for when
- // EFI_PEI_MP_SERVICES_PPI becomes available.
- //
- STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
- EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
- &gEfiPeiMpServicesPpiGuid, // Guid
- OnMpServicesAvailable // Notify
- };
- VOID
- InstallFeatureControlCallback (
- IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
- )
- {
- EFI_STATUS Status;
- FIRMWARE_CONFIG_ITEM FwCfgItem;
- UINTN FwCfgSize;
- Status = QemuFwCfgFindFile (
- "etc/msr_feature_control",
- &FwCfgItem,
- &FwCfgSize
- );
- if (EFI_ERROR (Status) || (FwCfgSize != sizeof (PlatformInfoHob->FeatureControlValue))) {
- //
- // Nothing to do.
- //
- return;
- }
- QemuFwCfgSelectItem (FwCfgItem);
- QemuFwCfgReadBytes (
- sizeof (PlatformInfoHob->FeatureControlValue),
- &(PlatformInfoHob->FeatureControlValue)
- );
- Status = PeiServicesNotifyPpi (&mMpServicesNotify);
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: failed to set up MP Services callback: %r\n",
- __FUNCTION__,
- Status
- ));
- }
- }
|