mirror of https://github.com/acidanthera/audk.git
Ring3: Added SYSCALL draft.
This commit is contained in:
parent
233a5cff09
commit
6502e73b0d
MdeModulePkg/Core
MdePkg
Include/Library
Library
BaseLib/X64
Ring3UefiBootServicesTableLib
UefiCpuPkg/Library
|
@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
#include "DxeMain.h"
|
||||
#include "Image.h"
|
||||
|
||||
#include <Register/Intel/ArchitecturalMsr.h>
|
||||
|
||||
//
|
||||
// Module Globals
|
||||
//
|
||||
|
@ -1599,6 +1601,7 @@ CoreStartImage (
|
|||
VOID *BaseOfStack;
|
||||
VOID *TopOfStack;
|
||||
UINTN SizeOfStack;
|
||||
UINT64 Msr;
|
||||
|
||||
Handle = ImageHandle;
|
||||
|
||||
|
@ -1713,6 +1716,7 @@ CoreStartImage (
|
|||
TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT);
|
||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
// DEBUG ((DEBUG_ERROR, "RING3_CODE64_SEL = 0x%x RING3_DATA64_SEL = 0x%x\n", (UINT16)RING3_CODE64_SEL, (UINT16)RING3_DATA64_SEL));
|
||||
// DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices));
|
||||
|
||||
//
|
||||
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
|
||||
|
@ -1723,6 +1727,19 @@ CoreStartImage (
|
|||
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||
);
|
||||
|
||||
//
|
||||
// Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET.
|
||||
//
|
||||
Msr = ((((UINT64)RING3_CODE64_SEL - 16) << 16) | (UINT64)RING0_CODE64_SEL) << 32;
|
||||
AsmWriteMsr64 (MSR_IA32_STAR, Msr);
|
||||
|
||||
Msr = (UINT64)(UINTN)CoreBootServices;
|
||||
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
|
||||
|
||||
// protection keys
|
||||
// Software can access the old stack, if necessary, by referencing the old
|
||||
// stack-segment selector and stack pointer saved on the new process stack.
|
||||
|
||||
EnterUserImage (
|
||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint,
|
||||
ImageHandle,
|
||||
|
|
|
@ -22,7 +22,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
|
||||
**/
|
||||
|
||||
#include <Register/Intel/ArchitecturalMsr.h>
|
||||
#include <Register/Intel/Cpuid.h>
|
||||
|
||||
#include "DxeIpl.h"
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
|
@ -705,8 +707,11 @@ CreateIdentityMappingPageTables (
|
|||
IA32_CR4 Cr4;
|
||||
IA32_EFLAGS32 Eflags;
|
||||
UINT32 Ebx;
|
||||
UINT32 Edx;
|
||||
MSR_IA32_EFER_REGISTER MsrEfer;
|
||||
|
||||
Ebx = 0;
|
||||
Edx = 0;
|
||||
|
||||
//
|
||||
// Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
|
||||
|
@ -984,7 +989,11 @@ CreateIdentityMappingPageTables (
|
|||
// SMEP and SMAP must be supported.
|
||||
//
|
||||
AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL);
|
||||
if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) {
|
||||
//
|
||||
// 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;
|
||||
|
@ -997,6 +1006,12 @@ CreateIdentityMappingPageTables (
|
|||
//
|
||||
Eflags.Bits.IOPL = 3;
|
||||
AsmWriteEflags (Eflags.UintN);
|
||||
//
|
||||
// Enable SYSCALL and SYSRET
|
||||
//
|
||||
MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
|
||||
MsrEfer.Bits.SCE = 1;
|
||||
AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64);
|
||||
}
|
||||
|
||||
return (UINTN)PageMap;
|
||||
|
|
|
@ -5574,16 +5574,17 @@ typedef struct {
|
|||
DATA_SEGMENT_32 SysData;
|
||||
CODE_SEGMENT_32 SysCode;
|
||||
CODE_SEGMENT_32 SysCode16;
|
||||
DATA_SEGMENT_32 LinearData64;
|
||||
CODE_SEGMENT_64 LinearCode64;
|
||||
DATA_SEGMENT_32 LinearData64;
|
||||
SEGMENT_DESCRIPTOR Spare5;
|
||||
DATA_SEGMENT_32 Ring3Data64;
|
||||
CODE_SEGMENT_64 Ring3Code64;
|
||||
// CALL_GATE_64 FromRing3ToRing0;
|
||||
} GDT;
|
||||
|
||||
#pragma pack ()
|
||||
|
||||
#define RING0_DATA64_SEL OFFSET_OF (GDT, LinearData64)
|
||||
#define RING0_CODE64_SEL OFFSET_OF (GDT, LinearCode64)
|
||||
#define RING3_DATA64_SEL OFFSET_OF (GDT, Ring3Data64)
|
||||
#define RING3_CODE64_SEL OFFSET_OF (GDT, Ring3Code64)
|
||||
|
||||
|
@ -6595,6 +6596,13 @@ AsmReadEflags (
|
|||
VOID
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
CoreBootServices (
|
||||
IN UINTN FunctionAddress,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
Reads the current value of the Control Register 0 (CR0).
|
||||
|
||||
|
|
|
@ -91,3 +91,49 @@ o16 mov gs, ax
|
|||
|
||||
; Pass control to user image
|
||||
retfq
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINTN
|
||||
; EFIAPI
|
||||
; CoreBootServices (
|
||||
; IN UINTN FunctionAddress,
|
||||
; ...
|
||||
; );
|
||||
;
|
||||
; (rcx) RIP of the next instruction saved by SYSCALL in SysCall().
|
||||
; (rdx) Argument 1 of the called function.
|
||||
; (r8) Argument 2 of the called function.
|
||||
; (r9) Argument 3 of the called function.
|
||||
; (r10) FunctionAddress.
|
||||
; (r11) RFLAGS saved by SYSCALL in SysCall().
|
||||
;On stack Argument 4, 5, ...
|
||||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(CoreBootServices)
|
||||
ASM_PFX(CoreBootServices):
|
||||
cmp r10, 0
|
||||
je readMemory
|
||||
|
||||
; Save return address and RFLAGS for SYSRET.
|
||||
mov [rsp], rcx
|
||||
mov [rsp + 8], r11
|
||||
|
||||
; Replace argument according to UEFI calling convention.
|
||||
mov rcx, rdx
|
||||
mov rdx, r8
|
||||
mov r8, r9
|
||||
mov r9, [rsp + 8*3]
|
||||
|
||||
; Call Boot Service by FunctionAddress.
|
||||
call r10
|
||||
|
||||
; Prepare SYSRET arguments.
|
||||
mov rcx, [rsp]
|
||||
mov r11, [rsp + 8]
|
||||
|
||||
; 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.
|
||||
|
||||
readMemory:
|
||||
mov rax, [rdx]
|
||||
o64 sysret
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
**/
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
SysCall (
|
||||
IN UINTN FunctionAddress,
|
||||
...
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Raise the task priority level to the new level.
|
||||
High level is implemented by disabling processor interrupts.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <Uefi.h>
|
||||
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include "Ring3.h"
|
||||
|
||||
|
@ -66,9 +67,8 @@ EFI_BOOT_SERVICES mBootServices = {
|
|||
(EFI_CREATE_EVENT_EX)Ring3CreateEventEx // CreateEventEx
|
||||
};
|
||||
|
||||
// EFI_HANDLE gImageHandle = NULL;
|
||||
// EFI_SYSTEM_TABLE *gST = NULL;
|
||||
EFI_BOOT_SERVICES *gBS = &mBootServices;
|
||||
EFI_BOOT_SERVICES *gBS = &mBootServices;
|
||||
EFI_BOOT_SERVICES *mCoreBS = NULL;
|
||||
|
||||
/**
|
||||
The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES.
|
||||
|
@ -86,23 +86,15 @@ UefiBootServicesTableLibConstructor (
|
|||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
//
|
||||
// Cache the Image Handle
|
||||
//
|
||||
// gImageHandle = ImageHandle;
|
||||
// ASSERT (gImageHandle != NULL);
|
||||
|
||||
//
|
||||
// Cache pointer to the EFI System Table
|
||||
//
|
||||
// gST = SystemTable;
|
||||
// ASSERT (gST != NULL);
|
||||
|
||||
//
|
||||
// Cache pointer to the EFI Boot Services Table
|
||||
//
|
||||
// gBS = SystemTable->BootServices;
|
||||
// ASSERT (gBS != NULL);
|
||||
mCoreBS = (EFI_BOOT_SERVICES *)SysCall (
|
||||
0,
|
||||
(UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices)
|
||||
);
|
||||
ASSERT (mCoreBS != NULL);
|
||||
// DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -512,7 +504,16 @@ Ring3LocateProtocol (
|
|||
OUT VOID **Interface
|
||||
)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = (EFI_STATUS)SysCall (
|
||||
(UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, LocateProtocol),
|
||||
Protocol,
|
||||
Registration,
|
||||
Interface
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
|
|
|
@ -26,9 +26,12 @@
|
|||
Ring3.h
|
||||
Ring3UefiBootServicesTableLib.c
|
||||
|
||||
[Sources.X64]
|
||||
X64/SysCall.nasm
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
;------------------------------------------------------------------------------
|
||||
; Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
DEFAULT REL
|
||||
SECTION .text
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINTN
|
||||
; EFIAPI
|
||||
; SysCall (
|
||||
; IN UINTN FunctionAddress,
|
||||
; ...
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(SysCall)
|
||||
ASM_PFX(SysCall):
|
||||
; Save FunctionAddress for CoreBootServices().
|
||||
mov r10, rcx
|
||||
|
||||
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
||||
syscall
|
||||
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
||||
|
||||
ret
|
|
@ -129,6 +129,25 @@ STATIC GDT mGdtTemplate = {
|
|||
.Granularity = 1,
|
||||
.BaseAddress_31_24 = 0x0
|
||||
},
|
||||
.LinearCode64 = {
|
||||
.Reserved1 = 0x0,
|
||||
.Reserved2 = 0x0,
|
||||
|
||||
.Accessed = 0,
|
||||
.Readable = 1,
|
||||
.Conforming = 0,
|
||||
.IsCode = 1,
|
||||
.IsNotSystemSegment = 1,
|
||||
.DescriptorPrivilegeLevel = 0,
|
||||
.SegmentPresent = 1,
|
||||
|
||||
.Reserved3 = 0x0,
|
||||
.Available = 0,
|
||||
.LongMode = 1,
|
||||
.Is32Bit = 0,
|
||||
.Granularity = 1,
|
||||
.Reserved4 = 0x0
|
||||
},
|
||||
.LinearData64 = {
|
||||
.SegmentLimit_15_0 = 0xFFFF,
|
||||
.BaseAddress_15_0 = 0x0,
|
||||
|
@ -149,25 +168,6 @@ STATIC GDT mGdtTemplate = {
|
|||
.Granularity = 1,
|
||||
.BaseAddress_31_24 = 0x0
|
||||
},
|
||||
.LinearCode64 = {
|
||||
.Reserved1 = 0x0,
|
||||
.Reserved2 = 0x0,
|
||||
|
||||
.Accessed = 0,
|
||||
.Readable = 1,
|
||||
.Conforming = 0,
|
||||
.IsCode = 1,
|
||||
.IsNotSystemSegment = 1,
|
||||
.DescriptorPrivilegeLevel = 0,
|
||||
.SegmentPresent = 1,
|
||||
|
||||
.Reserved3 = 0x0,
|
||||
.Available = 0,
|
||||
.LongMode = 1,
|
||||
.Is32Bit = 0,
|
||||
.Granularity = 1,
|
||||
.Reserved4 = 0x0
|
||||
},
|
||||
.Spare5 = {
|
||||
.SegmentLimit_15_0 = 0x0,
|
||||
.BaseAddress_15_0 = 0x0,
|
||||
|
@ -203,7 +203,7 @@ STATIC GDT mGdtTemplate = {
|
|||
.Granularity = 1,
|
||||
.BaseAddress_31_24 = 0x0
|
||||
},
|
||||
.Ring3Code64 = { // SetCodeSelector () | 5.8.6 Returning from a Called Procedure
|
||||
.Ring3Code64 = {
|
||||
.Reserved1 = 0x0,
|
||||
.Reserved2 = 0x0,
|
||||
|
||||
|
@ -222,21 +222,6 @@ STATIC GDT mGdtTemplate = {
|
|||
.Granularity = 1,
|
||||
.Reserved4 = 0x0
|
||||
},
|
||||
// .FromRing3ToRing0 = {
|
||||
// .Common.OffsetInSegment_15_0 = 0x?,
|
||||
// .Common.SegmentSelector = (UINT16)LINEAR_CODE64_SEL,
|
||||
//
|
||||
// .Common.ParameterCount = 0,
|
||||
// .Common.Reserved = 0,
|
||||
//
|
||||
// .Common.Type = 0xC,
|
||||
// .Common.IsNotSystemSegment = 0,
|
||||
// .Common.DescriptorPrivilegeLevel = 3,
|
||||
// .Common.SegmentPresent = 1,
|
||||
// .Common.OffsetInSegment_31_16 = 0x?,
|
||||
// .OffsetInSegment_63_31 = 0x?,
|
||||
// .Reserved = 0x0
|
||||
// },
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -249,8 +249,6 @@ ArchSetupExceptionStack (
|
|||
IdtTable[Vector].Bits.Reserved_0 = (UINT8)(Index + 1);
|
||||
}
|
||||
|
||||
// Tss->RSP0 = %rsp
|
||||
|
||||
//
|
||||
// Publish GDT
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue