audk/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c
2025-04-14 12:12:47 +03:00

74 lines
1.7 KiB
C

/** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include "DxeMain.h"
#include <Register/Intel/ArchitecturalMsr.h>
VOID
EFIAPI
InitializeMsr (
IN OUT EFI_CONFIGURATION_TABLE *Table,
IN UINTN NumberOfEntries
)
{
UINT64 Msr;
IA32_CR4 Cr4;
IA32_EFLAGS32 Eflags;
UINT32 Ebx;
UINT32 Edx;
Ebx = 0;
Edx = 0;
//
// Forbid supervisor-mode accesses to any user-mode pages.
//
AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL);
if ((Ebx & BIT7) != 0) {
Cr4.UintN = AsmReadCr4 ();
Cr4.Bits.SMEP = 1;
AsmWriteCr4 (Cr4.UintN);
Eflags.UintN = AsmReadEflags ();
Eflags.Bits.AC = 0;
AsmWriteEflags (Eflags.UintN);
}
if ((Ebx & BIT20) != 0) {
Cr4.UintN = AsmReadCr4 ();
Cr4.Bits.SMAP = 1;
AsmWriteCr4 (Cr4.UintN);
Eflags.UintN = AsmReadEflags ();
Eflags.Bits.AC = 0;
AsmWriteEflags (Eflags.UintN);
}
//
// SYSENTER and SYSEXIT must be supported.
//
AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx);
if ((Edx & BIT11) == 0) {
DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n"));
CpuDeadLoop ();
}
//
// Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and
// MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT.
//
Msr = RING0_CODE32_SEL;
AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr);
Msr = (UINT64)(UINTN)CoreBootServices;
AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr);
Msr = (UINT64)(UINTN)gCoreSysCallStackTop;
AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr);
}