Ring3: Refactored EnterUserImage() into CallRing3().

This commit is contained in:
Mikhail Krichanov 2024-02-09 15:25:06 +03:00
parent df7a3fa963
commit e5f7eb7654
6 changed files with 79 additions and 145 deletions

View File

@ -2833,15 +2833,11 @@ CoreBootServices (
...
);
VOID
EFI_STATUS
EFIAPI
EnterUserImage (
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
IN VOID *Context1 OPTIONAL,
IN VOID *Context2 OPTIONAL,
IN VOID *NewStack,
IN UINT16 CodeSelector,
IN UINT16 DataSelector
CallRing3 (
IN VOID *EntryPoint,
...
);
#endif

View File

@ -1788,15 +1788,11 @@ CoreStartImage (
Msr = (UINT64)(UINTN)CoreBootServices;
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
EnterUserImage (
(SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint,
ImageHandle,
Image->Info.SystemTable,
gRing3CallStackTop,
(UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL
);
Image->Status = EFI_SUCCESS;
Image->Status = CallRing3 (
(VOID *)Image->EntryPoint,
ImageHandle,
Image->Info.SystemTable
);
}
//

View File

@ -32,17 +32,6 @@ CallInstallMultipleProtocolInterfaces (
IN VOID *Function
);
VOID
EFIAPI
InternalEnterUserImage (
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
IN VOID *Context1 OPTIONAL,
IN VOID *Context2 OPTIONAL,
IN VOID *NewStack,
IN UINT16 CodeSelector,
IN UINT16 DataSelector
);
typedef struct {
UINTN Argument1;
UINTN Argument2;
@ -85,7 +74,9 @@ CallBootService (
EFI_HANDLE CoreHandle;
EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding;
//
// TODO: Check User variables.
//
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
@ -230,25 +221,3 @@ CallBootService (
return EFI_UNSUPPORTED;
}
VOID
EFIAPI
EnterUserImage (
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
IN VOID *Context1 OPTIONAL,
IN VOID *Context2 OPTIONAL,
IN VOID *NewStack,
IN UINT16 CodeSelector,
IN UINT16 DataSelector
)
{
ASSERT (EntryPoint != NULL);
ASSERT (NewStack != NULL);
//
// New stack must be aligned with CPU_STACK_ALIGNMENT
//
ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);
InternalEnterUserImage (EntryPoint, Context1, Context2, NewStack, CodeSelector, DataSelector);
}

View File

@ -18,16 +18,6 @@ typedef enum {
UserCallMax
} USER_CALL_TYPE;
EFI_STATUS
EFIAPI
CallRing3 (
IN UINT8 Type,
IN UINT16 CodeSelector,
IN UINT16 DataSelector,
IN VOID *FunctionAddress,
...
);
EFI_STATUS
EFIAPI
CoreDriverBindingSupported (
@ -37,9 +27,6 @@ CoreDriverBindingSupported (
)
{
return CallRing3 (
UserDriverBindingSupported,
(UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL,
(VOID *)mUserDriverBindingSupported,
This,
ControllerHandle,
@ -56,9 +43,6 @@ CoreDriverBindingStart (
)
{
return CallRing3 (
UserDriverBindingStart,
(UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL,
(VOID *)mUserDriverBindingStart,
This,
ControllerHandle,
@ -76,9 +60,6 @@ CoreDriverBindingStop (
)
{
return CallRing3 (
UserDriverBindingStop,
(UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL,
(VOID *)mUserDriverBindingStop,
This,
ControllerHandle,

View File

@ -5,14 +5,18 @@
;
;------------------------------------------------------------------------------
DEFAULT REL
SECTION .text
#include <Register/Intel/ArchitecturalMsr.h>
extern ASM_PFX(CallBootService)
extern ASM_PFX(gCoreSysCallStackTop)
extern ASM_PFX(gRing3CallStackTop)
extern ASM_PFX(gRing3EntryPoint)
extern ASM_PFX(AsmReadMsr64)
DEFAULT REL
SECTION .text
;------------------------------------------------------------------------------
; VOID
; EFIAPI
@ -167,92 +171,69 @@ o64 sysret
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
;------------------------------------------------------------------------------
; Routine Description:
; EFI_STATUS
; EFIAPI
; CallRing3 (
; IN VOID *EntryPoint,
; ...
; );
;
; Routine for transfering control to user image with 2 parameters
;
; Arguments:
;
; (rcx) EntryPoint - Entry point with new stack.
; (rcx) EntryPoint - Entry point in User address space.
; (rdx) Context1 - Parameter1 for entry point.
; (r8) Context2 - Parameter2 for entry point.
; (r9) NewStack - The pointer to new stack.
;On stack CodeSelector - Segment selector for code.
;On stack DataSelector - Segment selector for data.
;
; Returns:
;
; None
;
;------------------------------------------------------------------------------
global ASM_PFX(InternalEnterUserImage)
ASM_PFX(InternalEnterUserImage):
; Set Data selectors
mov rax, [rsp + 8*6]
or rax, 3H ; RPL = 3
global ASM_PFX(CallRing3)
ASM_PFX(CallRing3):
; Save input Arguments.
push r12
push r13
push r14
mov r12, rcx
mov r13, rdx
mov r14, r8
; Extract User Data selector.
mov rcx, MSR_IA32_STAR
call ASM_PFX(AsmReadMsr64)
; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32
shr rax, 48
add rax, 8
; Set Data selectors
or rax, 3H ; RPL = 3
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; Save Code selector
mov r10, [rsp + 8*5]
or r10, 3H ; RPL = 3
; Prepare SYSRET arguments.
mov rcx, [gRing3EntryPoint]
mov rdx, r12
mov r8, r13
mov r9, r14
pushfq
pop r11
; Prepare stack before swithcing
push rax ; ss
push r9 ; rsp
push r10 ; cs
push rcx ; rip
; Restore stack and registers.
pop r14
pop r13
pop r12
; Save 2 parameters
mov rcx, rdx
mov rdx, r8
; Save Core Stack pointers and switch to User Stack.
mov [ASM_PFX(CoreRsp)], rsp
mov [ASM_PFX(CoreRbp)], rbp
mov rsp, [ASM_PFX(gRing3CallStackTop)]
mov rbp, rsp
; Pass control to user image
retfq
o64 sysret
;------------------------------------------------------------------------------
; EFI_STATUS
; EFIAPI
; CallRing3 (
; IN UINT8 Type,
; IN UINT16 CodeSelector,
; IN UINT16 DataSelector,
; IN VOID *FunctionAddress,
; ...
; );
;
; (rcx) Type.
; (rdx) CodeSelector - Segment selector for code.
; (r8) DataSelector - Segment selector for data.
; (r9) FunctionAddress
;
; (On User Stack) Argument 1, 2, 3, ...
;------------------------------------------------------------------------------
global ASM_PFX(CallRing3)
ASM_PFX(CallRing3):
; Set Data selectors
or r8, 3H ; RPL = 3
o16 mov ds, r8
o16 mov es, r8
o16 mov fs, r8
o16 mov gs, r8
; Save Code selector
or rdx, 3H ; RPL = 3
; Prepare stack before swithcing
push r8 ; ss
push qword [gRing3CallStackTop] ; rsp
push rdx ; cs
push qword [gRing3EntryPoint] ; rip
; Copy Arguments from Core Stack to User Stack + return address
; Pass control to User driver function.
retfq
coreReturnAddress:
ret
SECTION .data
ASM_PFX(CoreRsp):
resq 1
ASM_PFX(CoreRbp):
resq 1

View File

@ -15,7 +15,18 @@ SECTION .text
; IN EFI_HANDLE ImageHandle,
; IN EFI_SYSTEM_TABLE *SystemTable
; )
;
; (rcx) _ModuleEntryPoint - Used by SYSRET.
; (rdx) EntryPoint - Function address in User address space.
; (r8) Context1 - Parameter1 for entry point.
; (r9) Context2 - Parameter2 for entry point.
;------------------------------------------------------------------------------
global ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
ret
mov rcx, r8
mov r8, rdx
mov rdx, r9
call r8
ret