Skip to content

Commit

Permalink
OvmfPkg/Sec: Setup MTRR early in the boot process.
Browse files Browse the repository at this point in the history
Specifically before running lzma uncompress of the main firmware volume.
This is needed to make sure caching is enabled, otherwise the uncompress
can be extremely slow.

Adapt the ASSERTs and MTRR setup in PlatformInitLib to the changes.

Background:  Depending on virtual machine configuration kvm may uses EPT
memory types to apply guest MTRR settings.  In case MTRRs are disabled
kvm will use the uncachable memory type for all mappings.  The
vmx_get_mt_mask() function in the linux kernel handles this and can be
found here:

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/x86/kvm/vmx/vmx.c?h=v6.7.1#n7580

In most VM configurations kvm uses MTRR_TYPE_WRBACK unconditionally.  In
case the VM has a mdev device assigned that is not the case though.

Before commit e8aa4c6 ("UefiCpuPkg/ResetVector: Cache Disable
should not be set by default in CR0") kvm also ended up using
MTRR_TYPE_WRBACK due to KVM_X86_QUIRK_CD_NW_CLEARED.  After that commit
kvm evaluates guest mtrr settings, which why setting up MTRRs early is
important now.

Signed-off-by: Gerd Hoffmann <[email protected]>
  • Loading branch information
kraxel authored and mergify[bot] committed Jun 26, 2024
1 parent e21bfae commit ce4c76e
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 10 deletions.
10 changes: 5 additions & 5 deletions OvmfPkg/Bhyve/PlatformPei/MemDetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,18 +511,18 @@ QemuInitializeRam (
MtrrGetAllMtrrs (&MtrrSettings);

//
// MTRRs disabled, fixed MTRRs disabled, default type is uncached
// See SecMtrrSetup(), default type should be write back
//
ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0);
ASSERT ((MtrrSettings.MtrrDefType & BIT11) != 0);
ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0);
ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0);
ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == MTRR_CACHE_WRITE_BACK);

//
// flip default type to writeback
//
SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06);
SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, MTRR_CACHE_WRITE_BACK);
ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables);
MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6;
MtrrSettings.MtrrDefType |= BIT10;
MtrrSetAllMtrrs (&MtrrSettings);

//
Expand Down
32 changes: 32 additions & 0 deletions OvmfPkg/IntelTdx/Sec/SecMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <Library/TdxHelperLib.h>
#include <Library/CcProbeLib.h>
#include <Library/PeilessStartupLib.h>
#include <Register/Intel/ArchitecturalMsr.h>
#include <Register/Intel/Cpuid.h>

#define SEC_IDT_ENTRY_COUNT 34

Expand All @@ -47,6 +49,31 @@ IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
}
};

//
// Enable MTRR early, set default type to write back.
// Needed to make sure caching is enabled,
// without this lzma decompress can be very slow.
//
STATIC
VOID
SecMtrrSetup (
VOID
)
{
CPUID_VERSION_INFO_EDX Edx;
MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType;

AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32);
if (!Edx.Bits.MTRR) {
return;
}

DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
DefType.Bits.Type = 6; /* write back */
DefType.Bits.E = 1; /* enable */
AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64);
}

VOID
EFIAPI
SecCoreStartupWithStack (
Expand Down Expand Up @@ -203,6 +230,11 @@ SecCoreStartupWithStack (
InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
DisableApicTimerInterrupt ();

//
// Initialize MTRR
//
SecMtrrSetup ();

PeilessStartup (&SecCoreData);

ASSERT (FALSE);
Expand Down
10 changes: 5 additions & 5 deletions OvmfPkg/Library/PlatformInitLib/MemDetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,18 +1175,18 @@ PlatformQemuInitializeRam (
MtrrGetAllMtrrs (&MtrrSettings);

//
// MTRRs disabled, fixed MTRRs disabled, default type is uncached
// See SecMtrrSetup(), default type should be write back
//
ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0);
ASSERT ((MtrrSettings.MtrrDefType & BIT11) != 0);
ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0);
ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0);
ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == MTRR_CACHE_WRITE_BACK);

//
// flip default type to writeback
//
SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06);
SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, MTRR_CACHE_WRITE_BACK);
ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables);
MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6;
MtrrSettings.MtrrDefType |= BIT10;
MtrrSetAllMtrrs (&MtrrSettings);

//
Expand Down
32 changes: 32 additions & 0 deletions OvmfPkg/Sec/SecMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <Ppi/MpInitLibDep.h>
#include <Library/TdxHelperLib.h>
#include <Library/CcProbeLib.h>
#include <Register/Intel/ArchitecturalMsr.h>
#include <Register/Intel/Cpuid.h>
#include "AmdSev.h"

#define SEC_IDT_ENTRY_COUNT 34
Expand Down Expand Up @@ -743,6 +745,31 @@ FindAndReportEntryPoints (
return;
}

//
// Enable MTRR early, set default type to write back.
// Needed to make sure caching is enabled,
// without this lzma decompress can be very slow.
//
STATIC
VOID
SecMtrrSetup (
VOID
)
{
CPUID_VERSION_INFO_EDX Edx;
MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType;

AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32);
if (!Edx.Bits.MTRR) {
return;
}

DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
DefType.Bits.Type = 6; /* write back */
DefType.Bits.E = 1; /* enable */
AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64);
}

VOID
EFIAPI
SecCoreStartupWithStack (
Expand Down Expand Up @@ -942,6 +969,11 @@ SecCoreStartupWithStack (
InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
DisableApicTimerInterrupt ();

//
// Initialize MTRR
//
SecMtrrSetup ();

//
// Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
//
Expand Down

0 comments on commit ce4c76e

Please sign in to comment.