1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/** @file
Map TPM MMIO range unencrypted when SEV-ES is active.
Install gOvmfTpmMmioAccessiblePpiGuid unconditionally.
Copyright (C) 2021, Advanced Micro Devices, Inc.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <Library/DebugLib.h>
#include <Library/MemEncryptSevLib.h>
#include <Library/PcdLib.h>
#include <Library/PeiServicesLib.h>
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpmMmioRangeAccessible = {
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gOvmfTpmMmioAccessiblePpiGuid,
NULL
};
/**
The entry point for TPM MMIO range mapping driver.
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@retval EFI_ABORTED No need to keep this PEIM resident
**/
EFI_STATUS
EFIAPI
TpmMmioSevDecryptPeimEntryPoint (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
RETURN_STATUS DecryptStatus;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "%a\n", __FUNCTION__));
//
// If SEV is active, MMIO succeeds against an encrypted physical address
// because the nested page fault (NPF) that occurs on access does not
// include the encryption bit in the guest physical address provided to the
// hypervisor.
//
// If SEV-ES is active, MMIO would succeed against an encrypted physical
// address because the #VC handler uses the virtual address (which is an
// identity mapped physical address without the encryption bit) as the guest
// physical address of the MMIO target in the VMGEXIT.
//
// However, if SEV-ES is active, before performing the actual MMIO, an
// additional MMIO mitigation check is performed in the #VC handler to ensure
// that MMIO is being done to/from an unencrypted address. To prevent guest
// termination in this scenario, mark the range unencrypted ahead of access.
//
if (MemEncryptSevEsIsEnabled ()) {
DEBUG ((
DEBUG_INFO,
"%a: mapping TPM MMIO address range unencrypted\n",
__FUNCTION__
));
DecryptStatus = MemEncryptSevClearMmioPageEncMask (
0,
FixedPcdGet64 (PcdTpmBaseAddress),
EFI_SIZE_TO_PAGES ((UINTN)0x5000)
);
if (RETURN_ERROR (DecryptStatus)) {
DEBUG ((
DEBUG_ERROR,
"%a: failed to map TPM MMIO address range unencrypted\n",
__FUNCTION__
));
ASSERT_RETURN_ERROR (DecryptStatus);
}
}
//
// MMIO range available
//
Status = PeiServicesInstallPpi (&mTpmMmioRangeAccessible);
ASSERT_EFI_ERROR (Status);
return EFI_ABORTED;
}
|