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