Ring3: Added necessary Core pages to User page table.

This commit is contained in:
Mikhail Krichanov 2024-11-27 18:03:30 +03:00
parent 285c6b0de9
commit c23d434619
7 changed files with 135 additions and 42 deletions

View File

@ -297,8 +297,7 @@ GetUefiImageRecord (
for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
ImageRecordLink != &mProtectedImageRecordList;
ImageRecordLink = ImageRecordLink->ForwardLink)
{
ImageRecordLink = ImageRecordLink->ForwardLink) {
ImageRecord = CR (
ImageRecordLink,
UEFI_IMAGE_RECORD,

View File

@ -18,9 +18,13 @@ RING3_DATA *gRing3Data;
VOID *gRing3Interfaces;
UINTN gUartBaseAddress;
UEFI_IMAGE_RECORD *mDxeRing3;
VOID *mUserPageTableTemplate;
UINTN mUserPageTableTemplateSize;
UEFI_IMAGE_RECORD *mDxeRing3;
VOID *mUserPageTableTemplate;
UINTN mUserPageTableTemplateSize;
EXCEPTION_ADDRESSES *mExceptionAddresses;
extern UINTN SysCallBase;
extern UINTN SysCallEnd;
VOID
EFIAPI
@ -193,6 +197,8 @@ InitializeRing3 (
MakeUserPageTableTemplate (&mUserPageTableTemplate, &mUserPageTableTemplateSize);
mExceptionAddresses = GetExceptionAddresses ();
return Status;
}
@ -255,32 +261,59 @@ InitializeUserPageTable (
}
//
// Map CoreBootServices
// Map CoreBootServices, gCoreSysCallStackBase, ExceptionHandlers, ExceptionStacks
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
(EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices,
SIZE_4KB,
(UINTN)&SysCallBase,
(UINTN)&SysCallEnd - (UINTN)&SysCallBase,
EFI_MEMORY_RO
);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
(EFI_PHYSICAL_ADDRESS)(UINTN)&gCorePageTable,
(UINTN)&gCorePageTable,
SIZE_4KB,
EFI_MEMORY_RO | EFI_MEMORY_XP
);
//
// Map ExceptionHandlerAsm: AsmIdtVectorBegin - AsmGetTemplateAddressMap
// mCorePageTable, gCoreSysCallStackTop
//
// gCpu->SetUserMemoryAttributes (gCpu, (UINTN)PageMap, BaseAddress, SIZE_4KB, EFI_MEMORY_RO);
//
// gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP);
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
(UINTN)gCoreSysCallStackBase,
EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE,
EFI_MEMORY_XP
);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mExceptionAddresses->ExceptionStackBase,
mExceptionAddresses->ExceptionStackSize,
EFI_MEMORY_XP
);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mExceptionAddresses->ExceptionHandlerBase,
mExceptionAddresses->ExceptionHandlerSize,
EFI_MEMORY_RO
);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mExceptionAddresses->ExceptionDataBase,
SIZE_4KB,
EFI_MEMORY_XP
);
//
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,

View File

@ -62,18 +62,7 @@ GoToRing3 (
VA_END (Marker);
ForbidSupervisorAccessToUserMemory ();
#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32)
if (Number == 2) {
//
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
//
SetUefiImageMemoryAttributes (
FixedPcdGet32 (PcdOvmfWorkAreaBase),
FixedPcdGet32 (PcdOvmfWorkAreaSize),
EFI_MEMORY_XP | EFI_MEMORY_USER
);
}
#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM)
#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM)
//
// Necessary fix for DEBUG printings.
//
@ -85,15 +74,7 @@ GoToRing3 (
#endif
Status = CallRing3 (Input);
#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32)
if (Number == 2) {
SetUefiImageMemoryAttributes (
FixedPcdGet32 (PcdOvmfWorkAreaBase),
FixedPcdGet32 (PcdOvmfWorkAreaSize),
EFI_MEMORY_XP
);
}
#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM)
#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM)
AllowSupervisorAccessToUserMemory ();
SetUefiImageMemoryAttributes (
gUartBaseAddress,

View File

@ -106,6 +106,10 @@ copy:
mov gs, ax
%endmacro
ALIGN 4096
global ASM_PFX(SysCallBase)
ASM_PFX(SysCallBase):
;------------------------------------------------------------------------------
; EFI_STATUS
; EFIAPI
@ -123,8 +127,6 @@ copy:
;
; (On User Stack) Argument 4, 5, ...
;------------------------------------------------------------------------------
ALIGN 4096
global ASM_PFX(CoreBootServices)
ASM_PFX(CoreBootServices):
mov rax, [ASM_PFX(gCorePageTable)]
@ -233,6 +235,10 @@ ASM_PFX(CallRing3):
; Pass control to user image
o64 sysret
ALIGN 4096
global ASM_PFX(SysCallEnd)
ASM_PFX(SysCallEnd):
;------------------------------------------------------------------------------
; VOID
; EFIAPI
@ -267,5 +273,6 @@ global ASM_PFX(gUserPageTable)
ASM_PFX(gUserPageTable):
resq 1
ALIGN 4096
ASM_PFX(CoreRsp):
resq 1

View File

@ -13,6 +13,14 @@
#include <Ppi/VectorHandoffInfo.h>
#include <Protocol/Cpu.h>
typedef struct {
UINTN ExceptionStackBase;
UINTN ExceptionStackSize;
UINTN ExceptionHandlerBase;
UINTN ExceptionHandlerSize;
UINTN ExceptionDataBase;
} EXCEPTION_ADDRESSES;
/**
Initializes all CPU exceptions entries and provides the default exception handlers.
@ -99,4 +107,10 @@ DumpCpuContext (
IN EFI_SYSTEM_CONTEXT SystemContext
);
EXCEPTION_ADDRESSES *
EFIAPI
GetExceptionAddresses (
VOID
);
#endif

View File

@ -30,6 +30,13 @@ UINT8 mBuffer[CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE
STATIC CONST EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *mDebugImageInfoTable = NULL;
EXCEPTION_ADDRESSES mAddresses;
extern UINTN ExceptionHandlerBase;
extern UINTN ExceptionHandlerEnd;
extern UINT8 mSwitchCr3Flag;
extern UINTN CorePageTable;
/**
Common exception handler.
@ -129,13 +136,17 @@ InitializeSeparateExceptionStacks (
UINTN LocalBufferSize;
EFI_STATUS Status;
mAddresses.ExceptionStackSize = CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE;
if ((Buffer == NULL) && (BufferSize == NULL)) {
SetMem (mBuffer, sizeof (mBuffer), 0);
LocalBufferSize = sizeof (mBuffer);
Status = ArchSetupExceptionStack (mBuffer, &LocalBufferSize);
ASSERT_EFI_ERROR (Status);
mAddresses.ExceptionStackBase = (UINTN)mBuffer;
return Status;
} else {
mAddresses.ExceptionStackBase = (UINTN)Buffer;
return ArchSetupExceptionStack (Buffer, BufferSize);
}
}
@ -189,3 +200,20 @@ GetImageInfoByIp (
return FALSE;
}
EXCEPTION_ADDRESSES *
EFIAPI
GetExceptionAddresses (
VOID
)
{
mSwitchCr3Flag = 1;
mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase;
mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase;
mAddresses.ExceptionDataBase = (UINTN)&CorePageTable;
CorePageTable = AsmReadCr3 ();
return &mAddresses;
}

View File

@ -53,11 +53,27 @@ extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
extern ASM_PFX(CommonExceptionHandler)
SECTION .data
ALIGN 4096
global ASM_PFX(CorePageTable)
ASM_PFX(CorePageTable):
resq 1
global ASM_PFX(UserPageTable)
ASM_PFX(UserPageTable):
resq 1
ALIGN 4096
global ASM_PFX(mSwitchCr3Flag)
ASM_PFX(mSwitchCr3Flag):
db 0x0
DEFAULT REL
SECTION .text
ALIGN 8
ALIGN 4096
global ASM_PFX(ExceptionHandlerBase)
ASM_PFX(ExceptionHandlerBase):
; Generate NUM_VECTORS IDT vectors.
AsmIdtVectorBegin:
@ -121,6 +137,14 @@ HookAfterStubHeaderEnd:
global ASM_PFX(CommonInterruptEntry)
ASM_PFX(CommonInterruptEntry):
cli
cmp byte [ASM_PFX(mSwitchCr3Flag)], 0
jz NoCr3Switch
mov rax, cr3
mov [ASM_PFX(UserPageTable)], rax
mov rax, [ASM_PFX(CorePageTable)]
mov cr3, rax
NoCr3Switch:
pop rax
;
; All interrupt handlers are invoked through interrupt gates, so
@ -436,8 +460,8 @@ CetDone:
push rcx
mov rcx, ds
and rcx, 3
pop rcx
jnz ReturnToRing3
pop rcx
mov rsp, rbp
pop rbp
@ -466,11 +490,18 @@ DoReturn:
DoIret:
iretq
ReturnToRing3:
mov rcx, [ASM_PFX(UserPageTable)]
mov cr3, rcx
pop rcx
mov rsp, rbp
pop rbp
add rsp, 16
iretq
ALIGN 4096
global ASM_PFX(ExceptionHandlerEnd)
ASM_PFX(ExceptionHandlerEnd):
;-------------------------------------------------------------------------------------
; GetTemplateAddressMap (&AddressMap);
;-------------------------------------------------------------------------------------