Skip to content

Commit

Permalink
Ring3: Refactored out AllocateRing3Pages() BootService.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikhail Krichanov committed Feb 2, 2024
1 parent 3cba245 commit 1a32743
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 89 deletions.
8 changes: 4 additions & 4 deletions MdeModulePkg/Core/Dxe/DxeMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -1167,11 +1167,11 @@ CoreAllocatePages (
IN OUT EFI_PHYSICAL_ADDRESS *Memory
);

EFI_STATUS
VOID *
EFIAPI
AllocateRing3Pages (
IN UINTN NumberOfPages,
IN OUT VOID **Memory
AllocateRing3CopyPages (
IN VOID *MemoryCore,
IN UINT32 MemoryCoreSize
);

/**
Expand Down
1 change: 1 addition & 0 deletions MdeModulePkg/Core/Dxe/DxeMain.inf
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES
gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES
gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES
gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES

# Arch Protocols
gEfiBdsArchProtocolGuid ## CONSUMES
Expand Down
3 changes: 1 addition & 2 deletions MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ EFI_BOOT_SERVICES mBootServices = {
(EFI_CALCULATE_CRC32)CoreEfiNotAvailableYetArg3, // CalculateCrc32
(EFI_COPY_MEM)CopyMem, // CopyMem
(EFI_SET_MEM)SetMem, // SetMem
(EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx
(EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages
(EFI_CREATE_EVENT_EX)CoreCreateEventEx // CreateEventEx
};

EFI_DXE_SERVICES mDxeServices = {
Expand Down
24 changes: 12 additions & 12 deletions MdeModulePkg/Core/Dxe/Image/Image.c
Original file line number Diff line number Diff line change
Expand Up @@ -1565,25 +1565,25 @@ CoreLoadImage (
return Status;
}

EFI_STATUS
VOID *
EFIAPI
AllocateRing3Pages (
IN UINTN NumberOfPages,
IN OUT VOID **Memory
AllocateRing3CopyPages (
IN VOID *MemoryCore,
IN UINT32 MemoryCoreSize
)
{
if (Memory == NULL) {
return EFI_INVALID_PARAMETER;
}
VOID *MemoryRing3;

*Memory = AllocatePages (NumberOfPages);
if (*Memory == NULL) {
return EFI_OUT_OF_RESOURCES;
MemoryRing3 = AllocatePages (EFI_SIZE_TO_PAGES (MemoryCoreSize));
if (MemoryRing3 == NULL) {
return NULL;
}

SetUefiImageMemoryAttributes ((UINTN)*Memory, EFI_PAGES_TO_SIZE (NumberOfPages), EFI_MEMORY_USER);
CopyMem (MemoryRing3, MemoryCore, MemoryCoreSize);

return EFI_SUCCESS;
SetUefiImageMemoryAttributes ((UINTN)MemoryRing3, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (MemoryCoreSize)), EFI_MEMORY_USER);

return MemoryRing3;
}

/**
Expand Down
53 changes: 38 additions & 15 deletions MdeModulePkg/Core/Dxe/SysCall/BootServices.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
**/

#include <Uefi.h>
#include "DxeMain.h"

#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/DevicePathUtilities.h>

VOID
EFIAPI
Expand Down Expand Up @@ -50,6 +48,7 @@ CallBootService (
UINT32 Arg6;

EFI_GUID *CoreProtocol;
UINT32 MemoryCoreSize;

// Stack:
// rcx - Rip for SYSCALL
Expand All @@ -59,13 +58,6 @@ CallBootService (
// r11 - User data segment selector <- CoreRbp
// rsp - User Rsp
switch (Type) {
case SysCallAllocateRing3Pages:
Status = gBS->AllocateRing3Pages (*((UINTN *)CoreRbp + 3), &Pointer);
DisableSMAP ();
*(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer;
EnableSMAP ();
return (UINTN)Status;

case SysCallLocateProtocol:
DisableSMAP ();
CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 3));
Expand All @@ -81,10 +73,25 @@ CallBootService (
&Pointer
);

FreePool (CoreProtocol);
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);
return EFI_OUT_OF_RESOURCES;
}

DisableSMAP ();
*((UINTN *)UserRsp + 5) = (UINTN)Pointer;
*(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer;
EnableSMAP ();

FreePool (CoreProtocol);

return (UINTN)Status;

case SysCallOpenProtocol:
Expand All @@ -108,11 +115,27 @@ CallBootService (
Arg6
);

FreePool (CoreProtocol);
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);
return EFI_OUT_OF_RESOURCES;
}

DisableSMAP ();
*((UINTN *)UserRsp + 5) = (UINTN)Pointer;
*(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer;
EnableSMAP ();

FreePool (CoreProtocol);

return (UINTN)Status;

default:
break;
}
Expand Down
9 changes: 0 additions & 9 deletions MdePkg/Include/Uefi/UefiSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,6 @@ EFI_STATUS
IN OUT EFI_PHYSICAL_ADDRESS *Memory
);

typedef
EFI_STATUS
(EFIAPI *EFI_ALLOCATE_RING3_PAGES)(
IN UINTN Pages,
IN OUT VOID **Memory
);

/**
Frees memory pages.
Expand Down Expand Up @@ -1967,13 +1960,11 @@ typedef struct {
EFI_COPY_MEM CopyMem;
EFI_SET_MEM SetMem;
EFI_CREATE_EVENT_EX CreateEventEx;
EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages;
} EFI_BOOT_SERVICES;

typedef enum {
SysCallLocateProtocol = 1,
SysCallOpenProtocol = 2,
SysCallAllocateRing3Pages = 3,
SysCallMax
} SYS_CALL_TYPE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,7 @@ EFI_BOOT_SERVICES mBootServices = {
(EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx
};

EFI_BOOT_SERVICES *gBS = &mBootServices;

EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mCoreDevicePathUtilitiesProtocol = NULL;
EFI_LOADED_IMAGE_PROTOCOL *mCoreLoadedImageProtocol = NULL;
EFI_BOOT_SERVICES *gBS = &mBootServices;

/**
The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES.
Expand Down Expand Up @@ -460,36 +457,11 @@ Ring3OpenProtocol (
}

if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) {
mCoreLoadedImageProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface;

Status = (EFI_STATUS)SysCall (
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 = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface;

*Interface = UserProtocol;
// TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces().

UserProtocol->Unload = NULL;

return Status;
}
Expand Down Expand Up @@ -570,18 +542,7 @@ Ring3LocateProtocol (
}

if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) {
mCoreDevicePathUtilitiesProtocol = (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 = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface;

UserProtocol->GetDevicePathSize = NULL;
UserProtocol->DuplicateDevicePath = NULL;
Expand All @@ -592,8 +553,6 @@ Ring3LocateProtocol (
UserProtocol->IsDevicePathMultiInstance = NULL;
UserProtocol->CreateDeviceNode = NULL;

*Interface = UserProtocol;

return Status;
}

Expand Down

0 comments on commit 1a32743

Please sign in to comment.