]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/AmdSev.c
4dc5340caa7a2814e8914ecfa7a3a6deb12acbd8
[mirror_edk2.git] / OvmfPkg / PlatformPei / AmdSev.c
1 /**@file
2 Initialize Secure Encrypted Virtualization (SEV) support
3
4 Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9 //
10 // The package level header files this module uses
11 //
12 #include <IndustryStandard/Q35MchIch9.h>
13 #include <Library/DebugLib.h>
14 #include <Library/HobLib.h>
15 #include <Library/MemEncryptSevLib.h>
16 #include <Library/PcdLib.h>
17 #include <PiPei.h>
18 #include <Register/Amd/Cpuid.h>
19 #include <Register/Cpuid.h>
20 #include <Register/Intel/SmramSaveStateMap.h>
21
22 #include "Platform.h"
23
24 /**
25
26 Initialize SEV-ES support if running as an SEV-ES guest.
27
28 **/
29 STATIC
30 VOID
31 AmdSevEsInitialize (
32 VOID
33 )
34 {
35 RETURN_STATUS PcdStatus;
36
37 if (!MemEncryptSevEsIsEnabled ()) {
38 return;
39 }
40
41 PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
42 ASSERT_RETURN_ERROR (PcdStatus);
43 }
44
45 /**
46
47 Function checks if SEV support is available, if present then it sets
48 the dynamic PcdPteMemoryEncryptionAddressOrMask with memory encryption mask.
49
50 **/
51 VOID
52 AmdSevInitialize (
53 VOID
54 )
55 {
56 CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx;
57 UINT64 EncryptionMask;
58 RETURN_STATUS PcdStatus;
59
60 //
61 // Check if SEV is enabled
62 //
63 if (!MemEncryptSevIsEnabled ()) {
64 return;
65 }
66
67 //
68 // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
69 //
70 AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
71 EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
72
73 //
74 // Set Memory Encryption Mask PCD
75 //
76 PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask);
77 ASSERT_RETURN_ERROR (PcdStatus);
78
79 DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask));
80
81 //
82 // Set Pcd to Deny the execution of option ROM when security
83 // violation.
84 //
85 PcdStatus = PcdSet32S (PcdOptionRomImageVerificationPolicy, 0x4);
86 ASSERT_RETURN_ERROR (PcdStatus);
87
88 //
89 // When SMM is required, cover the pages containing the initial SMRAM Save
90 // State Map with a memory allocation HOB:
91 //
92 // There's going to be a time interval between our decrypting those pages for
93 // SMBASE relocation and re-encrypting the same pages after SMBASE
94 // relocation. We shall ensure that the DXE phase stay away from those pages
95 // until after re-encryption, in order to prevent an information leak to the
96 // hypervisor.
97 //
98 if (FeaturePcdGet (PcdSmmSmramRequire) && (mBootMode != BOOT_ON_S3_RESUME)) {
99 RETURN_STATUS LocateMapStatus;
100 UINTN MapPagesBase;
101 UINTN MapPagesCount;
102
103 LocateMapStatus = MemEncryptSevLocateInitialSmramSaveStateMapPages (
104 &MapPagesBase,
105 &MapPagesCount
106 );
107 ASSERT_RETURN_ERROR (LocateMapStatus);
108
109 if (mQ35SmramAtDefaultSmbase) {
110 //
111 // The initial SMRAM Save State Map has been covered as part of a larger
112 // reserved memory allocation in InitializeRamRegions().
113 //
114 ASSERT (SMM_DEFAULT_SMBASE <= MapPagesBase);
115 ASSERT (
116 (MapPagesBase + EFI_PAGES_TO_SIZE (MapPagesCount) <=
117 SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE)
118 );
119 } else {
120 BuildMemoryAllocationHob (
121 MapPagesBase, // BaseAddress
122 EFI_PAGES_TO_SIZE (MapPagesCount), // Length
123 EfiBootServicesData // MemoryType
124 );
125 }
126 }
127
128 //
129 // Check and perform SEV-ES initialization if required.
130 //
131 AmdSevEsInitialize ();
132 }