summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UefiCpuPkg/Library/MtrrLib/MtrrLib.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
index e5c862c83d..a66357e305 100644
--- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
+++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -756,8 +756,11 @@ MtrrLibInitializeMtrrMask (
OUT UINT64 *MtrrValidAddressMask
)
{
- UINT32 MaxExtendedFunction;
- CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
+ UINT32 MaxExtendedFunction;
+ CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
+ UINT32 MaxFunction;
+ CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX ExtendedFeatureFlagsEcx;
+ MSR_IA32_TME_ACTIVATE_REGISTER TmeActivate;
AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL);
@@ -767,6 +770,23 @@ MtrrLibInitializeMtrrMask (
VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
}
+ //
+ // CPUID enumeration of MAX_PA is unaffected by TME-MK activation and will continue
+ // to report the maximum physical address bits available for software to use,
+ // irrespective of the number of KeyID bits.
+ // So, we need to check if TME is enabled and adjust the PA size accordingly.
+ //
+ AsmCpuid (CPUID_SIGNATURE, &MaxFunction, NULL, NULL, NULL);
+ if (MaxFunction >= CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) {
+ AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, NULL, NULL, &ExtendedFeatureFlagsEcx.Uint32, NULL);
+ if (ExtendedFeatureFlagsEcx.Bits.TME_EN == 1) {
+ TmeActivate.Uint64 = AsmReadMsr64 (MSR_IA32_TME_ACTIVATE);
+ if (TmeActivate.Bits.TmeEnable == 1) {
+ VirPhyAddressSize.Bits.PhysicalAddressBits -= TmeActivate.Bits.MkTmeKeyidBits;
+ }
+ }
+ }
+
*MtrrValidBitsMask = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1;
*MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL;
}