diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 16091d3f09..b9bbef7a8d 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2845,15 +2845,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 diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 89d3658d09..3ac911f56f 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -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 + ); } // diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index ad07e0c635..7d3cc8beb0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -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); -} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 952b88ddbe..50c89956f4 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -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, diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index d3f8f2635c..0ab6eebd3a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -5,14 +5,18 @@ ; ;------------------------------------------------------------------------------ -DEFAULT REL -SECTION .text +#include 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 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm index ec4780bdc8..09f0d866d2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm @@ -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