mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
Ring3: Added support for IA32 User page table.
This commit is contained in:
parent
5cd360104a
commit
b9976de78c
@ -224,7 +224,7 @@
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES
|
||||
|
||||
[Pcd.IA32,Pcd.X64]
|
||||
[Pcd.IA32, Pcd.X64]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## SOMETIMES_CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES
|
||||
|
@ -98,6 +98,10 @@ copy:
|
||||
pop eax
|
||||
%endmacro
|
||||
|
||||
ALIGN 4096
|
||||
global ASM_PFX(SysCallBase)
|
||||
ASM_PFX(SysCallBase):
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; EFI_STATUS
|
||||
; EFIAPI
|
||||
@ -119,6 +123,9 @@ ASM_PFX(CoreBootServices):
|
||||
push ebp
|
||||
push eax
|
||||
|
||||
mov eax, [ASM_PFX(gCorePageTable)]
|
||||
mov cr3, eax
|
||||
|
||||
; Switch from User to Core data segment selectors.
|
||||
mov ax, ss
|
||||
mov ds, ax
|
||||
@ -147,6 +154,9 @@ ASM_PFX(CoreBootServices):
|
||||
|
||||
SetRing3DataSegmentSelectors
|
||||
|
||||
mov eax, [ASM_PFX(gUserPageTable)]
|
||||
mov cr3, eax
|
||||
|
||||
pop eax
|
||||
|
||||
; Step over User Arguments [1..3] and CallBootService input.
|
||||
@ -194,10 +204,17 @@ ASM_PFX(CallRing3):
|
||||
; Switch to User Stack.
|
||||
mov ebp, ecx
|
||||
|
||||
mov ebx, [ASM_PFX(gUserPageTable)]
|
||||
mov cr3, ebx
|
||||
|
||||
; Pass control to user image
|
||||
sti
|
||||
sysexit
|
||||
|
||||
ALIGN 4096
|
||||
global ASM_PFX(SysCallEnd)
|
||||
ASM_PFX(SysCallEnd):
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; EFIAPI
|
||||
@ -219,5 +236,16 @@ ASM_PFX(ReturnToCore):
|
||||
ret
|
||||
|
||||
SECTION .data
|
||||
ALIGN 4096
|
||||
|
||||
global ASM_PFX(gCorePageTable)
|
||||
ASM_PFX(gCorePageTable):
|
||||
resd 1
|
||||
|
||||
global ASM_PFX(gUserPageTable)
|
||||
ASM_PFX(gUserPageTable):
|
||||
resd 1
|
||||
|
||||
ALIGN 4096
|
||||
ASM_PFX(CoreEsp):
|
||||
resd 1
|
||||
|
@ -8,6 +8,86 @@
|
||||
#include "DxeMain.h"
|
||||
|
||||
#include <Register/Intel/ArchitecturalMsr.h>
|
||||
#include <IndustryStandard/PageTable.h>
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
MakeUserPageTableTemplate (
|
||||
OUT VOID **UserPageTableTemplate,
|
||||
OUT UINTN *UserPageTableTemplateSize
|
||||
)
|
||||
{
|
||||
UINT8 PhysicalAddressBits;
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddress;
|
||||
UINTN IndexOfPdpEntries;
|
||||
UINTN IndexOfPageDirectoryEntries;
|
||||
UINT32 NumberOfPdpEntriesNeeded;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
|
||||
PAGE_TABLE_ENTRY *PageDirectoryEntry;
|
||||
UINTN TotalPagesNum;
|
||||
UINTN PageAddress;
|
||||
UINT64 AddressEncMask;
|
||||
|
||||
//
|
||||
// Make sure AddressEncMask is contained to smallest supported address field
|
||||
//
|
||||
AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
|
||||
|
||||
PhysicalAddressBits = 32;
|
||||
|
||||
//
|
||||
// Calculate the table entries needed.
|
||||
//
|
||||
NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
|
||||
|
||||
TotalPagesNum = NumberOfPdpEntriesNeeded + 1;
|
||||
PageAddress = (UINTN)AllocateAlignedPages (TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT);
|
||||
ASSERT (PageAddress != 0);
|
||||
|
||||
PageMap = (VOID *)PageAddress;
|
||||
PageAddress += SIZE_4KB;
|
||||
|
||||
PageDirectoryPointerEntry = PageMap;
|
||||
PhysicalAddress = 0;
|
||||
|
||||
for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; 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 *)PageAddress;
|
||||
PageAddress += SIZE_4KB;
|
||||
|
||||
//
|
||||
// Fill in a Page Directory Pointer Entries
|
||||
//
|
||||
PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;
|
||||
PageDirectoryPointerEntry->Bits.Present = 1;
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectoryEntry->Uint64 = (UINT64)PhysicalAddress | AddressEncMask;
|
||||
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryEntry->Bits.Present = 0;
|
||||
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
|
||||
ZeroMem (
|
||||
PageDirectoryPointerEntry,
|
||||
sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
|
||||
);
|
||||
}
|
||||
|
||||
*UserPageTableTemplate = (VOID *)PageMap;
|
||||
*UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT);
|
||||
|
||||
SetUefiImageMemoryAttributes ((UINT64)(UINTN)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP);
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
@ -25,6 +105,13 @@ InitializeMsr (
|
||||
Ebx = 0;
|
||||
Edx = 0;
|
||||
|
||||
//
|
||||
// Forbid global pages.
|
||||
//
|
||||
Cr4.UintN = AsmReadCr4 ();
|
||||
Cr4.Bits.PGE = 0;
|
||||
AsmWriteCr4 (Cr4.UintN);
|
||||
|
||||
//
|
||||
// Forbid supervisor-mode accesses to any user-mode pages.
|
||||
//
|
||||
@ -70,4 +157,6 @@ InitializeMsr (
|
||||
|
||||
Msr = (UINT64)(UINTN)gCoreSysCallStackTop;
|
||||
AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr);
|
||||
|
||||
gCorePageTable = AsmReadCr3 ();
|
||||
}
|
||||
|
@ -23,16 +23,33 @@
|
||||
;
|
||||
; CommonExceptionHandler()
|
||||
;
|
||||
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
|
||||
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
|
||||
extern ASM_PFX(CommonExceptionHandler)
|
||||
|
||||
SECTION .data
|
||||
ALIGN 4096
|
||||
|
||||
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
|
||||
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
|
||||
global ASM_PFX(CorePageTable)
|
||||
ASM_PFX(CorePageTable):
|
||||
resq 1
|
||||
|
||||
global ASM_PFX(UserPageTable)
|
||||
ASM_PFX(UserPageTable):
|
||||
resq 1
|
||||
|
||||
global ASM_PFX(mSwitchCr3Flag)
|
||||
ASM_PFX(mSwitchCr3Flag):
|
||||
db 0x0
|
||||
|
||||
ALIGN 4096
|
||||
Padding:
|
||||
db 0x0
|
||||
|
||||
SECTION .text
|
||||
|
||||
ALIGN 8
|
||||
ALIGN 4096
|
||||
global ASM_PFX(ExceptionHandlerBase)
|
||||
ASM_PFX(ExceptionHandlerBase):
|
||||
|
||||
;
|
||||
; exception handler stub table
|
||||
@ -88,6 +105,14 @@ HookAfterStubHeaderEnd:
|
||||
global ASM_PFX(CommonInterruptEntry)
|
||||
ASM_PFX(CommonInterruptEntry):
|
||||
cli
|
||||
cmp byte [ASM_PFX(mSwitchCr3Flag)], 0
|
||||
jz NoCr3Switch
|
||||
mov eax, cr3
|
||||
mov [ASM_PFX(UserPageTable)], eax
|
||||
mov eax, [ASM_PFX(CorePageTable)]
|
||||
mov cr3, eax
|
||||
|
||||
NoCr3Switch:
|
||||
pop eax
|
||||
;
|
||||
; All interrupt handlers are invoked through interrupt gates, so
|
||||
@ -413,8 +438,8 @@ continue:
|
||||
push ecx
|
||||
mov ecx, ds
|
||||
and ecx, 3
|
||||
pop ecx
|
||||
jnz ReturnToRing3
|
||||
pop ecx
|
||||
|
||||
pop dword [ebp - 8]
|
||||
pop dword [ebp - 4]
|
||||
@ -444,11 +469,18 @@ DoReturn:
|
||||
DoIret:
|
||||
iretd
|
||||
ReturnToRing3:
|
||||
mov ecx, [ASM_PFX(UserPageTable)]
|
||||
mov cr3, ecx
|
||||
pop ecx
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
add esp, 8
|
||||
iretd
|
||||
|
||||
ALIGN 4096
|
||||
global ASM_PFX(ExceptionHandlerEnd)
|
||||
ASM_PFX(ExceptionHandlerEnd):
|
||||
|
||||
;---------------------------------------;
|
||||
; _AsmGetTemplateAddressMap ;
|
||||
;----------------------------------------------------------------------------;
|
||||
|
Loading…
x
Reference in New Issue
Block a user