diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 914b08d1ce..7ff3f0c69c 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -68,6 +68,8 @@ DxeMain/DxeProtocolNotify.c DxeMain/DxeMain.c SysCall/BootServices.c + SysCall/SupportedProtocols.h + SysCall/DriverBindingProtocol.c [Sources.X64] SysCall/X64/CoreBootServices.nasm @@ -163,6 +165,7 @@ gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES + gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES # Arch Protocols gEfiBdsArchProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 925b5d6eea..c579873bec 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -6,9 +6,13 @@ **/ #include "DxeMain.h" +#include "SupportedProtocols.h" +#include #include +#define MAX_LIST 32 + VOID EFIAPI DisableSMAP ( @@ -68,6 +72,10 @@ CallBootService ( EFI_HANDLE Argument4; EFI_HANDLE Argument5; UINT32 Argument6; + UINT32 Index; + UINTN *ArgList[MAX_LIST]; + + EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -80,12 +88,14 @@ CallBootService ( // Argument 3: VOID **Interface // DisableSMAP (); - CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)CoreRbp->Argument1); - EnableSMAP (); - if (CoreProtocol == NULL) { - DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); - return EFI_OUT_OF_RESOURCES; + if (CompareGuid ((EFI_GUID *)CoreRbp->Argument1, &gEfiDevicePathUtilitiesProtocolGuid)) { + CoreProtocol = &gEfiDevicePathUtilitiesProtocolGuid; + MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); + } else { + CoreProtocol = NULL; + MemoryCoreSize = 0; } + EnableSMAP (); Status = gBS->LocateProtocol ( CoreProtocol, @@ -93,16 +103,9 @@ CallBootService ( &Interface ); - if (CompareGuid (CoreProtocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); - } else { - MemoryCoreSize = 0; - } - Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); - FreePool (CoreProtocol); return EFI_OUT_OF_RESOURCES; } @@ -110,8 +113,6 @@ CallBootService ( *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); - FreePool (CoreProtocol); - return Status; case SysCallOpenProtocol: @@ -124,15 +125,18 @@ CallBootService ( // Argument 6: UINT32 Attributes // DisableSMAP (); - CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)CoreRbp->Argument2); + if (CompareGuid ((EFI_GUID *)CoreRbp->Argument2, &gEfiLoadedImageProtocolGuid)) { + CoreProtocol = &gEfiLoadedImageProtocolGuid; + MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); + } else { + CoreProtocol = NULL; + MemoryCoreSize = 0; + } + Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; Argument5 = (EFI_HANDLE)UserRsp->Arguments[5]; Argument6 = (UINT32)UserRsp->Arguments[6]; EnableSMAP (); - if (CoreProtocol == NULL) { - DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); - return EFI_OUT_OF_RESOURCES; - } Status = gBS->OpenProtocol ( (EFI_HANDLE)CoreRbp->Argument1, @@ -143,16 +147,9 @@ CallBootService ( Argument6 ); - if (CompareGuid (CoreProtocol, &gEfiLoadedImageProtocolGuid)) { - MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); - } else { - MemoryCoreSize = 0; - } - Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); - FreePool (CoreProtocol); return EFI_OUT_OF_RESOURCES; } @@ -160,7 +157,47 @@ CallBootService ( *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); - FreePool (CoreProtocol); + return Status; + + case SysCallInstallMultipleProtocolInterfaces: + // + // Argument 1: EFI_HANDLE *Handle + // ... + // + DisableSMAP (); + for (Index = 0; ((VOID *)UserRsp->Arguments[Index] != NULL) && (Index < MAX_LIST); Index += 2) { + if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiDriverBindingProtocolGuid)) { + ArgList[Index] = (UINTN *)&gEfiDriverBindingProtocolGuid; + MemoryCoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); + } else if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiComponentNameProtocolGuid)) { + ArgList[Index] = (UINTN *)&gEfiComponentNameProtocolGuid; + MemoryCoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + } else { + DEBUG ((DEBUG_INFO, "Ring0: Argument %d is not a GUID.\n", Index)); + } + + ArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserRsp->Arguments[Index + 1]); + } + EnableSMAP (); + + if ((Index == MAX_LIST) && ((VOID *)UserRsp->Arguments[Index] != NULL)) { + DEBUG ((DEBUG_ERROR, "Ring0: Too many protocols!\n")); + return EFI_OUT_OF_RESOURCES; + } + + ArgList[Index] = NULL; + + for (Index = 0; ArgList[Index] != NULL; Index += 2) { + if (CompareGuid ((EFI_GUID *)ArgList[Index], &gEfiDriverBindingProtocolGuid)) { + CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)ArgList[Index + 1]; + + CoreDriverBinding->Supported = CoreDriverBindingSupported; + CoreDriverBinding->Start = CoreDriverBindingStart; + CoreDriverBinding->Stop = CoreDriverBindingStop; + } + } + + Status = gBS->InstallMultipleProtocolInterfaces ((EFI_HANDLE *)ArgList); return Status; diff --git a/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c b/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c new file mode 100644 index 0000000000..80143dccb6 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c @@ -0,0 +1,42 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h new file mode 100644 index 0000000000..07c43d162a --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -0,0 +1,31 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index bd795b7b9a..80c6ebf7db 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2014,8 +2014,9 @@ typedef struct { } EFI_BOOT_SERVICES; typedef enum { - SysCallLocateProtocol = 1, - SysCallOpenProtocol = 2, + SysCallLocateProtocol = 1, + SysCallOpenProtocol = 2, + SysCallInstallMultipleProtocolInterfaces = 3, SysCallMax } SYS_CALL_TYPE; diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 24b87c3f91..27f0c39fdd 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -564,7 +564,10 @@ Ring3InstallMultipleProtocolInterfaces ( ... ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallInstallMultipleProtocolInterfaces, + Handle + ); } EFI_STATUS