diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 2f92c49c06..a7db34c55f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -132,6 +132,7 @@ gEfiEndOfDxeEventGroupGuid ## SOMETIMES_CONSUMES ## Event gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB + gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 53c7ff00f4..e0800f446f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "Ring3.h" @@ -200,10 +201,12 @@ Ring3Initialization ( Ring3Data = (RING3_DATA *)SystemTable; - Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; - Ring3Data->BootServices = &mBootServices; + Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; + Ring3Data->BootServices = &mBootServices; + Ring3Data->RuntimeServices = &mRuntimeServices; gBS = &mBootServices; + gRT = &mRuntimeServices; CoreInitializePool (); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 71cc66b2e2..426e9e07c3 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -42,6 +42,7 @@ MemoryPoolLib UefiBootServicesTableLib UefiDriverEntryPoint + UefiRuntimeServicesTableLib [Protocols] gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c index bb579e8b15..aabd1f1e26 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -89,9 +89,14 @@ Ring3GetVariable ( OUT VOID *Data OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetVariable is not supported\n")); - - return EFI_UNSUPPORTED; + return SysCall ( + SysCallGetVariable, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 8233ec96af..2f2473be62 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1611,7 +1611,8 @@ InitializeRing3 ( gRing3EntryPoint = gRing3Data->EntryPoint; - gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; Status = CoreAllocatePages ( AllocateAnyPages, diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index f6a1b79f4e..212204e5cb 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -85,6 +85,10 @@ FindGuid ( *Core = &gEfiUnicodeCollationProtocolGuid; *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiGlobalVariableGuid)) { + + *Core = &gEfiGlobalVariableGuid; + } else { DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); return EFI_NOT_FOUND; @@ -533,8 +537,8 @@ CallBootService ( // // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType // Argument 2: EFI_GUID *Protocol OPTIONAL - // Argument 3: VOID *SearchKey OPTIONAL, - // Argument 4: UINTN *NumberHandles, + // Argument 3: VOID *SearchKey OPTIONAL + // Argument 4: UINTN *NumberHandles // Argument 5: EFI_HANDLE **Buffer // if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { @@ -581,11 +585,11 @@ CallBootService ( PagesNumber = EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - (EFI_PHYSICAL_ADDRESS *)&Ring3Pages - ); + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + ); if (EFI_ERROR (Status)) { return Status; } @@ -600,6 +604,96 @@ CallBootService ( return StatusBS; + case SysCallGetVariable: + // + // Argument 1: CHAR16 *VariableName + // Argument 2: EFI_GUID *VendorGuid + // Argument 3: UINT32 *Attributes OPTIONAL + // Argument 4: UINTN *DataSize + // Argument 5: VOID *Data OPTIONAL + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); + if ((VOID *)Argument6 == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return Status; + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = *(UINTN *)UserRsp->Arguments[4]; + + if ((VOID *)UserRsp->Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Status = gRT->GetVariable ( + (CHAR16 *)Argument6, + CoreProtocol, + (UINT32 *)&Attributes, + &Argument4, + (VOID *)Argument5 + ); + + DisableSMAP (); + if ((VOID *)UserRsp->Arguments[5] != NULL) { + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + } + + *(UINTN *)UserRsp->Arguments[4] = Argument4; + + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; + } + EnableSMAP (); + + FreePool ((VOID *)Argument6); + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + case SysCallBlockIoReset: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index ea56d88ff3..8f93030aa6 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2031,6 +2031,7 @@ typedef enum { // // RuntimeServices // + SysCallGetVariable, // // Protocols // @@ -2137,9 +2138,10 @@ typedef struct { } EFI_SYSTEM_TABLE; typedef struct { - EFI_SYSTEM_TABLE SystemTable; - VOID *EntryPoint; - EFI_BOOT_SERVICES *BootServices; + EFI_SYSTEM_TABLE SystemTable; + VOID *EntryPoint; + EFI_BOOT_SERVICES *BootServices; + EFI_RUNTIME_SERVICES *RuntimeServices; } RING3_DATA; typedef struct {