]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c
OvmfPkg/MemEncryptSevLib: find pages of initial SMRAM save state map
[mirror_edk2.git] / OvmfPkg / Library / BaseMemEncryptSevLib / MemEncryptSevLibInternal.c
... / ...
CommitLineData
1/** @file\r
2\r
3 Secure Encrypted Virtualization (SEV) library helper function\r
4\r
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
6\r
7 This program and the accompanying materials are licensed and made available\r
8 under the terms and conditions of the BSD License which accompanies this\r
9 distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <Library/BaseLib.h>\r
18#include <Library/DebugLib.h>\r
19#include <Library/MemEncryptSevLib.h>\r
20#include <Library/PcdLib.h>\r
21#include <Register/Amd/Cpuid.h>\r
22#include <Register/Amd/Msr.h>\r
23#include <Register/Cpuid.h>\r
24#include <Register/QemuSmramSaveStateMap.h>\r
25#include <Register/SmramSaveStateMap.h>\r
26#include <Uefi/UefiBaseType.h>\r
27\r
28STATIC BOOLEAN mSevStatus = FALSE;\r
29STATIC BOOLEAN mSevStatusChecked = FALSE;\r
30\r
31/**\r
32\r
33 Returns a boolean to indicate whether SEV is enabled\r
34\r
35 @retval TRUE SEV is enabled\r
36 @retval FALSE SEV is not enabled\r
37 **/\r
38STATIC\r
39BOOLEAN\r
40EFIAPI\r
41InternalMemEncryptSevIsEnabled (\r
42 VOID\r
43 )\r
44{\r
45 UINT32 RegEax;\r
46 MSR_SEV_STATUS_REGISTER Msr;\r
47 CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;\r
48\r
49 //\r
50 // Check if memory encryption leaf exist\r
51 //\r
52 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
53 if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {\r
54 //\r
55 // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)\r
56 //\r
57 AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
58\r
59 if (Eax.Bits.SevBit) {\r
60 //\r
61 // Check MSR_0xC0010131 Bit 0 (Sev Enabled)\r
62 //\r
63 Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);\r
64 if (Msr.Bits.SevBit) {\r
65 return TRUE;\r
66 }\r
67 }\r
68 }\r
69\r
70 return FALSE;\r
71}\r
72\r
73/**\r
74 Returns a boolean to indicate whether SEV is enabled\r
75\r
76 @retval TRUE SEV is enabled\r
77 @retval FALSE SEV is not enabled\r
78**/\r
79BOOLEAN\r
80EFIAPI\r
81MemEncryptSevIsEnabled (\r
82 VOID\r
83 )\r
84{\r
85 if (mSevStatusChecked) {\r
86 return mSevStatus;\r
87 }\r
88\r
89 mSevStatus = InternalMemEncryptSevIsEnabled();\r
90 mSevStatusChecked = TRUE;\r
91\r
92 return mSevStatus;\r
93}\r
94\r
95\r
96/**\r
97 Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM\r
98 Save State Map.\r
99\r
100 @param[out] BaseAddress The base address of the lowest-address page that\r
101 covers the initial SMRAM Save State Map.\r
102\r
103 @param[out] NumberOfPages The number of pages in the page range that covers\r
104 the initial SMRAM Save State Map.\r
105\r
106 @retval RETURN_SUCCESS BaseAddress and NumberOfPages have been set on\r
107 output.\r
108\r
109 @retval RETURN_UNSUPPORTED SMM is unavailable.\r
110**/\r
111RETURN_STATUS\r
112EFIAPI\r
113MemEncryptSevLocateInitialSmramSaveStateMapPages (\r
114 OUT UINTN *BaseAddress,\r
115 OUT UINTN *NumberOfPages\r
116 )\r
117{\r
118 UINTN MapStart;\r
119 UINTN MapEnd;\r
120 UINTN MapPagesStart; // MapStart rounded down to page boundary\r
121 UINTN MapPagesEnd; // MapEnd rounded up to page boundary\r
122 UINTN MapPagesSize; // difference between MapPagesStart and MapPagesEnd\r
123\r
124 if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
125 return RETURN_UNSUPPORTED;\r
126 }\r
127\r
128 MapStart = SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET;\r
129 MapEnd = MapStart + sizeof (QEMU_SMRAM_SAVE_STATE_MAP);\r
130 MapPagesStart = MapStart & ~(UINTN)EFI_PAGE_MASK;\r
131 MapPagesEnd = ALIGN_VALUE (MapEnd, EFI_PAGE_SIZE);\r
132 MapPagesSize = MapPagesEnd - MapPagesStart;\r
133\r
134 ASSERT ((MapPagesSize & EFI_PAGE_MASK) == 0);\r
135\r
136 *BaseAddress = MapPagesStart;\r
137 *NumberOfPages = MapPagesSize >> EFI_PAGE_SHIFT;\r
138\r
139 return RETURN_SUCCESS;\r
140}\r