Ring3: Added PrepareRing3Interface().

This commit is contained in:
Mikhail Krichanov 2024-02-29 20:19:02 +03:00
parent c855d93030
commit 94017d9567
5 changed files with 102 additions and 52 deletions

View File

@ -115,6 +115,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define DEPEX_STACK_SIZE_INCREMENT 0x1000
#define USER_STACK_SIZE 0x20000
#define RING3_INTERFACES_PAGES 20
typedef struct {
EFI_GUID *ProtocolGuid;
@ -269,6 +270,10 @@ extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate;
extern EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfigurationTable;
extern BOOLEAN gLoadFixedAddressCodeMemoryReady;
extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage;
extern RING3_DATA *gRing3Data;
extern VOID *gRing3Interfaces;
//
// Service Initialization Functions
//

View File

@ -840,6 +840,16 @@ CoreExitBootServices (
//
gRuntime->AtRuntime = TRUE;
CoreFreePages (
(EFI_PHYSICAL_ADDRESS)gRing3Data,
EFI_SIZE_TO_PAGES (sizeof (RING3_DATA))
);
CoreFreePages (
(EFI_PHYSICAL_ADDRESS)gRing3Interfaces,
RING3_INTERFACES_PAGES
);
return Status;
}

View File

@ -7,9 +7,6 @@
#include "Ring3.h"
EFI_BLOCK_IO_PROTOCOL mCoreBlockIo;
EFI_DISK_IO_PROTOCOL mCoreDiskIo;
EFI_STATUS
EFIAPI
Ring3BlockIoReset (

View File

@ -30,7 +30,8 @@ extern BOOLEAN gBdsStarted;
VOID *gCoreSysCallStackTop;
VOID *gRing3CallStackTop;
VOID *gRing3EntryPoint;
RING3_DATA *mRing3Data;
RING3_DATA *gRing3Data;
VOID *gRing3Interfaces;
//
// This code is needed to build the Image handle for the DXE Core
@ -1593,13 +1594,14 @@ AllocateRing3Copy (
return MemoryRing3;
}
VOID
EFI_STATUS
EFIAPI
InitializeRing3 (
IN EFI_HANDLE ImageHandle,
IN LOADED_IMAGE_PRIVATE_DATA *Image
)
{
EFI_STATUS Status;
VOID *BaseOfStack;
VOID *TopOfStack;
UINTN SizeOfStack;
@ -1616,18 +1618,39 @@ InitializeRing3 (
//
// Set Ring3 EntryPoint and BootServices.
//
mRing3Data = AllocateRing3Copy (
(VOID *)Image->Info.SystemTable,
sizeof (RING3_DATA),
sizeof (EFI_SYSTEM_TABLE)
);
ASSERT (mRing3Data != NULL);
Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data);
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)),
(EFI_PHYSICAL_ADDRESS *)&gRing3Data
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n"));
return Status;
}
gRing3EntryPoint = mRing3Data->EntryPoint;
CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE));
mRing3Data->SystemTable.BootServices = mRing3Data->BootServices;
Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data);
gRing3EntryPoint = gRing3Data->EntryPoint;
gRing3Data->SystemTable.BootServices = gRing3Data->BootServices;
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
RING3_INTERFACES_PAGES,
(EFI_PHYSICAL_ADDRESS *)&gRing3Interfaces
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n"));
CoreFreePages (
(EFI_PHYSICAL_ADDRESS)gRing3Data,
EFI_SIZE_TO_PAGES (sizeof (RING3_DATA))
);
return Status;
}
//
// Forbid supervisor-mode accesses to any user-mode pages.
@ -1703,6 +1726,8 @@ InitializeRing3 (
Msr = (UINT64)(UINTN)CoreBootServices;
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
return Status;
}
/**
@ -1832,7 +1857,7 @@ CoreStartImage (
Image->Started = TRUE;
if (Image->IsRing3EntryPoint) {
InitializeRing3 (ImageHandle, Image);
Image->Status = InitializeRing3 (ImageHandle, Image);
} else if (Image->IsUserImage) {
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
@ -1841,7 +1866,7 @@ CoreStartImage (
2,
(VOID *)Image->EntryPoint,
ImageHandle,
mRing3Data
gRing3Data
);
} else {
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);

View File

@ -10,6 +10,7 @@
EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol;
EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol;
UINTN mRing3InterfacePointer = 0;
EFI_STATUS
EFIAPI
@ -20,6 +21,7 @@ CallInstallMultipleProtocolInterfaces (
IN VOID *Function
);
STATIC
EFI_STATUS
EFIAPI
FindGuid (
@ -79,24 +81,56 @@ FindGuid (
return EFI_SUCCESS;
}
VOID
STATIC
VOID *
EFIAPI
FixInterface (
IN EFI_GUID *Guid,
IN OUT VOID *Interface
PrepareRing3Interface (
IN EFI_GUID *Guid,
IN VOID *CoreInterface,
IN UINT32 CoreSize
)
{
UINTN Ring3Limit;
VOID *Ring3Interface;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) {
BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Interface;
ASSERT (Guid != NULL);
ASSERT (CoreInterface != NULL);
BlockIo->Media = AllocateRing3Copy (
BlockIo->Media,
sizeof (EFI_BLOCK_IO_MEDIA),
sizeof (EFI_BLOCK_IO_MEDIA)
);
if (mRing3InterfacePointer == 0) {
mRing3InterfacePointer = (UINTN)gRing3Interfaces;
}
Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES);
ASSERT ((mRing3InterfacePointer + sizeof (EFI_GUID) + CoreSize) <= Ring3Limit);
CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)Guid, sizeof (EFI_GUID));
mRing3InterfacePointer += sizeof (EFI_GUID);
Ring3Interface = (VOID *)mRing3InterfacePointer;
CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize);
mRing3InterfacePointer += CoreSize;
if (CompareGuid (Guid, &gEfiDiskIoProtocolGuid)) {
mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)CoreInterface;
} else if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) {
ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit);
mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)CoreInterface;
BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface;
CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));
BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer;
mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA);
}
return Ring3Interface;
}
typedef struct {
@ -170,11 +204,7 @@ CallBootService (
DisableSMAP ();
if (Interface != NULL) {
Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize);
if (Interface == NULL) {
EnableSMAP ();
return EFI_OUT_OF_RESOURCES;
}
Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize);
}
*(VOID **)CoreRbp->Argument3 = Interface;
@ -214,19 +244,7 @@ CallBootService (
DisableSMAP ();
if (Interface != NULL) {
if (CompareGuid (CoreProtocol, &gEfiDiskIoProtocolGuid)) {
mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)Interface;
} else if (CompareGuid (CoreProtocol, &gEfiBlockIoProtocolGuid)) {
mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)Interface;
}
Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize);
if (Interface == NULL) {
EnableSMAP ();
return EFI_OUT_OF_RESOURCES;
}
FixInterface (CoreProtocol, Interface);
Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize);
}
*(VOID **)CoreRbp->Argument3 = Interface;
@ -338,12 +356,7 @@ CallBootService (
DisableSMAP ();
if (Interface != NULL) {
Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize);
if (Interface == NULL) {
EnableSMAP ();
return EFI_OUT_OF_RESOURCES;
}
Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize);
}
*(VOID **)CoreRbp->Argument3 = Interface;