Ring3: Refactored out AllocateRing3Pages() BootService.

This commit is contained in:
Mikhail Krichanov 2024-02-02 14:49:47 +03:00
parent 40b3cd4420
commit e4eb762d22
7 changed files with 60 additions and 87 deletions

View File

@ -1173,11 +1173,11 @@ CoreAllocatePages (
IN OUT EFI_PHYSICAL_ADDRESS *Memory IN OUT EFI_PHYSICAL_ADDRESS *Memory
); );
EFI_STATUS VOID *
EFIAPI EFIAPI
AllocateRing3Pages ( AllocateRing3CopyPages (
IN UINTN NumberOfPages, IN VOID *MemoryCore,
IN OUT VOID **Memory IN UINT32 MemoryCoreSize
); );
/** /**

View File

@ -162,6 +162,7 @@
gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES
gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES
gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES
gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES
# Arch Protocols # Arch Protocols
gEfiBdsArchProtocolGuid ## CONSUMES gEfiBdsArchProtocolGuid ## CONSUMES

View File

@ -89,8 +89,7 @@ EFI_BOOT_SERVICES mBootServices = {
(EFI_CALCULATE_CRC32)CoreEfiNotAvailableYetArg3, // CalculateCrc32 (EFI_CALCULATE_CRC32)CoreEfiNotAvailableYetArg3, // CalculateCrc32
(EFI_COPY_MEM)CopyMem, // CopyMem (EFI_COPY_MEM)CopyMem, // CopyMem
(EFI_SET_MEM)SetMem, // SetMem (EFI_SET_MEM)SetMem, // SetMem
(EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx (EFI_CREATE_EVENT_EX)CoreCreateEventEx // CreateEventEx
(EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages
}; };
EFI_DXE_SERVICES mDxeServices = { EFI_DXE_SERVICES mDxeServices = {

View File

@ -1565,25 +1565,25 @@ CoreLoadImage (
return Status; return Status;
} }
EFI_STATUS VOID *
EFIAPI EFIAPI
AllocateRing3Pages ( AllocateRing3CopyPages (
IN UINTN NumberOfPages, IN VOID *MemoryCore,
IN OUT VOID **Memory IN UINT32 MemoryCoreSize
) )
{ {
if (Memory == NULL) { VOID *MemoryRing3;
return EFI_INVALID_PARAMETER;
MemoryRing3 = AllocatePages (EFI_SIZE_TO_PAGES (MemoryCoreSize));
if (MemoryRing3 == NULL) {
return NULL;
} }
*Memory = AllocatePages (NumberOfPages); CopyMem (MemoryRing3, MemoryCore, MemoryCoreSize);
if (*Memory == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SetUefiImageMemoryAttributes ((UINTN)*Memory, EFI_PAGES_TO_SIZE (NumberOfPages), EFI_MEMORY_USER); SetUefiImageMemoryAttributes ((UINTN)MemoryRing3, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (MemoryCoreSize)), EFI_MEMORY_USER);
return EFI_SUCCESS; return MemoryRing3;
} }
/** /**

View File

@ -5,11 +5,9 @@
**/ **/
#include <Uefi.h> #include "DxeMain.h"
#include <Library/DebugLib.h> #include <Protocol/DevicePathUtilities.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
VOID VOID
EFIAPI EFIAPI
@ -50,6 +48,7 @@ CallBootService (
UINT32 Arg6; UINT32 Arg6;
EFI_GUID *CoreProtocol; EFI_GUID *CoreProtocol;
UINT32 MemoryCoreSize;
// Stack: // Stack:
// rcx - Rip for SYSCALL // rcx - Rip for SYSCALL
@ -59,13 +58,6 @@ CallBootService (
// r11 - User data segment selector <- CoreRbp // r11 - User data segment selector <- CoreRbp
// rsp - User Rsp // rsp - User Rsp
switch (Type) { switch (Type) {
case SysCallAllocateRing3Pages:
Status = gBS->AllocateRing3Pages (*((UINTN *)CoreRbp + 3), &Pointer);
DisableSMAP ();
*(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer;
EnableSMAP ();
return (UINTN)Status;
case SysCallLocateProtocol: case SysCallLocateProtocol:
DisableSMAP (); DisableSMAP ();
CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 3)); CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 3));
@ -81,10 +73,25 @@ CallBootService (
&Pointer &Pointer
); );
if (CompareGuid (CoreProtocol, &gEfiDevicePathUtilitiesProtocolGuid)) {
MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL);
} else {
MemoryCoreSize = 0;
}
Pointer = AllocateRing3CopyPages (Pointer, MemoryCoreSize);
if (Pointer == NULL) {
DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n"));
FreePool (CoreProtocol); FreePool (CoreProtocol);
return EFI_OUT_OF_RESOURCES;
}
DisableSMAP (); DisableSMAP ();
*((UINTN *)UserRsp + 5) = (UINTN)Pointer; *(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer;
EnableSMAP (); EnableSMAP ();
FreePool (CoreProtocol);
return (UINTN)Status; return (UINTN)Status;
case SysCallOpenProtocol: case SysCallOpenProtocol:
@ -108,11 +115,27 @@ CallBootService (
Arg6 Arg6
); );
if (CompareGuid (CoreProtocol, &gEfiLoadedImageProtocolGuid)) {
MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL);
} else {
MemoryCoreSize = 0;
}
Pointer = AllocateRing3CopyPages (Pointer, MemoryCoreSize);
if (Pointer == NULL) {
DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n"));
FreePool (CoreProtocol); FreePool (CoreProtocol);
return EFI_OUT_OF_RESOURCES;
}
DisableSMAP (); DisableSMAP ();
*((UINTN *)UserRsp + 5) = (UINTN)Pointer; *(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer;
EnableSMAP (); EnableSMAP ();
FreePool (CoreProtocol);
return (UINTN)Status; return (UINTN)Status;
default: default:
break; break;
} }

View File

@ -213,13 +213,6 @@ EFI_STATUS
IN OUT EFI_PHYSICAL_ADDRESS *Memory IN OUT EFI_PHYSICAL_ADDRESS *Memory
); );
typedef
EFI_STATUS
(EFIAPI *EFI_ALLOCATE_RING3_PAGES)(
IN UINTN Pages,
IN OUT VOID **Memory
);
/** /**
Frees memory pages. Frees memory pages.
@ -2018,13 +2011,11 @@ typedef struct {
EFI_COPY_MEM CopyMem; EFI_COPY_MEM CopyMem;
EFI_SET_MEM SetMem; EFI_SET_MEM SetMem;
EFI_CREATE_EVENT_EX CreateEventEx; EFI_CREATE_EVENT_EX CreateEventEx;
EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages;
} EFI_BOOT_SERVICES; } EFI_BOOT_SERVICES;
typedef enum { typedef enum {
SysCallLocateProtocol = 1, SysCallLocateProtocol = 1,
SysCallOpenProtocol = 2, SysCallOpenProtocol = 2,
SysCallAllocateRing3Pages = 3,
SysCallMax SysCallMax
} SYS_CALL_TYPE; } SYS_CALL_TYPE;

View File

@ -72,9 +72,6 @@ EFI_BOOT_SERVICES mBootServices = {
EFI_BOOT_SERVICES *gBS = &mBootServices; EFI_BOOT_SERVICES *gBS = &mBootServices;
EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mCoreDevicePathUtilitiesProtocol = NULL;
EFI_LOADED_IMAGE_PROTOCOL *mCoreLoadedImageProtocol = NULL;
/** /**
The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES.
@ -460,37 +457,12 @@ Ring3OpenProtocol (
} }
if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) {
mCoreLoadedImageProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; UserProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface;
Status = (EFI_STATUS)SysCall ( // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces().
SysCallAllocateRing3Pages,
0,
EFI_SIZE_TO_PAGES (sizeof (EFI_LOADED_IMAGE_PROTOCOL)),
(VOID **)&UserProtocol
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3 EFI_LOADED_IMAGE_PROTOCOL structure.\n"));
return Status;
}
// TODO: Copy Core Interface fields with AllocateRing3Pages().
UserProtocol->Revision = 0;
UserProtocol->ParentHandle = NULL;
UserProtocol->SystemTable = NULL;
UserProtocol->DeviceHandle = NULL;
UserProtocol->FilePath = NULL;
UserProtocol->Reserved = 0;
UserProtocol->LoadOptionsSize = 0;
UserProtocol->LoadOptions = NULL;
UserProtocol->ImageBase = NULL;
UserProtocol->ImageSize = 0;
UserProtocol->ImageCodeType = 0;
UserProtocol->ImageDataType = 0;
UserProtocol->Unload = NULL; UserProtocol->Unload = NULL;
*Interface = UserProtocol;
return Status; return Status;
} }
@ -570,18 +542,7 @@ Ring3LocateProtocol (
} }
if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) {
mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; UserProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface;
Status = (EFI_STATUS)SysCall (
SysCallAllocateRing3Pages,
0,
EFI_SIZE_TO_PAGES (sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL)),
(VOID **)&UserProtocol
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3 EFI_DEVICE_PATH_UTILITIES_PROTOCOL structure.\n"));
return Status;
}
UserProtocol->GetDevicePathSize = NULL; UserProtocol->GetDevicePathSize = NULL;
UserProtocol->DuplicateDevicePath = NULL; UserProtocol->DuplicateDevicePath = NULL;
@ -592,8 +553,6 @@ Ring3LocateProtocol (
UserProtocol->IsDevicePathMultiInstance = NULL; UserProtocol->IsDevicePathMultiInstance = NULL;
UserProtocol->CreateDeviceNode = NULL; UserProtocol->CreateDeviceNode = NULL;
*Interface = UserProtocol;
return Status; return Status;
} }