From 633521d91f8a10a77b2de4c7a9f2a4811975b36f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 26 Jan 2024 12:29:01 +0300 Subject: [PATCH] Ring3: Fixed bug in calling Boot Service and did some refactoring. --- MdeModulePkg/Core/Dxe/Image/Image.c | 6 +- .../Core/DxeIplPeim/X64/VirtualMemory.c | 2 +- MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 55 ++++++++++++------- .../Ring3UefiBootServicesTableLib.c | 2 +- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 0893d39fa2..6270963f8c 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1716,9 +1716,9 @@ CoreStartImage ( TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); gCoreSysCallStackTop = TopOfStack; - DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); + DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); // // Allocate 128KB for the User Stack. @@ -1735,8 +1735,6 @@ CoreStartImage ( SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); DEBUG ((DEBUG_ERROR, "Core: UserTopOfStack = %p\n", TopOfStack)); - DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices)); - // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // @@ -1746,6 +1744,8 @@ CoreStartImage ( EFI_MEMORY_XP | EFI_MEMORY_USER ); + DEBUG ((DEBUG_ERROR, "Core: BootServices = 0x%lx\n", (UINTN)Image->Info.SystemTable->BootServices)); + // // Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET. // diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 31db5de3fb..41a9d6d5c8 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -995,7 +995,7 @@ CreateIdentityMappingPageTables ( 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.SMAP = 1; Cr4.Bits.SMEP = 1; AsmWriteCr4 (Cr4.UintN); diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index f7fb758269..868d23df87 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -70,10 +70,10 @@ ASM_PFX(InternalEnterUserImage): mov rax, [rsp + 8*6] or rax, 3H ; RPL = 3 -o16 mov ds, ax -o16 mov es, ax -o16 mov fs, ax -o16 mov gs, ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax ; Save Code selector mov r10, [rsp + 8*5] @@ -108,10 +108,30 @@ o16 mov gs, ax ; (r11) RFLAGS saved by SYSCALL in SysCall(). ;On stack Argument 4, 5, ... ;------------------------------------------------------------------------------ +%macro CallSysRet 0 +o16 mov ds, r11 +o16 mov es, r11 +o16 mov fs, r11 +o16 mov gs, r11 + + ; Restore RFLAGS in R11 for SYSRET. + pushfq + pop r11 + + ; Switch to User Stack. + pop rbp + pop rdx + mov rsp, rdx + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. +o64 sysret + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. +%endmacro + global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): - cmp r10, 0 - je readMemory + ; Save User data segment selector. + mov r11, ds mov ax, ss mov ds, ax @@ -119,7 +139,7 @@ ASM_PFX(CoreBootServices): mov fs, ax mov gs, ax - ; Save User Stack pointer and switch to Core SysCall Stack. + ; Save User Stack pointers and switch to Core SysCall Stack. mov rax, [ASM_PFX(gCoreSysCallStackTop)] sub rax, 8 mov [rax], rsp @@ -128,9 +148,11 @@ ASM_PFX(CoreBootServices): push rbp mov rbp, rsp - ; Save return address and RFLAGS for SYSRET. + cmp r10, 0 + je readMemory + + ; Save return address for SYSRET. push rcx - push r11 ; Replace argument according to UEFI calling convention. mov rcx, rdx @@ -142,24 +164,17 @@ ASM_PFX(CoreBootServices): ; ... ; Call Boot Service by FunctionAddress. - call r10 + call [r10] ; Prepare SYSRET arguments. - pop r11 pop rcx - ; Switch to User Stack. - pop rbp - pop rdx - mov rsp, rdx - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. -o64 sysret - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + CallSysRet readMemory: mov rax, [rdx] -o64 sysret + + CallSysRet SECTION .data diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 1d5ae5064f..cce038ba87 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -94,7 +94,7 @@ UefiBootServicesTableLibConstructor ( (UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices) ); ASSERT (mCoreBS != NULL); - DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS)); + DEBUG ((DEBUG_ERROR, "User: BootServices = 0x%lx\n", (UINTN)mCoreBS)); return EFI_SUCCESS; }