SysCall: Refactored Core wrappers to allow support for multiple User space drivers.

This commit is contained in:
Mikhail Krichanov 2025-01-09 15:42:04 +03:00
parent f3b5cea966
commit ce3bfc7754
4 changed files with 240 additions and 183 deletions

View File

@ -1446,7 +1446,6 @@ CoreLoadImageCommon (
if ((gRing3Data != NULL) && Image->IsUserImage) { if ((gRing3Data != NULL) && Image->IsUserImage) {
Image->UserPageTable = InitializeUserPageTable (Image); Image->UserPageTable = InitializeUserPageTable (Image);
gUserPageTable = Image->UserPageTable;
} }
RegisterMemoryProfileImage ( RegisterMemoryProfileImage (
@ -1704,6 +1703,8 @@ CoreStartImage (
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0); ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
gUserPageTable = Image->UserPageTable;
Image->Status = GoToRing3 ( Image->Status = GoToRing3 (
2, 2,
(VOID *)Image->EntryPoint, (VOID *)Image->EntryPoint,

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved. Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
**/ **/
@ -302,6 +302,7 @@ CallBootService (
EFI_HANDLE CoreHandle; EFI_HANDLE CoreHandle;
UINT32 PagesNumber; UINT32 PagesNumber;
EFI_PHYSICAL_ADDRESS Ring3Pages; EFI_PHYSICAL_ADDRESS Ring3Pages;
USER_SPACE_DRIVER *UserDriver;
EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem;
@ -465,6 +466,15 @@ CallBootService (
ASSERT ((Attributes & EFI_MEMORY_USER) != 0); ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]);
//
// TODO: Check everywhere that Allocated != NULL
//
UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
UserDriver->CoreWrapper = CoreArgList[Index + 1];
UserDriver->UserSpaceDriver = UserArgList[Index + 1];
UserDriver->UserPageTable = gUserPageTable;
InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link);
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0); ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
@ -478,23 +488,13 @@ CallBootService (
if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) {
CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1];
mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported;
mRing3DriverBindingProtocol.Start = CoreDriverBinding->Start;
mRing3DriverBindingProtocol.Stop = CoreDriverBinding->Stop;
CoreDriverBinding->Supported = CoreDriverBindingSupported; CoreDriverBinding->Supported = CoreDriverBindingSupported;
CoreDriverBinding->Start = CoreDriverBindingStart; CoreDriverBinding->Start = CoreDriverBindingStart;
CoreDriverBinding->Stop = CoreDriverBindingStop; CoreDriverBinding->Stop = CoreDriverBindingStop;
} else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) {
CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1];
mRing3SimpleFileSystemProtocol.OpenVolume = CoreSimpleFileSystem->OpenVolume;
CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; CoreSimpleFileSystem->OpenVolume = CoreOpenVolume;
AllowSupervisorAccessToUserMemory ();
mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1];
ForbidSupervisorAccessToUserMemory ();
} }
} }

View File

@ -1,22 +1,14 @@
/** @file /** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved. Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
**/ **/
#include "DxeMain.h" #include "DxeMain.h"
#include "SupportedProtocols.h"
EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; LIST_ENTRY mUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (mUserSpaceDriversHead);
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol;
EFI_FILE_PROTOCOL mRing3FileProtocol;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer;
typedef struct {
EFI_FILE_PROTOCOL Protocol;
EFI_FILE_PROTOCOL *Ring3File;
} RING3_EFI_FILE_PROTOCOL;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -66,31 +58,24 @@ GoToRing3 (
} }
STATIC STATIC
VOID * USER_SPACE_DRIVER *
EFIAPI EFIAPI
Ring3Copy ( FindUserSpaceDriver (
IN VOID *Core, IN VOID *CoreWrapper
IN UINT32 Size
) )
{ {
EFI_STATUS Status; LIST_ENTRY *Link;
EFI_PHYSICAL_ADDRESS Ring3; USER_SPACE_DRIVER *UserDriver;
Status = CoreAllocatePages ( for (Link = mUserSpaceDriversHead.ForwardLink; Link != &mUserSpaceDriversHead; Link = Link->ForwardLink) {
AllocateAnyPages, UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link);
EfiRing3MemoryType,
1, if (UserDriver->CoreWrapper == CoreWrapper) {
&Ring3 return UserDriver;
); }
if (EFI_ERROR (Status)) {
return NULL;
} }
AllowSupervisorAccessToUserMemory (); return NULL;
CopyMem ((VOID *)(UINTN)Ring3, Core, Size);
ForbidSupervisorAccessToUserMemory ();
return (VOID *)(UINTN)Ring3;
} }
EFI_STATUS EFI_STATUS
@ -101,23 +86,28 @@ CoreDriverBindingSupported (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); UserDriver = FindUserSpaceDriver (This);
if (This == NULL) { ASSERT (UserDriver != NULL);
return EFI_OUT_OF_RESOURCES;
} This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory ();
EntryPoint = (VOID *)This->Supported;
ForbidSupervisorAccessToUserMemory ();
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
(VOID *)mRing3DriverBindingProtocol.Supported, EntryPoint,
This, This,
ControllerHandle, ControllerHandle,
RemainingDevicePath RemainingDevicePath
); );
CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1);
return Status; return Status;
} }
@ -129,23 +119,28 @@ CoreDriverBindingStart (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); UserDriver = FindUserSpaceDriver (This);
if (This == NULL) { ASSERT (UserDriver != NULL);
return EFI_OUT_OF_RESOURCES;
} This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory ();
EntryPoint = (VOID *)This->Start;
ForbidSupervisorAccessToUserMemory ();
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
(VOID *)mRing3DriverBindingProtocol.Start, EntryPoint,
This, This,
ControllerHandle, ControllerHandle,
RemainingDevicePath RemainingDevicePath
); );
CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1);
return Status; return Status;
} }
@ -158,24 +153,29 @@ CoreDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); UserDriver = FindUserSpaceDriver (This);
if (This == NULL) { ASSERT (UserDriver != NULL);
return EFI_OUT_OF_RESOURCES;
} This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory ();
EntryPoint = (VOID *)This->Stop;
ForbidSupervisorAccessToUserMemory ();
Status = GoToRing3 ( Status = GoToRing3 (
4, 4,
(VOID *)mRing3DriverBindingProtocol.Stop, EntryPoint,
This, This,
ControllerHandle, ControllerHandle,
NumberOfChildren, NumberOfChildren,
ChildHandleBuffer ChildHandleBuffer
); );
CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1);
return Status; return Status;
} }
@ -186,18 +186,27 @@ CoreFileClose (
IN EFI_FILE_PROTOCOL *This IN EFI_FILE_PROTOCOL *This
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
RING3_EFI_FILE_PROTOCOL *File; USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
File = (RING3_EFI_FILE_PROTOCOL *)This; UserDriver = FindUserSpaceDriver (This);
ASSERT (UserDriver != NULL);
This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory ();
EntryPoint = (VOID *)This->Close;
ForbidSupervisorAccessToUserMemory ();
Status = GoToRing3 ( Status = GoToRing3 (
1, 1,
(VOID *)mRing3FileProtocol.Close, EntryPoint,
File->Ring3File This
); );
FreePool (This); FreePool (UserDriver->CoreWrapper);
return Status; return Status;
} }
@ -221,21 +230,20 @@ CoreFileRead (
OUT VOID *Buffer OUT VOID *Buffer
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
RING3_EFI_FILE_PROTOCOL *File; UINTN *Ring3BufferSize;
UINTN *Ring3BufferSize; VOID *Ring3Buffer;
VOID *Ring3Buffer; EFI_PHYSICAL_ADDRESS Ring3Pages;
EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber;
UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
if ((This == NULL) || (BufferSize == NULL)) { if ((This == NULL) || (BufferSize == NULL)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
File = (RING3_EFI_FILE_PROTOCOL *)This;
Ring3Buffer = NULL; Ring3Buffer = NULL;
Ring3Pages = 0; Ring3Pages = 0;
PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize);
Status = CoreAllocatePages ( Status = CoreAllocatePages (
@ -250,8 +258,15 @@ CoreFileRead (
Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages;
UserDriver = FindUserSpaceDriver (This);
ASSERT (UserDriver != NULL);
This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
*Ring3BufferSize = *BufferSize; *Ring3BufferSize = *BufferSize;
EntryPoint = (VOID *)This->Read;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
if (Buffer != NULL) { if (Buffer != NULL) {
@ -260,8 +275,8 @@ CoreFileRead (
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
(VOID *)mRing3FileProtocol.Read, EntryPoint,
File->Ring3File, This,
Ring3BufferSize, Ring3BufferSize,
Ring3Buffer Ring3Buffer
); );
@ -299,15 +314,24 @@ CoreFileSetPosition (
IN UINT64 Position IN UINT64 Position
) )
{ {
RING3_EFI_FILE_PROTOCOL *File; USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
File = (RING3_EFI_FILE_PROTOCOL *)This; UserDriver = FindUserSpaceDriver (This);
ASSERT (UserDriver != NULL);
This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory ();
EntryPoint = (VOID *)This->SetPosition;
ForbidSupervisorAccessToUserMemory ();
#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) #if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64)
return GoToRing3 ( return GoToRing3 (
2, 2,
(VOID *)mRing3FileProtocol.SetPosition, EntryPoint,
File->Ring3File, This,
Position Position
); );
#elif defined (MDE_CPU_IA32) #elif defined (MDE_CPU_IA32)
@ -316,8 +340,8 @@ CoreFileSetPosition (
// //
return GoToRing3 ( return GoToRing3 (
3, 3,
(VOID *)mRing3FileProtocol.SetPosition, EntryPoint,
File->Ring3File, This,
Position Position
); );
#elif defined (MDE_CPU_ARM) #elif defined (MDE_CPU_ARM)
@ -327,8 +351,8 @@ CoreFileSetPosition (
// //
return GoToRing3 ( return GoToRing3 (
4, 4,
(VOID *)mRing3FileProtocol.SetPosition, EntryPoint,
File->Ring3File, This,
Position Position
); );
#endif #endif
@ -343,17 +367,15 @@ CoreFileGetPosition (
OUT UINT64 *Position OUT UINT64 *Position
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
RING3_EFI_FILE_PROTOCOL *File; EFI_PHYSICAL_ADDRESS Ring3Position;
EFI_PHYSICAL_ADDRESS Ring3Position; USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
if ((This == NULL) || (Position == NULL)) { if ((This == NULL) || (Position == NULL)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
File = (RING3_EFI_FILE_PROTOCOL *)This;
Ring3Position = 0;
Status = CoreAllocatePages ( Status = CoreAllocatePages (
AllocateAnyPages, AllocateAnyPages,
EfiRing3MemoryType, EfiRing3MemoryType,
@ -364,14 +386,21 @@ CoreFileGetPosition (
return Status; return Status;
} }
UserDriver = FindUserSpaceDriver (This);
ASSERT (UserDriver != NULL);
This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
*(UINT64 *)(UINTN)Ring3Position = *Position; *(UINT64 *)(UINTN)Ring3Position = *Position;
EntryPoint = (VOID *)This->GetPosition;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
Status = GoToRing3 ( Status = GoToRing3 (
2, 2,
(VOID *)mRing3FileProtocol.GetPosition, EntryPoint,
File->Ring3File, This,
Ring3Position Ring3Position
); );
@ -394,19 +423,19 @@ CoreFileGetInfo (
OUT VOID *Buffer OUT VOID *Buffer
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
RING3_EFI_FILE_PROTOCOL *File; EFI_GUID *Ring3InformationType;
EFI_GUID *Ring3InformationType; UINTN *Ring3BufferSize;
UINTN *Ring3BufferSize; VOID *Ring3Buffer;
VOID *Ring3Buffer; EFI_PHYSICAL_ADDRESS Ring3Pages;
EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber;
UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
if ((This == NULL) || (BufferSize == NULL)) { if ((This == NULL) || (BufferSize == NULL)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
File = (RING3_EFI_FILE_PROTOCOL *)This;
Ring3Buffer = NULL; Ring3Buffer = NULL;
Ring3InformationType = NULL; Ring3InformationType = NULL;
Ring3Pages = 0; Ring3Pages = 0;
@ -425,8 +454,15 @@ CoreFileGetInfo (
Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages;
UserDriver = FindUserSpaceDriver (This);
ASSERT (UserDriver != NULL);
This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
*Ring3BufferSize = *BufferSize; *Ring3BufferSize = *BufferSize;
EntryPoint = (VOID *)This->GetInfo;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
if (Buffer != NULL) { if (Buffer != NULL) {
@ -443,8 +479,8 @@ CoreFileGetInfo (
Status = GoToRing3 ( Status = GoToRing3 (
4, 4,
(VOID *)mRing3FileProtocol.GetInfo, EntryPoint,
File->Ring3File, This,
Ring3InformationType, Ring3InformationType,
Ring3BufferSize, Ring3BufferSize,
Ring3Buffer Ring3Buffer
@ -545,19 +581,19 @@ CoreFileOpen (
IN UINT64 Attributes IN UINT64 Attributes
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
RING3_EFI_FILE_PROTOCOL *File; EFI_FILE_PROTOCOL *NewFile;
RING3_EFI_FILE_PROTOCOL *NewFile; EFI_FILE_PROTOCOL **Ring3NewHandle;
EFI_FILE_PROTOCOL **Ring3NewHandle; CHAR16 *Ring3FileName;
CHAR16 *Ring3FileName; EFI_PHYSICAL_ADDRESS Ring3Pages;
EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber;
UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
File = (RING3_EFI_FILE_PROTOCOL *)This;
Ring3NewHandle = NULL; Ring3NewHandle = NULL;
Ring3FileName = NULL; Ring3FileName = NULL;
Ring3Pages = 0; Ring3Pages = 0;
@ -578,8 +614,15 @@ CoreFileOpen (
Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages;
Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1);
UserDriver = FindUserSpaceDriver (This);
ASSERT (UserDriver != NULL);
This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName);
EntryPoint = (VOID *)This->Open;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
*NewHandle = NULL; *NewHandle = NULL;
@ -590,8 +633,8 @@ CoreFileOpen (
#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) #if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64)
Status = GoToRing3 ( Status = GoToRing3 (
5, 5,
(VOID *)mRing3FileProtocol.Open, EntryPoint,
File->Ring3File, This,
Ring3NewHandle, Ring3NewHandle,
Ring3FileName, Ring3FileName,
OpenMode, OpenMode,
@ -603,8 +646,8 @@ CoreFileOpen (
// //
Status = GoToRing3 ( Status = GoToRing3 (
7, 7,
(VOID *)mRing3FileProtocol.Open, EntryPoint,
File->Ring3File, This,
Ring3NewHandle, Ring3NewHandle,
Ring3FileName, Ring3FileName,
OpenMode, OpenMode,
@ -619,8 +662,8 @@ CoreFileOpen (
// //
Status = GoToRing3 ( Status = GoToRing3 (
8, 8,
(VOID *)mRing3FileProtocol.Open, EntryPoint,
File->Ring3File, This,
Ring3NewHandle, Ring3NewHandle,
Ring3FileName, Ring3FileName,
OpenMode, OpenMode,
@ -633,33 +676,39 @@ CoreFileOpen (
return Status; return Status;
} }
NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); NewFile = AllocatePool (sizeof (EFI_FILE_PROTOCOL));
if (NewFile == NULL) { if (NewFile == NULL) {
*NewHandle = NULL; *NewHandle = NULL;
CoreFreePages (Ring3Pages, PagesNumber); CoreFreePages (Ring3Pages, PagesNumber);
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
NewFile->Protocol.Revision = mRing3FileProtocol.Revision; UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
NewFile->Protocol.Open = CoreFileOpen; UserDriver->CoreWrapper = NewFile;
NewFile->Protocol.Close = CoreFileClose; UserDriver->UserPageTable = gUserPageTable;
NewFile->Protocol.Delete = CoreFileDelete;
NewFile->Protocol.Read = CoreFileRead;
NewFile->Protocol.Write = CoreFileWrite;
NewFile->Protocol.GetPosition = CoreFileGetPosition;
NewFile->Protocol.SetPosition = CoreFileSetPosition;
NewFile->Protocol.GetInfo = CoreFileGetInfo;
NewFile->Protocol.SetInfo = CoreFileSetInfo;
NewFile->Protocol.Flush = CoreFileFlush;
NewFile->Protocol.OpenEx = CoreFileOpenEx;
NewFile->Protocol.ReadEx = CoreFileReadEx;
NewFile->Protocol.WriteEx = CoreFileWriteEx;
NewFile->Protocol.FlushEx = CoreFileFlushEx;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
NewFile->Ring3File = *Ring3NewHandle; UserDriver->UserSpaceDriver = *Ring3NewHandle;
NewFile->Revision = (*Ring3NewHandle)->Revision;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link);
NewFile->Open = CoreFileOpen;
NewFile->Close = CoreFileClose;
NewFile->Delete = CoreFileDelete;
NewFile->Read = CoreFileRead;
NewFile->Write = CoreFileWrite;
NewFile->GetPosition = CoreFileGetPosition;
NewFile->SetPosition = CoreFileSetPosition;
NewFile->GetInfo = CoreFileGetInfo;
NewFile->SetInfo = CoreFileSetInfo;
NewFile->Flush = CoreFileFlush;
NewFile->OpenEx = CoreFileOpenEx;
NewFile->ReadEx = CoreFileReadEx;
NewFile->WriteEx = CoreFileWriteEx;
NewFile->FlushEx = CoreFileFlushEx;
*NewHandle = (EFI_FILE_PROTOCOL *)NewFile; *NewHandle = (EFI_FILE_PROTOCOL *)NewFile;
CoreFreePages (Ring3Pages, PagesNumber); CoreFreePages (Ring3Pages, PagesNumber);
@ -674,15 +723,27 @@ CoreOpenVolume (
OUT EFI_FILE_PROTOCOL **Root OUT EFI_FILE_PROTOCOL **Root
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_FILE_PROTOCOL **Ring3Root; EFI_FILE_PROTOCOL **Ring3Root;
RING3_EFI_FILE_PROTOCOL *File; EFI_FILE_PROTOCOL *File;
EFI_PHYSICAL_ADDRESS Physical; EFI_PHYSICAL_ADDRESS Physical;
USER_SPACE_DRIVER *UserDriver;
VOID *EntryPoint;
if (Root == NULL) { if (Root == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
UserDriver = FindUserSpaceDriver (This);
ASSERT (UserDriver != NULL);
This = UserDriver->UserSpaceDriver;
gUserPageTable = UserDriver->UserPageTable;
AllowSupervisorAccessToUserMemory ();
EntryPoint = (VOID *)This->OpenVolume;
ForbidSupervisorAccessToUserMemory ();
Status = CoreAllocatePages ( Status = CoreAllocatePages (
AllocateAnyPages, AllocateAnyPages,
EfiRing3MemoryType, EfiRing3MemoryType,
@ -698,8 +759,8 @@ CoreOpenVolume (
Status = GoToRing3 ( Status = GoToRing3 (
2, 2,
(VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, EntryPoint,
mRing3SimpleFileSystemPointer, This,
Ring3Root Ring3Root
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -708,48 +769,38 @@ CoreOpenVolume (
return Status; return Status;
} }
File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); File = AllocatePool (sizeof (EFI_FILE_PROTOCOL));
if (File == NULL) { if (File == NULL) {
*Root = NULL; *Root = NULL;
CoreFreePages (Physical, 1); CoreFreePages (Physical, 1);
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
AllowSupervisorAccessToUserMemory (); UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
mRing3FileProtocol.Revision = (*Ring3Root)->Revision; UserDriver->CoreWrapper = File;
mRing3FileProtocol.Open = (*Ring3Root)->Open; UserDriver->UserPageTable = gUserPageTable;
mRing3FileProtocol.Close = (*Ring3Root)->Close;
mRing3FileProtocol.Delete = (*Ring3Root)->Delete;
mRing3FileProtocol.Read = (*Ring3Root)->Read;
mRing3FileProtocol.Write = (*Ring3Root)->Write;
mRing3FileProtocol.GetPosition = (*Ring3Root)->GetPosition;
mRing3FileProtocol.SetPosition = (*Ring3Root)->SetPosition;
mRing3FileProtocol.GetInfo = (*Ring3Root)->GetInfo;
mRing3FileProtocol.SetInfo = (*Ring3Root)->SetInfo;
mRing3FileProtocol.Flush = (*Ring3Root)->Flush;
mRing3FileProtocol.OpenEx = (*Ring3Root)->OpenEx;
mRing3FileProtocol.ReadEx = (*Ring3Root)->ReadEx;
mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx;
mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx;
File->Ring3File = *Ring3Root; AllowSupervisorAccessToUserMemory ();
UserDriver->UserSpaceDriver = *Ring3Root;
File->Revision = (*Ring3Root)->Revision;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
File->Protocol.Revision = mRing3FileProtocol.Revision; InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link);
File->Protocol.Open = CoreFileOpen;
File->Protocol.Close = CoreFileClose; File->Open = CoreFileOpen;
File->Protocol.Delete = CoreFileDelete; File->Close = CoreFileClose;
File->Protocol.Read = CoreFileRead; File->Delete = CoreFileDelete;
File->Protocol.Write = CoreFileWrite; File->Read = CoreFileRead;
File->Protocol.GetPosition = CoreFileGetPosition; File->Write = CoreFileWrite;
File->Protocol.SetPosition = CoreFileSetPosition; File->GetPosition = CoreFileGetPosition;
File->Protocol.GetInfo = CoreFileGetInfo; File->SetPosition = CoreFileSetPosition;
File->Protocol.SetInfo = CoreFileSetInfo; File->GetInfo = CoreFileGetInfo;
File->Protocol.Flush = CoreFileFlush; File->SetInfo = CoreFileSetInfo;
File->Protocol.OpenEx = CoreFileOpenEx; File->Flush = CoreFileFlush;
File->Protocol.ReadEx = CoreFileReadEx; File->OpenEx = CoreFileOpenEx;
File->Protocol.WriteEx = CoreFileWriteEx; File->ReadEx = CoreFileReadEx;
File->Protocol.FlushEx = CoreFileFlushEx; File->WriteEx = CoreFileWriteEx;
File->FlushEx = CoreFileFlushEx;
*Root = (EFI_FILE_PROTOCOL *)File; *Root = (EFI_FILE_PROTOCOL *)File;

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved. Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
**/ **/
@ -11,9 +11,14 @@
#include <Protocol/DiskIo.h> #include <Protocol/DiskIo.h>
#include <Protocol/UnicodeCollation.h> #include <Protocol/UnicodeCollation.h>
extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; typedef struct {
extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; VOID *CoreWrapper;
extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; VOID *UserSpaceDriver;
UINTN UserPageTable;
LIST_ENTRY Link;
} USER_SPACE_DRIVER;
extern LIST_ENTRY mUserSpaceDriversHead;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI