Ring3: Moved platform dependant initialization to separate files.

This commit is contained in:
Mikhail Krichanov 2024-03-15 15:43:21 +03:00
parent 0ce839dc64
commit 9bf5a1d5f0
7 changed files with 192 additions and 53 deletions

View File

@ -274,6 +274,7 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage;
extern RING3_DATA *gRing3Data;
extern VOID *gRing3Interfaces;
extern VOID *gCoreSysCallStackBase;
extern VOID *gCoreSysCallStackTop;
extern VOID *gRing3CallStackBase;
//

View File

@ -71,9 +71,11 @@
SysCall/SupportedProtocols.c
[Sources.IA32]
SysCall/IA32/InitializeMsr.c
SysCall/IA32/CoreBootServices.nasm
[Sources.X64]
SysCall/X64/InitializeMsr.c
SysCall/X64/CoreBootServices.nasm
[Packages]

View File

@ -0,0 +1,62 @@
/** @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 (
VOID
)
{
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.
// SMEP and SMAP must be supported.
//
AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL);
//
// SYSENTER and SYSEXIT must be also supported.
//
AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx);
if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) {
Cr4.UintN = AsmReadCr4 ();
Cr4.Bits.SMAP = 1;
Cr4.Bits.SMEP = 1;
AsmWriteCr4 (Cr4.UintN);
Eflags.UintN = AsmReadEflags ();
Eflags.Bits.AC = 0;
AsmWriteEflags (Eflags.UintN);
} else {
DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n"));
ASSERT (FALSE);
}
//
// 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);
}

View File

@ -7,8 +7,6 @@
#include "DxeMain.h"
#include <Register/Intel/ArchitecturalMsr.h>
VOID *gCoreSysCallStackTop;
VOID *gCoreSysCallStackBase;
VOID *gRing3CallStackTop;
@ -17,6 +15,12 @@ VOID *gRing3EntryPoint;
RING3_DATA *gRing3Data;
VOID *gRing3Interfaces;
VOID
EFIAPI
InitializeMsr (
VOID
);
EFI_STATUS
EFIAPI
InitializeRing3 (
@ -27,15 +31,6 @@ InitializeRing3 (
EFI_STATUS Status;
VOID *TopOfStack;
UINTN SizeOfStack;
UINT64 Msr;
IA32_CR4 Cr4;
IA32_EFLAGS32 Eflags;
UINT32 Ebx;
UINT32 Edx;
MSR_IA32_EFER_REGISTER MsrEfer;
Ebx = 0;
Edx = 0;
//
// Set Ring3 EntryPoint and BootServices.
@ -75,32 +70,6 @@ InitializeRing3 (
return Status;
}
//
// Forbid supervisor-mode accesses to any user-mode pages.
// SMEP and SMAP must be supported.
//
AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL);
//
// SYSCALL and SYSRET must be also supported.
//
AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx);
if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) {
Cr4.UintN = AsmReadCr4 ();
Cr4.Bits.SMAP = 1;
Cr4.Bits.SMEP = 1;
AsmWriteCr4 (Cr4.UintN);
Eflags.UintN = AsmReadEflags ();
Eflags.Bits.AC = 0;
AsmWriteEflags (Eflags.UintN);
//
// Enable SYSCALL and SYSRET.
//
MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
MsrEfer.Bits.SCE = 1;
AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64);
}
SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE;
//
@ -137,19 +106,7 @@ InitializeRing3 (
SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER);
DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop));
//
// Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET.
//
Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32;
AsmWriteMsr64 (MSR_IA32_STAR, Msr);
Msr = (UINT64)(UINTN)CoreBootServices;
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
//
// Disable maskable interrupts at SYSCALL.
//
Msr = (UINT64)BIT9;
AsmWriteMsr64 (MSR_IA32_FMASK, Msr);
InitializeMsr ();
return Status;
}

View File

@ -0,0 +1,70 @@
/** @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 (
VOID
)
{
UINT64 Msr;
IA32_CR4 Cr4;
IA32_EFLAGS32 Eflags;
UINT32 Ebx;
UINT32 Edx;
MSR_IA32_EFER_REGISTER MsrEfer;
Ebx = 0;
Edx = 0;
//
// Forbid supervisor-mode accesses to any user-mode pages.
// SMEP and SMAP must be supported.
//
AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL);
//
// SYSCALL and SYSRET must be also supported.
//
AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx);
if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) {
Cr4.UintN = AsmReadCr4 ();
Cr4.Bits.SMAP = 1;
Cr4.Bits.SMEP = 1;
AsmWriteCr4 (Cr4.UintN);
Eflags.UintN = AsmReadEflags ();
Eflags.Bits.AC = 0;
AsmWriteEflags (Eflags.UintN);
//
// Enable SYSCALL and SYSRET.
//
MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
MsrEfer.Bits.SCE = 1;
AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64);
} else {
DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n"));
ASSERT (FALSE);
}
//
// Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET.
//
Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32;
AsmWriteMsr64 (MSR_IA32_STAR, Msr);
Msr = (UINT64)(UINTN)CoreBootServices;
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
//
// Disable maskable interrupts at SYSCALL.
//
Msr = (UINT64)BIT9;
AsmWriteMsr64 (MSR_IA32_FMASK, Msr);
}

View File

@ -5560,8 +5560,10 @@ typedef struct {
SEGMENT_DESCRIPTOR Null;
DATA_SEGMENT_32 Linear;
CODE_SEGMENT_32 LinearCode;
DATA_SEGMENT_32 SysData;
CODE_SEGMENT_32 SysCode;
DATA_SEGMENT_32 SysData;
CODE_SEGMENT_32 Ring3Code32;
DATA_SEGMENT_32 Ring3Data32;
CODE_SEGMENT_32 SysCode16;
CODE_SEGMENT_64 LinearCode64;
DATA_SEGMENT_32 LinearData64;
@ -5572,6 +5574,11 @@ typedef struct {
#pragma pack ()
#define RING0_DATA32_SEL OFFSET_OF (GDT, SysData)
#define RING0_CODE32_SEL OFFSET_OF (GDT, SysCode)
#define RING3_DATA32_SEL OFFSET_OF (GDT, Ring3Data32)
#define RING3_CODE32_SEL OFFSET_OF (GDT, Ring3Code32)
#define RING0_DATA64_SEL OFFSET_OF (GDT, LinearData64)
#define RING0_CODE64_SEL OFFSET_OF (GDT, LinearCode64)
#define RING3_DATA64_SEL OFFSET_OF (GDT, Ring3Data64)

View File

@ -69,6 +69,26 @@ STATIC GDT mGdtTemplate = {
.Granularity = 1,
.BaseAddress_31_24 = 0x0
},
.SysCode = {
.SegmentLimit_15_0 = 0xFFFF,
.BaseAddress_15_0 = 0x0,
.BaseAddress_23_16 = 0x0,
.Accessed = 0,
.Readable = 1,
.Conforming = 0,
.IsCode = 1,
.IsNotSystemSegment = 1,
.DescriptorPrivilegeLevel = 0,
.SegmentPresent = 1,
.SegmentLimit_19_16 = 0xF,
.Available = 0,
.Reserved = 0,
.Is32Bit = 1,
.Granularity = 1,
.BaseAddress_31_24 = 0x0
},
.SysData = {
.SegmentLimit_15_0 = 0xFFFF,
.BaseAddress_15_0 = 0x0,
@ -89,7 +109,7 @@ STATIC GDT mGdtTemplate = {
.Granularity = 1,
.BaseAddress_31_24 = 0x0
},
.SysCode = {
.Ring3Code32 = {
.SegmentLimit_15_0 = 0xFFFF,
.BaseAddress_15_0 = 0x0,
.BaseAddress_23_16 = 0x0,
@ -99,7 +119,7 @@ STATIC GDT mGdtTemplate = {
.Conforming = 0,
.IsCode = 1,
.IsNotSystemSegment = 1,
.DescriptorPrivilegeLevel = 0,
.DescriptorPrivilegeLevel = 3,
.SegmentPresent = 1,
.SegmentLimit_19_16 = 0xF,
@ -109,6 +129,26 @@ STATIC GDT mGdtTemplate = {
.Granularity = 1,
.BaseAddress_31_24 = 0x0
},
.Ring3Data32 = {
.SegmentLimit_15_0 = 0xFFFF,
.BaseAddress_15_0 = 0x0,
.BaseAddress_23_16 = 0x0,
.Accessed = 1,
.Writable = 1,
.ExpansionDirection = 0,
.IsCode = 0,
.IsNotSystemSegment = 1,
.DescriptorPrivilegeLevel = 3,
.SegmentPresent = 1,
.SegmentLimit_19_16 = 0xF,
.Available = 0,
.Reserved = 0,
.UpperBound = 1,
.Granularity = 1,
.BaseAddress_31_24 = 0x0
},
.SysCode16 = {
.SegmentLimit_15_0 = 0xFFFF,
.BaseAddress_15_0 = 0x0,