diff --git a/MsvmPkg/Include/Ppi/ParameterConfig.h b/MsvmPkg/Include/Ppi/ParameterConfig.h new file mode 100644 index 000000000..ccb90d534 --- /dev/null +++ b/MsvmPkg/Include/Ppi/ParameterConfig.h @@ -0,0 +1,25 @@ +/** @file + SEC parameter configuration PPI definition. + + This PPI carries the optional parameter configuration header supplied in + the initial VP context from SEC to PEI. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PARAMETER_CONFIG_H_ +#define PARAMETER_CONFIG_H_ + +/// +/// PPI carrying an optional parameter configuration header from SEC to PEI. +/// A NULL header means that the legacy UEFI configuration blob is in use. +/// +typedef struct { + VOID *ParameterConfigHeader; +} MSVM_PARAMETER_CONFIG_PPI; + +extern EFI_GUID gMsvmParameterConfigPpiGuid; + +#endif // PARAMETER_CONFIG_H_ diff --git a/MsvmPkg/MsvmPkg.dec b/MsvmPkg/MsvmPkg.dec index 6132c50f9..b676d836c 100644 --- a/MsvmPkg/MsvmPkg.dec +++ b/MsvmPkg/MsvmPkg.dec @@ -53,6 +53,7 @@ [Ppis] gMsvmSecPlatformTypePpiGuid = {0x7a3b9e2c, 0x4d15, 0x4f8a, {0xb1, 0x0e, 0x3c, 0x5d, 0x8f, 0x2a, 0x6b, 0x47}} + gMsvmParameterConfigPpiGuid = {0x81b465f3, 0xa0f3, 0x46d2, {0x9e, 0xeb, 0x3b, 0x5b, 0x94, 0x6b, 0x95, 0x52}} [Protocols] gMsvmAziHsmProtocolGuid = {0x38976D4E, 0x7454, 0x40CF, {0x9E, 0x12, 0x95, 0xCE, 0x61, 0xA4, 0xCD, 0x6C}} diff --git a/MsvmPkg/PlatformPei/Config.c b/MsvmPkg/PlatformPei/Config.c index 6deb211da..cd29dbf7a 100644 --- a/MsvmPkg/PlatformPei/Config.c +++ b/MsvmPkg/PlatformPei/Config.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "Hv.h" #include "Config.h" @@ -1706,17 +1707,42 @@ Return Value: n/a --*/ -{ - EFI_STATUS status; - - // - // If this is a hardware-isolated VM running without a paravisor, then no - // config blob is present. Instead, the parameters were inserted in IGVM - // format and must be parsed as such. +{ + BOOLEAN hardwareIsolatedNoParavisor; + VOID *parameterConfigHeader; + MSVM_PARAMETER_CONFIG_PPI *parameterConfigPpi; + EFI_STATUS status; + + hardwareIsolatedNoParavisor = IsHardwareIsolatedNoParavisor(); + + // + // Older isolated images use the parameter format at the historical fixed + // address without providing an explicit pointer in their initial context. + // + parameterConfigHeader = hardwareIsolatedNoParavisor + ? GetStartOfConfigBlob() + : NULL; + + // + // SEC receives the parameter configuration address in the architecture's + // initial VP context and publishes it through this PPI. // - if (IsHardwareIsolatedNoParavisor()) - { - status = GetIgvmConfigInfo(); + status = PeiServicesLocatePpi( + &gMsvmParameterConfigPpiGuid, + 0, + NULL, + (VOID **)¶meterConfigPpi); + if (!EFI_ERROR(status) && + (parameterConfigPpi->ParameterConfigHeader != NULL)) + { + parameterConfigHeader = parameterConfigPpi->ParameterConfigHeader; + } + + if (parameterConfigHeader != NULL) + { + status = GetIgvmConfigInfo( + parameterConfigHeader, + hardwareIsolatedNoParavisor); } else { diff --git a/MsvmPkg/PlatformPei/Config.h b/MsvmPkg/PlatformPei/Config.h index 5f826af9c..897577e08 100644 --- a/MsvmPkg/PlatformPei/Config.h +++ b/MsvmPkg/PlatformPei/Config.h @@ -24,7 +24,8 @@ GetConfiguration( EFI_STATUS GetIgvmConfigInfo( - VOID + IN VOID *ParameterConfigHeader, + IN BOOLEAN HardwareIsolatedNoParavisor ); VOID diff --git a/MsvmPkg/PlatformPei/IgvmConfig.c b/MsvmPkg/PlatformPei/IgvmConfig.c index 2737be1e2..ea1ab1799 100644 --- a/MsvmPkg/PlatformPei/IgvmConfig.c +++ b/MsvmPkg/PlatformPei/IgvmConfig.c @@ -365,9 +365,10 @@ Return Value: } -EFI_STATUS -GetIgvmConfigInfo( - VOID +EFI_STATUS +GetIgvmConfigInfo( + IN VOID *ParameterConfigHeader, + IN BOOLEAN HardwareIsolatedNoParavisor ) /*++ @@ -377,7 +378,10 @@ Routine Description: Arguments: - None. + ParameterConfigHeader - Supplies the parameter area base. + + HardwareIsolatedNoParavisor - Supplies whether the VM is hardware + isolated without a paravisor. Return Value: @@ -398,7 +402,12 @@ Return Value: // area. // - parameterInfo = (UEFI_IGVM_PARAMETER_INFO *)GetStartOfConfigBlob(); + if (ParameterConfigHeader == NULL) + { + return EFI_INVALID_PARAMETER; + } + + parameterInfo = (UEFI_IGVM_PARAMETER_INFO *)ParameterConfigHeader; // // Capture the total size of config information. @@ -515,10 +524,26 @@ Return Value: // ZeroMem(&configFlags, sizeof(configFlags)); - configFlags.Flags.MeasureAdditionalPcrs = 1; - configFlags.Flags.DefaultBootAlwaysAttempt = 1; - configFlags.Flags.VpciBootEnabled = 1; - configFlags.Flags.MemoryProtectionMode = ConfigLibMemoryProtectionModeDefault; + if (HardwareIsolatedNoParavisor) + { + configFlags.Flags.MeasureAdditionalPcrs = 1; + configFlags.Flags.DefaultBootAlwaysAttempt = 1; + configFlags.Flags.VpciBootEnabled = 1; + configFlags.Flags.MemoryProtectionMode = ConfigLibMemoryProtectionModeDefault; + } + else + { + // + // Match the legacy OpenVMM defaults for a directly launched UEFI VM. + // Isolated guests retain the existing IGVM defaults above. + // + configFlags.Flags.SerialControllersEnabled = 1; + configFlags.Flags.HibernateEnabled = 1; + configFlags.Flags.ConsoleMode = ConfigLibConsoleModeCOM1; + configFlags.Flags.MemoryProtectionMode = ConfigLibMemoryProtectionModeDisabled; + configFlags.Flags.MtrrsInitializedAtLoad = 1; + configFlags.Flags.PciResourcesPreAssigned = 1; + } ConfigSetUefiConfigFlags(&configFlags); diff --git a/MsvmPkg/PlatformPei/PlatformPei.inf b/MsvmPkg/PlatformPei/PlatformPei.inf index 8ff5b775f..f4059af34 100644 --- a/MsvmPkg/PlatformPei/PlatformPei.inf +++ b/MsvmPkg/PlatformPei/PlatformPei.inf @@ -204,6 +204,7 @@ [Ppis] gEfiPeiMasterBootModePpiGuid + gMsvmParameterConfigPpiGuid ## CONSUMES [Ppis.AARCH64] gMsvmSecPlatformTypePpiGuid ## CONSUMES diff --git a/MsvmPkg/Sec/AArch64/SecEntry.S b/MsvmPkg/Sec/AArch64/SecEntry.S index 116fd2e51..216eeedb4 100644 --- a/MsvmPkg/Sec/AArch64/SecEntry.S +++ b/MsvmPkg/Sec/AArch64/SecEntry.S @@ -12,12 +12,13 @@ ASM_FUNC(_ModuleEntryPoint) // x0 - Firmware Volume Base Address // x1 - Stack Base Address // x2 - Platform Type (MSVM_SEC_PLATFORM_TYPE; 0 = HyperV, 1 = Generic) + // x3 - Optional parameter configuration header // bl SerialWriteBanner // print banner to COM2 mov sp, x1 // Establish stack - leave x1 as second arg to C code - bl SecStartupWithStack // jump to C code with 3 args (x0,x1,x2) + bl SecStartupWithStack // jump to C code with 4 args (x0,x1,x2,x3) ASM_FUNC(HvInvokeDebugger) diff --git a/MsvmPkg/Sec/AArch64/SecMain.c b/MsvmPkg/Sec/AArch64/SecMain.c index f46b680c6..06e03f6ac 100644 --- a/MsvmPkg/Sec/AArch64/SecMain.c +++ b/MsvmPkg/Sec/AArch64/SecMain.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,8 @@ MSVM_SEC_PLATFORM_TYPE_PPI mSecPlatformTypePpi = MsvmSecPlatformHyperV }; +MSVM_PARAMETER_CONFIG_PPI mParameterConfigPpi; + EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = { { @@ -51,10 +54,15 @@ EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = &mTemporaryRamSupportPpi }, { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + EFI_PEI_PPI_DESCRIPTOR_PPI, &gMsvmSecPlatformTypePpiGuid, &mSecPlatformTypePpi }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gMsvmParameterConfigPpiGuid, + &mParameterConfigPpi + }, }; @@ -121,7 +129,8 @@ EFIAPI SecStartupWithStack ( IN EFI_FIRMWARE_VOLUME_HEADER *BootFv, IN VOID *TopOfCurrentStack, - IN UINT64 PlatformType + IN UINT64 PlatformType, + IN OPTIONAL VOID *ParameterConfigHeader ) /*++ @@ -139,6 +148,9 @@ Routine Description: PlatformType - Platform type from the loader (MSVM_SEC_PLATFORM_TYPE). 0 = HyperV (default), 1 = Generic. + ParameterConfigHeader - Supplies the optional parameter configuration + header provided by the loader. + Return Value: None. @@ -152,11 +164,12 @@ Return Value: DEBUG((DEBUG_VERBOSE, sequence)); DEBUG((DEBUG_VERBOSE, - ">>> SecStartupWithStack @ %p (%p, %p, 0x%llx)\n", + ">>> SecStartupWithStack @ %p (%p, %p, 0x%llx, %p)\n", SecStartupWithStack, BootFv, TopOfCurrentStack, - PlatformType + PlatformType, + ParameterConfigHeader )); // @@ -171,6 +184,7 @@ Return Value: CpuDeadLoop(); } mSecPlatformTypePpi.PlatformType = (MSVM_SEC_PLATFORM_TYPE)PlatformType; + mParameterConfigPpi.ParameterConfigHeader = ParameterConfigHeader; // // Initialize floating point operating environment diff --git a/MsvmPkg/Sec/SecMain.inf b/MsvmPkg/Sec/SecMain.inf index 09bf2c9d6..63698476c 100644 --- a/MsvmPkg/Sec/SecMain.inf +++ b/MsvmPkg/Sec/SecMain.inf @@ -61,6 +61,7 @@ [Ppis] gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED + gMsvmParameterConfigPpiGuid # PPI ALWAYS_PRODUCED [Ppis.AARCH64] gMsvmSecPlatformTypePpiGuid # PPI ALWAYS_PRODUCED diff --git a/MsvmPkg/Sec/X64/SecMain.c b/MsvmPkg/Sec/X64/SecMain.c index 14a6c8f43..2d66a6911 100644 --- a/MsvmPkg/Sec/X64/SecMain.c +++ b/MsvmPkg/Sec/X64/SecMain.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include "SecP.h" @@ -48,13 +49,21 @@ EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = }; +MSVM_PARAMETER_CONFIG_PPI mParameterConfigPpi; + + EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = { { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + EFI_PEI_PPI_DESCRIPTOR_PPI, &gEfiTemporaryRamSupportPpiGuid, &mTemporaryRamSupportPpi }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gMsvmParameterConfigPpiGuid, + &mParameterConfigPpi + }, }; HV_HYPERVISOR_ISOLATION_CONFIGURATION mIsolationConfiguration; @@ -1079,6 +1088,9 @@ Routine Description: IsolationConfiguration - Supplies the isolation configuration of the current partition. + UefiIgvmConfigHeader - Supplies the optional IGVM parameter configuration + header provided by the loader. + Return Value: None. @@ -1124,6 +1136,7 @@ Return Value: // mIsolationConfiguration = *IsolationConfiguration; + mParameterConfigPpi.ParameterConfigHeader = UefiIgvmConfigHeader; Handler = 0; Vector = 0;