FeatureControl.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**@file
  2. Install a callback when necessary for setting the Feature Control MSR on all
  3. processors.
  4. Copyright (C) 2016, Red Hat, Inc.
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <Library/DebugLib.h>
  8. #include <Library/PeiServicesLib.h>
  9. #include <Library/QemuFwCfgLib.h>
  10. #include <Ppi/MpServices.h>
  11. #include <Register/ArchitecturalMsr.h>
  12. #include <IndustryStandard/Tdx.h>
  13. #include "Platform.h"
  14. //
  15. // The value to be written to the Feature Control MSR, retrieved from fw_cfg.
  16. //
  17. STATIC UINT64 mFeatureControlValue;
  18. /**
  19. Write the Feature Control MSR on an Application Processor or the Boot
  20. Processor.
  21. All APs execute this function in parallel. The BSP executes the function
  22. separately.
  23. @param[in,out] WorkSpace Pointer to the input/output argument workspace
  24. shared by all processors.
  25. **/
  26. STATIC
  27. VOID
  28. EFIAPI
  29. WriteFeatureControl (
  30. IN OUT VOID *WorkSpace
  31. )
  32. {
  33. if (TdIsEnabled ()) {
  34. TdVmCall (TDVMCALL_WRMSR, (UINT64)MSR_IA32_FEATURE_CONTROL, mFeatureControlValue, 0, 0, 0);
  35. } else {
  36. AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL, mFeatureControlValue);
  37. }
  38. }
  39. /**
  40. Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
  41. @param[in] PeiServices Indirect reference to the PEI Services Table.
  42. @param[in] NotifyDescriptor Address of the notification descriptor data
  43. structure.
  44. @param[in] Ppi Address of the PPI that was installed.
  45. @return Status of the notification. The status code returned from this
  46. function is ignored.
  47. **/
  48. STATIC
  49. EFI_STATUS
  50. EFIAPI
  51. OnMpServicesAvailable (
  52. IN EFI_PEI_SERVICES **PeiServices,
  53. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  54. IN VOID *Ppi
  55. )
  56. {
  57. EFI_PEI_MP_SERVICES_PPI *MpServices;
  58. EFI_STATUS Status;
  59. DEBUG ((DEBUG_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
  60. //
  61. // Write the MSR on all the APs in parallel.
  62. //
  63. MpServices = Ppi;
  64. Status = MpServices->StartupAllAPs (
  65. (CONST EFI_PEI_SERVICES **)PeiServices,
  66. MpServices,
  67. WriteFeatureControl, // Procedure
  68. FALSE, // SingleThread
  69. 0, // TimeoutInMicroSeconds: inf.
  70. NULL // ProcedureArgument
  71. );
  72. if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
  73. DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
  74. return Status;
  75. }
  76. //
  77. // Now write the MSR on the BSP too.
  78. //
  79. WriteFeatureControl (NULL);
  80. return EFI_SUCCESS;
  81. }
  82. //
  83. // Notification object for registering the callback, for when
  84. // EFI_PEI_MP_SERVICES_PPI becomes available.
  85. //
  86. STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
  87. EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
  88. EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  89. &gEfiPeiMpServicesPpiGuid, // Guid
  90. OnMpServicesAvailable // Notify
  91. };
  92. VOID
  93. InstallFeatureControlCallback (
  94. VOID
  95. )
  96. {
  97. EFI_STATUS Status;
  98. FIRMWARE_CONFIG_ITEM FwCfgItem;
  99. UINTN FwCfgSize;
  100. Status = QemuFwCfgFindFile (
  101. "etc/msr_feature_control",
  102. &FwCfgItem,
  103. &FwCfgSize
  104. );
  105. if (EFI_ERROR (Status) || (FwCfgSize != sizeof mFeatureControlValue)) {
  106. //
  107. // Nothing to do.
  108. //
  109. return;
  110. }
  111. QemuFwCfgSelectItem (FwCfgItem);
  112. QemuFwCfgReadBytes (sizeof mFeatureControlValue, &mFeatureControlValue);
  113. Status = PeiServicesNotifyPpi (&mMpServicesNotify);
  114. if (EFI_ERROR (Status)) {
  115. DEBUG ((
  116. DEBUG_ERROR,
  117. "%a: failed to set up MP Services callback: %r\n",
  118. __FUNCTION__,
  119. Status
  120. ));
  121. }
  122. }