mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-23 13:44:33 +02:00
Ring3: Added support for separate User address space.
This commit is contained in:
parent
983649444e
commit
3b8cd407d3
@ -229,6 +229,7 @@ typedef struct {
|
|||||||
|
|
||||||
VOID *HiiData;
|
VOID *HiiData;
|
||||||
BOOLEAN IsUserImage;
|
BOOLEAN IsUserImage;
|
||||||
|
UINTN UserPageTable;
|
||||||
} LOADED_IMAGE_PRIVATE_DATA;
|
} LOADED_IMAGE_PRIVATE_DATA;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -288,6 +289,10 @@ extern VOID *gCoreSysCallStackTop;
|
|||||||
extern VOID *gRing3CallStackBase;
|
extern VOID *gRing3CallStackBase;
|
||||||
extern VOID *gRing3CallStackTop;
|
extern VOID *gRing3CallStackTop;
|
||||||
extern VOID *gRing3EntryPoint;
|
extern VOID *gRing3EntryPoint;
|
||||||
|
extern VOID *gUserPageTableTemplate;
|
||||||
|
extern UINTN gUserPageTableTemplateSize;
|
||||||
|
extern UINTN gUserPageTable;
|
||||||
|
extern UINTN gCorePageTable;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Service Initialization Functions
|
// Service Initialization Functions
|
||||||
@ -2777,4 +2782,10 @@ FreeProtocolsList (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
MakeUserPageTableTemplate (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -150,6 +150,7 @@
|
|||||||
gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB
|
gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB
|
||||||
gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall
|
gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall
|
||||||
gEarlyPL011BaseAddressGuid ## CONSUMES
|
gEarlyPL011BaseAddressGuid ## CONSUMES
|
||||||
|
gEfiHobPageTableInfoGuid ## CONSUMES ## HOB
|
||||||
|
|
||||||
[Ppis]
|
[Ppis]
|
||||||
gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB
|
gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB
|
||||||
|
@ -328,6 +328,8 @@ DxeMain (
|
|||||||
|
|
||||||
ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage);
|
ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage);
|
||||||
|
|
||||||
|
MakeUserPageTableTemplate ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Call constructor for all libraries
|
// Call constructor for all libraries
|
||||||
//
|
//
|
||||||
|
@ -1108,6 +1108,7 @@ CoreLoadImageCommon (
|
|||||||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
UINT8 ImageOrigin;
|
UINT8 ImageOrigin;
|
||||||
EFI_FV_FILE_ATTRIBUTES FileAttributes;
|
EFI_FV_FILE_ATTRIBUTES FileAttributes;
|
||||||
|
VOID *UserPageTable;
|
||||||
|
|
||||||
SecurityStatus = EFI_SUCCESS;
|
SecurityStatus = EFI_SUCCESS;
|
||||||
|
|
||||||
@ -1348,6 +1349,14 @@ CoreLoadImageCommon (
|
|||||||
Image->Info.ParentHandle = ParentImageHandle;
|
Image->Info.ParentHandle = ParentImageHandle;
|
||||||
Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0;
|
Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0;
|
||||||
|
|
||||||
|
if ((gRing3Data != NULL) && Image->IsUserImage) {
|
||||||
|
UserPageTable = AllocatePages (EFI_SIZE_TO_PAGES (gUserPageTableTemplateSize));
|
||||||
|
CopyMem (UserPageTable, gUserPageTableTemplate, gUserPageTableTemplateSize);
|
||||||
|
|
||||||
|
Image->UserPageTable = (UINTN)UserPageTable;
|
||||||
|
gUserPageTable = Image->UserPageTable;
|
||||||
|
}
|
||||||
|
|
||||||
if (NumberOfPages != NULL) {
|
if (NumberOfPages != NULL) {
|
||||||
Image->NumberOfPages = *NumberOfPages;
|
Image->NumberOfPages = *NumberOfPages;
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,6 +82,10 @@ SetUefiImageMemoryAttributes (
|
|||||||
|
|
||||||
ASSERT (gCpu != NULL);
|
ASSERT (gCpu != NULL);
|
||||||
gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes);
|
gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes);
|
||||||
|
|
||||||
|
if ((Attributes & EFI_MEMORY_USER) != 0) {
|
||||||
|
gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, BaseAddress, Length, FinalAttributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,6 +59,12 @@ InitializeRing3 (
|
|||||||
|
|
||||||
CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE));
|
CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE));
|
||||||
|
|
||||||
|
SetUefiImageMemoryAttributes (
|
||||||
|
(UINTN)gRing3Data,
|
||||||
|
ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE),
|
||||||
|
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||||
|
);
|
||||||
|
|
||||||
if (PcdGetBool (PcdSerialUseMmio)) {
|
if (PcdGetBool (PcdSerialUseMmio)) {
|
||||||
Status = CoreAllocatePages (
|
Status = CoreAllocatePages (
|
||||||
AllocateAnyPages,
|
AllocateAnyPages,
|
||||||
@ -124,6 +130,12 @@ InitializeRing3 (
|
|||||||
|
|
||||||
gRing3Interfaces = (VOID *)(UINTN)Physical;
|
gRing3Interfaces = (VOID *)(UINTN)Physical;
|
||||||
|
|
||||||
|
SetUefiImageMemoryAttributes (
|
||||||
|
(UINTN)gRing3Interfaces,
|
||||||
|
EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES),
|
||||||
|
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||||
|
);
|
||||||
|
|
||||||
SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE;
|
SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -141,6 +153,9 @@ InitializeRing3 (
|
|||||||
gCoreSysCallStackTop = TopOfStack;
|
gCoreSysCallStackTop = TopOfStack;
|
||||||
|
|
||||||
SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP);
|
SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP);
|
||||||
|
//
|
||||||
|
// gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP);
|
||||||
|
//
|
||||||
DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop));
|
DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop));
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -123,8 +123,13 @@ copy:
|
|||||||
;
|
;
|
||||||
; (On User Stack) Argument 4, 5, ...
|
; (On User Stack) Argument 4, 5, ...
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
ALIGN 4096
|
||||||
|
|
||||||
global ASM_PFX(CoreBootServices)
|
global ASM_PFX(CoreBootServices)
|
||||||
ASM_PFX(CoreBootServices):
|
ASM_PFX(CoreBootServices):
|
||||||
|
mov rax, [ASM_PFX(gCorePageTable)]
|
||||||
|
mov cr3, rax
|
||||||
|
|
||||||
; Switch from User to Core data segment selectors.
|
; Switch from User to Core data segment selectors.
|
||||||
mov ax, ss
|
mov ax, ss
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
@ -175,6 +180,8 @@ ASM_PFX(CoreBootServices):
|
|||||||
pop rbp
|
pop rbp
|
||||||
pop rsp
|
pop rsp
|
||||||
|
|
||||||
|
mov rdx, [ASM_PFX(gUserPageTable)]
|
||||||
|
mov cr3, rdx
|
||||||
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
||||||
o64 sysret
|
o64 sysret
|
||||||
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
||||||
@ -190,9 +197,9 @@ o64 sysret
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
global ASM_PFX(CallRing3)
|
global ASM_PFX(CallRing3)
|
||||||
ASM_PFX(CallRing3):
|
ASM_PFX(CallRing3):
|
||||||
|
cli
|
||||||
pushfq
|
pushfq
|
||||||
pop r11
|
pop r11
|
||||||
cli
|
|
||||||
; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15.
|
; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15.
|
||||||
push rbx
|
push rbx
|
||||||
push rbp
|
push rbp
|
||||||
@ -221,6 +228,8 @@ ASM_PFX(CallRing3):
|
|||||||
mov rsp, r8
|
mov rsp, r8
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
|
mov r8, [ASM_PFX(gUserPageTable)]
|
||||||
|
mov cr3, r8
|
||||||
; Pass control to user image
|
; Pass control to user image
|
||||||
o64 sysret
|
o64 sysret
|
||||||
|
|
||||||
@ -248,5 +257,15 @@ ASM_PFX(ReturnToCore):
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
SECTION .data
|
SECTION .data
|
||||||
|
ALIGN 4096
|
||||||
|
|
||||||
|
global ASM_PFX(gCorePageTable)
|
||||||
|
ASM_PFX(gCorePageTable):
|
||||||
|
resq 1
|
||||||
|
|
||||||
|
global ASM_PFX(gUserPageTable)
|
||||||
|
ASM_PFX(gUserPageTable):
|
||||||
|
resq 1
|
||||||
|
|
||||||
ASM_PFX(CoreRsp):
|
ASM_PFX(CoreRsp):
|
||||||
resq 1
|
resq 1
|
||||||
|
@ -8,6 +8,202 @@
|
|||||||
#include "DxeMain.h"
|
#include "DxeMain.h"
|
||||||
|
|
||||||
#include <Register/Intel/ArchitecturalMsr.h>
|
#include <Register/Intel/ArchitecturalMsr.h>
|
||||||
|
#include <IndustryStandard/PageTable.h>
|
||||||
|
|
||||||
|
VOID *gUserPageTableTemplate;
|
||||||
|
UINTN gUserPageTableTemplateSize;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
MakeUserPageTableTemplate (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_HOB_GUID_TYPE *GuidHob;
|
||||||
|
EFI_PAGE_TABLE_INFO *PageTableInfo;
|
||||||
|
UINTN BigPageAddress;
|
||||||
|
EFI_PHYSICAL_ADDRESS PageAddress;
|
||||||
|
UINTN IndexOfPml5Entries;
|
||||||
|
UINTN IndexOfPml4Entries;
|
||||||
|
UINTN IndexOfPdpEntries;
|
||||||
|
UINTN IndexOfPageDirectoryEntries;
|
||||||
|
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel5Entry;
|
||||||
|
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
|
||||||
|
PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
|
||||||
|
PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
|
||||||
|
PAGE_TABLE_ENTRY *PageDirectoryEntry;
|
||||||
|
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
|
||||||
|
|
||||||
|
GuidHob = GetFirstGuidHob (&gEfiHobPageTableInfoGuid);
|
||||||
|
if (GuidHob == NULL) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Core: Could not retrieve PageTableInfo HOB.\n"));
|
||||||
|
CpuDeadLoop ();
|
||||||
|
}
|
||||||
|
|
||||||
|
PageTableInfo = (EFI_PAGE_TABLE_INFO *)(GET_GUID_HOB_DATA (GuidHob));
|
||||||
|
|
||||||
|
BigPageAddress = (UINTN)AllocateAlignedPages (PageTableInfo->TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT);
|
||||||
|
if (BigPageAddress == 0) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Core: Could not allocate buffer for User page table.\n"));
|
||||||
|
CpuDeadLoop ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
|
||||||
|
//
|
||||||
|
PageMap = (VOID *)BigPageAddress;
|
||||||
|
if (PageTableInfo->Page5LevelEnabled) {
|
||||||
|
//
|
||||||
|
// By architecture only one PageMapLevel5 exists - so lets allocate storage for it.
|
||||||
|
//
|
||||||
|
PageMapLevel5Entry = PageMap;
|
||||||
|
BigPageAddress += SIZE_4KB;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageAddress = 0;
|
||||||
|
|
||||||
|
for ( IndexOfPml5Entries = 0
|
||||||
|
; IndexOfPml5Entries < PageTableInfo->NumberOfPml5EntriesNeeded
|
||||||
|
; IndexOfPml5Entries++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Each PML5 entry points to a page of PML4 entires.
|
||||||
|
// So lets allocate space for them and fill them in in the IndexOfPml4Entries loop.
|
||||||
|
// When 5-Level Paging is disabled, below allocation happens only once.
|
||||||
|
//
|
||||||
|
PageMapLevel4Entry = (VOID *)BigPageAddress;
|
||||||
|
BigPageAddress += SIZE_4KB;
|
||||||
|
|
||||||
|
if (PageTableInfo->Page5LevelEnabled) {
|
||||||
|
//
|
||||||
|
// Make a PML5 Entry
|
||||||
|
//
|
||||||
|
PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | PageTableInfo->AddressEncMask;
|
||||||
|
PageMapLevel5Entry->Bits.ReadWrite = 1;
|
||||||
|
PageMapLevel5Entry->Bits.UserSupervisor = 1;
|
||||||
|
PageMapLevel5Entry->Bits.Present = 1;
|
||||||
|
PageMapLevel5Entry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( IndexOfPml4Entries = 0
|
||||||
|
; IndexOfPml4Entries < (PageTableInfo->NumberOfPml5EntriesNeeded == 1 ? PageTableInfo->NumberOfPml4EntriesNeeded : 512)
|
||||||
|
; IndexOfPml4Entries++, PageMapLevel4Entry++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Each PML4 entry points to a page of Page Directory Pointer entires.
|
||||||
|
// So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
|
||||||
|
//
|
||||||
|
PageDirectoryPointerEntry = (VOID *)BigPageAddress;
|
||||||
|
BigPageAddress += SIZE_4KB;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make a PML4 Entry
|
||||||
|
//
|
||||||
|
PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | PageTableInfo->AddressEncMask;
|
||||||
|
PageMapLevel4Entry->Bits.ReadWrite = 1;
|
||||||
|
PageMapLevel4Entry->Bits.UserSupervisor = 1;
|
||||||
|
PageMapLevel4Entry->Bits.Present = 1;
|
||||||
|
|
||||||
|
if (PageTableInfo->Page1GSupport) {
|
||||||
|
PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry;
|
||||||
|
|
||||||
|
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
|
||||||
|
//
|
||||||
|
// Fill in the Page Directory entries
|
||||||
|
//
|
||||||
|
PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask;
|
||||||
|
PageDirectory1GEntry->Bits.ReadWrite = 1;
|
||||||
|
PageDirectory1GEntry->Bits.Present = 1;
|
||||||
|
PageDirectory1GEntry->Bits.MustBe1 = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for ( IndexOfPdpEntries = 0
|
||||||
|
; IndexOfPdpEntries < (PageTableInfo->NumberOfPml4EntriesNeeded == 1 ? PageTableInfo->NumberOfPdpEntriesNeeded : 512)
|
||||||
|
; IndexOfPdpEntries++, PageDirectoryPointerEntry++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Each Directory Pointer entries points to a page of Page Directory entires.
|
||||||
|
// So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
|
||||||
|
//
|
||||||
|
PageDirectoryEntry = (VOID *)BigPageAddress;
|
||||||
|
BigPageAddress += SIZE_4KB;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill in a Page Directory Pointer Entries
|
||||||
|
//
|
||||||
|
PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | PageTableInfo->AddressEncMask;
|
||||||
|
PageDirectoryPointerEntry->Bits.ReadWrite = 1;
|
||||||
|
PageDirectoryPointerEntry->Bits.UserSupervisor = 1;
|
||||||
|
PageDirectoryPointerEntry->Bits.Present = 1;
|
||||||
|
|
||||||
|
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
|
||||||
|
//
|
||||||
|
// Fill in the Page Directory entries
|
||||||
|
//
|
||||||
|
PageDirectoryEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask;
|
||||||
|
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||||
|
PageDirectoryEntry->Bits.Present = 0;
|
||||||
|
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill with null entry for unused PDPTE
|
||||||
|
//
|
||||||
|
ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// For the PML4 entries we are not using fill in a null entry.
|
||||||
|
//
|
||||||
|
ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PageTableInfo->Page5LevelEnabled) {
|
||||||
|
//
|
||||||
|
// For the PML5 entries we are not using fill in a null entry.
|
||||||
|
//
|
||||||
|
ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
|
||||||
|
}
|
||||||
|
|
||||||
|
gUserPageTableTemplate = (VOID *)PageMap;
|
||||||
|
gUserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT);
|
||||||
|
gUserPageTable = (UINTN)gUserPageTableTemplate;
|
||||||
|
|
||||||
|
SetUefiImageMemoryAttributes ((UINT64)PageMap, gUserPageTableTemplateSize, EFI_MEMORY_XP);
|
||||||
|
//
|
||||||
|
// Map CoreBootServices
|
||||||
|
//
|
||||||
|
gCpu->SetUserMemoryAttributes (
|
||||||
|
gCpu,
|
||||||
|
(UINTN)PageMap,
|
||||||
|
(EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices,
|
||||||
|
SIZE_4KB,
|
||||||
|
EFI_MEMORY_RO
|
||||||
|
);
|
||||||
|
|
||||||
|
gCpu->SetUserMemoryAttributes (
|
||||||
|
gCpu,
|
||||||
|
(UINTN)PageMap,
|
||||||
|
(EFI_PHYSICAL_ADDRESS)(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,
|
||||||
|
(UINTN)PageMap,
|
||||||
|
FixedPcdGet32 (PcdOvmfWorkAreaBase),
|
||||||
|
FixedPcdGet32 (PcdOvmfWorkAreaSize),
|
||||||
|
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
@ -26,6 +222,9 @@ InitializeMsr (
|
|||||||
Ebx = 0;
|
Ebx = 0;
|
||||||
Edx = 0;
|
Edx = 0;
|
||||||
|
|
||||||
|
// The Intel-64 and IA-32 architectures also allow for global pages when the PGE flag (bit 7) is 1 in CR4.
|
||||||
|
// PGE must be zero.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Forbid supervisor-mode accesses to any user-mode pages.
|
// Forbid supervisor-mode accesses to any user-mode pages.
|
||||||
//
|
//
|
||||||
@ -76,4 +275,6 @@ InitializeMsr (
|
|||||||
//
|
//
|
||||||
Msr = (UINT64)BIT9;
|
Msr = (UINT64)BIT9;
|
||||||
AsmWriteMsr64 (MSR_IA32_FMASK, Msr);
|
AsmWriteMsr64 (MSR_IA32_FMASK, Msr);
|
||||||
|
|
||||||
|
gCorePageTable = AsmReadCr3 ();
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
## SOMETIMES_PRODUCES ## HOB
|
## SOMETIMES_PRODUCES ## HOB
|
||||||
gEfiMemoryTypeInformationGuid
|
gEfiMemoryTypeInformationGuid
|
||||||
gUefiImageLoaderImageContextGuid
|
gUefiImageLoaderImageContextGuid
|
||||||
|
gEfiHobPageTableInfoGuid
|
||||||
|
|
||||||
[FeaturePcd.IA32]
|
[FeaturePcd.IA32]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
|
||||||
|
@ -705,6 +705,7 @@ CreateIdentityMappingPageTables (
|
|||||||
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
|
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
|
||||||
UINT64 AddressEncMask;
|
UINT64 AddressEncMask;
|
||||||
IA32_CR4 Cr4;
|
IA32_CR4 Cr4;
|
||||||
|
EFI_PAGE_TABLE_INFO PageTableInfo;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
|
// Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
|
||||||
@ -828,6 +829,16 @@ CreateIdentityMappingPageTables (
|
|||||||
(UINT64)TotalPagesNum
|
(UINT64)TotalPagesNum
|
||||||
));
|
));
|
||||||
|
|
||||||
|
PageTableInfo.NumberOfPml5EntriesNeeded = NumberOfPml5EntriesNeeded;
|
||||||
|
PageTableInfo.NumberOfPml4EntriesNeeded = NumberOfPml4EntriesNeeded;
|
||||||
|
PageTableInfo.NumberOfPdpEntriesNeeded = NumberOfPdpEntriesNeeded;
|
||||||
|
PageTableInfo.TotalPagesNum = TotalPagesNum;
|
||||||
|
PageTableInfo.Page5LevelEnabled = Page5LevelEnabled;
|
||||||
|
PageTableInfo.Page1GSupport = Page1GSupport;
|
||||||
|
PageTableInfo.AddressEncMask = AddressEncMask;
|
||||||
|
|
||||||
|
BuildGuidDataHob (&gEfiHobPageTableInfoGuid, &PageTableInfo, sizeof (EFI_PAGE_TABLE_INFO));
|
||||||
|
|
||||||
BigPageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum);
|
BigPageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum);
|
||||||
ASSERT (BigPageAddress != 0);
|
ASSERT (BigPageAddress != 0);
|
||||||
|
|
||||||
|
@ -21,8 +21,12 @@
|
|||||||
#define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \
|
#define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \
|
||||||
{0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} }
|
{0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} }
|
||||||
|
|
||||||
|
#define EFI_HOB_PAGE_TABLE_INFO_GUID \
|
||||||
|
{0xac992fe9, 0xb0cc, 0x45df, {0xae, 0xcf, 0x51, 0x5a, 0xd2, 0xc4, 0xe8, 0xb3} }
|
||||||
|
|
||||||
extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid;
|
extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid;
|
||||||
extern EFI_GUID gEfiHobMemoryAllocStackGuid;
|
extern EFI_GUID gEfiHobMemoryAllocStackGuid;
|
||||||
extern EFI_GUID gEfiHobMemoryAllocModuleGuid;
|
extern EFI_GUID gEfiHobMemoryAllocModuleGuid;
|
||||||
|
extern EFI_GUID gEfiHobPageTableInfoGuid;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,6 +14,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
#ifndef __MEMORY_ALLOCATION_LIB_H__
|
#ifndef __MEMORY_ALLOCATION_LIB_H__
|
||||||
#define __MEMORY_ALLOCATION_LIB_H__
|
#define __MEMORY_ALLOCATION_LIB_H__
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT32 NumberOfPml5EntriesNeeded;
|
||||||
|
UINT32 NumberOfPml4EntriesNeeded;
|
||||||
|
UINT32 NumberOfPdpEntriesNeeded;
|
||||||
|
UINTN TotalPagesNum;
|
||||||
|
BOOLEAN Page5LevelEnabled;
|
||||||
|
BOOLEAN Page1GSupport;
|
||||||
|
UINT64 AddressEncMask;
|
||||||
|
} EFI_PAGE_TABLE_INFO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Allocates one or more 4KB pages of type EfiBootServicesData.
|
Allocates one or more 4KB pages of type EfiBootServicesData.
|
||||||
|
|
||||||
|
@ -258,6 +258,16 @@ EFI_STATUS
|
|||||||
OUT UINT64 *Attributes
|
OUT UINT64 *Attributes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
EFI_STATUS
|
||||||
|
(EFIAPI *EFI_CPU_SET_USER_MEMORY_ATTRIBUTES)(
|
||||||
|
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||||
|
IN UINTN UserPageTable,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes
|
||||||
|
);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE
|
/// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE
|
||||||
/// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt
|
/// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt
|
||||||
@ -288,6 +298,7 @@ struct _EFI_CPU_ARCH_PROTOCOL {
|
|||||||
///
|
///
|
||||||
UINT32 DmaBufferAlignment;
|
UINT32 DmaBufferAlignment;
|
||||||
EFI_CPU_GET_MEMORY_ATTRIBUTES GetMemoryAttributes;
|
EFI_CPU_GET_MEMORY_ATTRIBUTES GetMemoryAttributes;
|
||||||
|
EFI_CPU_SET_USER_MEMORY_ATTRIBUTES SetUserMemoryAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EFI_GUID gEfiCpuArchProtocolGuid;
|
extern EFI_GUID gEfiCpuArchProtocolGuid;
|
||||||
|
@ -781,6 +781,9 @@
|
|||||||
## Include/Guid/MemoryAllocationHob.h
|
## Include/Guid/MemoryAllocationHob.h
|
||||||
gEfiHobMemoryAllocBspStoreGuid = { 0x564B33CD, 0xC92A, 0x4593, { 0x90, 0xBF, 0x24, 0x73, 0xE4, 0x3C, 0x63, 0x22 }}
|
gEfiHobMemoryAllocBspStoreGuid = { 0x564B33CD, 0xC92A, 0x4593, { 0x90, 0xBF, 0x24, 0x73, 0xE4, 0x3C, 0x63, 0x22 }}
|
||||||
|
|
||||||
|
## Include/Guid/MemoryAllocationHob.h
|
||||||
|
gEfiHobPageTableInfoGuid = { 0xAC992FE9, 0xB0CC, 0x45DF, { 0xAE, 0xCF, 0x51, 0x5A, 0xD2, 0xC4, 0xE8, 0xB3 }}
|
||||||
|
|
||||||
## Include/Guid/EventLegacyBios.h
|
## Include/Guid/EventLegacyBios.h
|
||||||
gEfiEventLegacyBootGuid = { 0x2A571201, 0x4966, 0x47F6, { 0x8B, 0x86, 0xF3, 0x1E, 0x41, 0xF3, 0x2F, 0x10 }}
|
gEfiEventLegacyBootGuid = { 0x2A571201, 0x4966, 0x47F6, { 0x8B, 0x86, 0xF3, 0x1E, 0x41, 0xF3, 0x2F, 0x10 }}
|
||||||
|
|
||||||
|
@ -158,4 +158,6 @@ typedef union {
|
|||||||
#define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK)
|
#define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK)
|
||||||
#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
|
#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
|
||||||
|
|
||||||
|
#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,7 +32,8 @@ EFI_CPU_ARCH_PROTOCOL gCpuImpl = {
|
|||||||
CpuSetMemoryAttributes,
|
CpuSetMemoryAttributes,
|
||||||
1, // NumberOfTimers
|
1, // NumberOfTimers
|
||||||
4, // DmaBufferAlignment
|
4, // DmaBufferAlignment
|
||||||
CpuGetMemoryAttributes
|
CpuGetMemoryAttributes,
|
||||||
|
CpuSetUserMemoryAttributes
|
||||||
};
|
};
|
||||||
|
|
||||||
EFI_HOB_PLATFORM_INFO *mPlatformInfoHob2 = NULL;
|
EFI_HOB_PLATFORM_INFO *mPlatformInfoHob2 = NULL;
|
||||||
|
@ -229,6 +229,16 @@ CpuGetMemoryAttributes (
|
|||||||
OUT UINT64 *Attributes
|
OUT UINT64 *Attributes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
CpuSetUserMemoryAttributes (
|
||||||
|
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||||
|
IN UINTN UserPageTable,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize Global Descriptor Table.
|
Initialize Global Descriptor Table.
|
||||||
|
|
||||||
|
@ -429,6 +429,35 @@ CpuGetMemoryAttributes (
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
CpuSetUserMemoryAttributes (
|
||||||
|
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||||
|
IN UINTN UserPageTable,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 MemoryAttributes;
|
||||||
|
PAGE_TABLE_LIB_PAGING_CONTEXT PagingContext;
|
||||||
|
|
||||||
|
MemoryAttributes = Attributes & EFI_MEMORY_ATTRIBUTE_MASK;
|
||||||
|
|
||||||
|
GetCurrentPagingContext (&PagingContext);
|
||||||
|
|
||||||
|
if (PagingContext.MachineType == IMAGE_FILE_MACHINE_I386) {
|
||||||
|
PagingContext.ContextData.Ia32.PageTableBase = (UINT32)UserPageTable;
|
||||||
|
} else {
|
||||||
|
PagingContext.ContextData.X64.PageTableBase = (UINT64)UserPageTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set memory attribute by page table
|
||||||
|
//
|
||||||
|
return AssignMemoryPageAttributes (&PagingContext, BaseAddress, Length, MemoryAttributes, AllocatePages);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Modify memory attributes of page entry.
|
Modify memory attributes of page entry.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user