From 2cd1b35113a35ab0c943b70dc36ea724ca6c9ca2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 27 Jan 2025 18:51:13 +0300 Subject: [PATCH] Core/Dxe: Placed platform dependent code into separate files. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 5 +- MdeModulePkg/Core/Dxe/Image/Image.c | 3 + .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 84 +++++++++- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 80 +++++++++- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 59 +++++++- .../Core/Dxe/SysCall/Initialization.c | 143 ++++-------------- .../Core/Dxe/SysCall/X64/InitializeX64.c | 59 +++++++- 7 files changed, 294 insertions(+), 139 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 2f9e558fb5..ca533c5406 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -149,10 +149,10 @@ gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall - gEarlyPL011BaseAddressGuid ## CONSUMES [Guids.ARM, Guids.AARCH64] - gArmVirtSystemMemorySizeGuid ## CONSUMES + gArmVirtSystemMemorySizeGuid ## SOMETIMES_CONSUMES ## SysCall + gEarlyPL011BaseAddressGuid ## SOMETIMES_CONSUMES ## SysCall [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB @@ -226,7 +226,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES [Pcd.IA32, Pcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index f124a15d96..6fa3c90160 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1700,6 +1700,9 @@ CoreStartImage ( if (PcdGetBool (PcdEnableUserSpace) && (Image->IsUserImage)) { if (gRing3Data == NULL) { Image->Status = InitializeRing3 (ImageHandle, Image); + if (EFI_ERROR (Image->Status)) { + CpuDeadLoop (); + } } else { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 3541667e50..854f80301c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -6,6 +6,7 @@ **/ #include +#include #include #include #include @@ -14,6 +15,10 @@ UINTN gUserPageTable; +STATIC UINTN mConfigurationTable; +STATIC UINTN mConfigurationTableSize; +STATIC UINTN mUartBaseAddress; + EFI_STATUS EFIAPI ArmCallRing3 ( @@ -89,15 +94,55 @@ MakeUserPageTableTemplate ( ); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { - UINTN Tcr; - UINTN Sctlr; + EFI_STATUS Status; + UINTN Tcr; + UINTN Sctlr; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + EARLY_PL011_BASE_ADDRESS *UartBase; + CONST VOID *Hob; + + mConfigurationTableSize = (System->NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (mConfigurationTableSize), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } + + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + for (Index = 0; Index < System->NumberOfTableEntries; ++Index) { + CopyGuid (&Conf->VendorGuid, &System->ConfigurationTable[Index].VendorGuid); + + Conf->VendorTable = System->ConfigurationTable[Index].VendorTable; + + ++Conf; + } + + Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); + UartBase = GET_GUID_HOB_DATA (Hob); + mUartBaseAddress = (UINTN)UartBase->DebugAddress; + + CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); + Conf->VendorTable = (VOID *)mUartBaseAddress; + ++System->NumberOfTableEntries; + + System->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + mConfigurationTable = (UINTN)Physical; + // // Disable Hierarchical permissions just in case. // @@ -118,6 +163,33 @@ InitializeMsr ( InitializeSysCallHandler ((VOID *)SysCallBootService); SetExceptionAddresses (NULL, 0); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mConfigurationTable, + ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + // + // Necessary fix for DEBUG printings. + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mUartBaseAddress, + SIZE_4KB, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 66804b9d71..dd0bc1c51f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -5,6 +5,7 @@ **/ +#include #include #include #include @@ -13,6 +14,10 @@ UINTN gUserPageTable; +STATIC UINTN mConfigurationTable; +STATIC UINTN mConfigurationTableSize; +STATIC UINTN mUartBaseAddress; + EFI_STATUS EFIAPI ArmCallRing3 ( @@ -116,13 +121,53 @@ MakeUserPageTableTemplate ( ); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + EARLY_PL011_BASE_ADDRESS *UartBase; + CONST VOID *Hob; + + mConfigurationTableSize = (System->NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (mConfigurationTableSize), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } + + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + for (Index = 0; Index < System->NumberOfTableEntries; ++Index) { + CopyGuid (&Conf->VendorGuid, &System->ConfigurationTable[Index].VendorGuid); + + Conf->VendorTable = System->ConfigurationTable[Index].VendorTable; + + ++Conf; + } + + Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); + UartBase = GET_GUID_HOB_DATA (Hob); + mUartBaseAddress = (UINTN)UartBase->DebugAddress; + + CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); + Conf->VendorTable = (VOID *)mUartBaseAddress; + ++System->NumberOfTableEntries; + + System->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + mConfigurationTable = (UINTN)Physical; + if (ArmHasPan ()) { // // Enable Privileged Access Never feature. @@ -132,6 +177,33 @@ InitializeMsr ( InitializeSysCallHandler (SysCallBootService); SetExceptionAddresses (NULL, 0); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mConfigurationTable, + ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + // + // Necessary fix for DEBUG printings. + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mUartBaseAddress, + SIZE_4KB, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index b2725303d2..f9b615914a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -10,6 +10,8 @@ #include #include +extern EXCEPTION_ADDRESSES *mExceptionAddresses; + VOID EFIAPI MakeUserPageTableTemplate ( @@ -87,11 +89,10 @@ MakeUserPageTableTemplate ( *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { UINT64 Msr; @@ -140,7 +141,7 @@ InitializeMsr ( AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); if ((Edx & BIT11) == 0) { DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n")); - CpuDeadLoop (); + return EFI_UNSUPPORTED; } // @@ -154,4 +155,52 @@ InitializeMsr ( AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); gCorePageTable = AsmReadCr3 (); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + + AsmReadIdtr (&IdtDescriptor); + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + IdtDescriptor.Base, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + } diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 20949c0019..7302ef6e49 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -5,25 +5,20 @@ **/ -#include - #include "DxeMain.h" VOID *gRing3EntryPoint; RING3_DATA *gRing3Data; VOID *gRing3Interfaces; -UINTN gUartBaseAddress; - -UEFI_IMAGE_RECORD *mDxeRing3; -EXCEPTION_ADDRESSES *mExceptionAddresses; -UINTN mConfigurationTable; -UINTN mConfigurationTableSize; -EFI_PHYSICAL_ADDRESS mCoreStackBase; -UINT64 mCoreStackSize; +EXCEPTION_ADDRESSES *mExceptionAddresses; extern UINTN SysCallBase; extern UINTN SysCallEnd; +STATIC UEFI_IMAGE_RECORD *mDxeRing3; +STATIC EFI_PHYSICAL_ADDRESS mCoreStackBase; +STATIC UINT64 mCoreStackSize; + VOID EFIAPI MakeUserPageTableTemplate ( @@ -31,11 +26,16 @@ MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplateSize ); +EFI_STATUS +EFIAPI +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System + ); + VOID EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +MapPlatform ( + IN OUT UINTN UserPageTable ); EFI_STATUS @@ -47,10 +47,6 @@ InitializeRing3 ( { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; - UINTN Index; - EFI_CONFIGURATION_TABLE *Conf; - EARLY_PL011_BASE_ADDRESS *UartBase; - CONST VOID *Hob; EFI_PEI_HOB_POINTERS PeiHob; EFI_HOB_MEMORY_ALLOCATION *MemoryHob; @@ -78,43 +74,6 @@ InitializeRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - if (PcdGetBool (PcdSerialUseMmio)) { - mConfigurationTableSize = (gRing3Data->SystemTable.NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (mConfigurationTableSize), - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); - return Status; - } - - Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - - for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { - CopyGuid (&(Conf->VendorGuid), &gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid); - - Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; - - ++Conf; - } - - Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); - UartBase = GET_GUID_HOB_DATA (Hob); - gUartBaseAddress = (UINTN)UartBase->DebugAddress; - - CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); - Conf->VendorTable = (VOID *)gUartBaseAddress; - ++gRing3Data->SystemTable.NumberOfTableEntries; - - DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = 0x%p\n", gUartBaseAddress)); - - gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - mConfigurationTable = (UINTN)Physical; - } // // Initialize DxeRing3 with Supervisor privileges. // @@ -155,10 +114,18 @@ InitializeRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - InitializeMsr ( - gRing3Data->SystemTable.ConfigurationTable, - gRing3Data->SystemTable.NumberOfTableEntries - ); + Status = InitializePlatform (&gRing3Data->SystemTable); + if (EFI_ERROR (Status)) { + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Interfaces, + RING3_INTERFACES_PAGES + ); + return Status; + } mExceptionAddresses = GetExceptionAddresses (); @@ -249,7 +216,7 @@ InitializeUserPageTable ( ); // - // Map ExceptionHandlers, ExceptionStacks, Idt + // Map ExceptionHandlers // gCpu->SetUserMemoryAttributes ( gCpu, @@ -267,63 +234,7 @@ InitializeUserPageTable ( EFI_MEMORY_XP ); -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - IA32_DESCRIPTOR IdtDescriptor; - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)&gCorePageTable, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionStackBase, - mExceptionAddresses->ExceptionStackSize, - EFI_MEMORY_XP - ); - - AsmReadIdtr (&IdtDescriptor); - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - IdtDescriptor.Base, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); -#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mConfigurationTable, - ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - // - // Necessary fix for DEBUG printings. - // - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - gUartBaseAddress, - SIZE_4KB, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); -#endif + MapPlatform (UserPageTable); // // Map User Image diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c index 04325c5b47..9428f7fbb9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c @@ -11,6 +11,8 @@ #include #include +extern EXCEPTION_ADDRESSES *mExceptionAddresses; + VOID EFIAPI MakeUserPageTableTemplate ( @@ -284,11 +286,10 @@ MakeUserPageTableTemplate ( *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { UINT64 Msr; @@ -342,7 +343,7 @@ InitializeMsr ( AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); } else { DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n")); - CpuDeadLoop (); + return EFI_UNSUPPORTED; } // @@ -360,4 +361,52 @@ InitializeMsr ( AsmWriteMsr64 (MSR_IA32_FMASK, Msr); gCorePageTable = AsmReadCr3 (); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + + AsmReadIdtr (&IdtDescriptor); + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + IdtDescriptor.Base, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + }