diff --git a/OvmfPkg/VirtHstiDxe/QemuPC.c b/OvmfPkg/VirtHstiDxe/QemuPC.c new file mode 100644 index 0000000000..aa0459e8b6 --- /dev/null +++ b/OvmfPkg/VirtHstiDxe/QemuPC.c @@ -0,0 +1,38 @@ +/** @file + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "VirtHstiDxe.h" + +STATIC VIRT_ADAPTER_INFO_PLATFORM_SECURITY mHstiPC = { + PLATFORM_SECURITY_VERSION_VNEXTCS, + PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, + { L"OVMF (Qemu PC)" }, + VIRT_HSTI_SECURITY_FEATURE_SIZE, +}; + +VIRT_ADAPTER_INFO_PLATFORM_SECURITY * +VirtHstiQemuPCInit ( + VOID + ) +{ + return &mHstiPC; +} + +VOID +VirtHstiQemuPCVerify ( + VOID + ) +{ +} diff --git a/OvmfPkg/VirtHstiDxe/QemuQ35.c b/OvmfPkg/VirtHstiDxe/QemuQ35.c new file mode 100644 index 0000000000..5eab4aab29 --- /dev/null +++ b/OvmfPkg/VirtHstiDxe/QemuQ35.c @@ -0,0 +1,58 @@ +/** @file + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "VirtHstiDxe.h" + +STATIC VIRT_ADAPTER_INFO_PLATFORM_SECURITY mHstiQ35 = { + PLATFORM_SECURITY_VERSION_VNEXTCS, + PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, + { L"OVMF (Qemu Q35)" }, + VIRT_HSTI_SECURITY_FEATURE_SIZE, +}; + +VIRT_ADAPTER_INFO_PLATFORM_SECURITY * +VirtHstiQemuQ35Init ( + VOID + ) +{ + if (FeaturePcdGet (PcdSmmSmramRequire)) { + VirtHstiSetSupported (&mHstiQ35, 0, VIRT_HSTI_BYTE0_SMM_SMRAM_LOCK); + } + + return &mHstiQ35; +} + +VOID +VirtHstiQemuQ35Verify ( + VOID + ) +{ + if (VirtHstiIsSupported (&mHstiQ35, 0, VIRT_HSTI_BYTE0_SMM_SMRAM_LOCK)) { + CHAR16 *ErrorMsg = NULL; + UINT8 SmramVal; + UINT8 EsmramcVal; + + SmramVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_SMRAM)); + EsmramcVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC)); + + if (!(EsmramcVal & MCH_ESMRAMC_T_EN)) { + ErrorMsg = L"q35 smram access is open"; + } else if (!(SmramVal & MCH_SMRAM_D_LCK)) { + ErrorMsg = L"q35 smram config is not locked"; + } + + VirtHstiTestResult (ErrorMsg, 0, VIRT_HSTI_BYTE0_SMM_SMRAM_LOCK); + } +} diff --git a/OvmfPkg/VirtHstiDxe/VirtHstiDxe.c b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.c new file mode 100644 index 0000000000..74e5e6bd9d --- /dev/null +++ b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.c @@ -0,0 +1,169 @@ +/** @file + This file contains DXE driver for publishing empty HSTI table + +Copyright (c) 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2024, Red Hat. Inc + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "VirtHstiDxe.h" + +VOID +VirtHstiSetSupported ( + VIRT_ADAPTER_INFO_PLATFORM_SECURITY *VirtHsti, + IN UINT32 ByteIndex, + IN UINT8 BitMask + ) +{ + ASSERT (ByteIndex < VIRT_HSTI_SECURITY_FEATURE_SIZE); + VirtHsti->SecurityFeaturesRequired[ByteIndex] |= BitMask; + VirtHsti->SecurityFeaturesImplemented[ByteIndex] |= BitMask; +} + +BOOLEAN +VirtHstiIsSupported ( + VIRT_ADAPTER_INFO_PLATFORM_SECURITY *VirtHsti, + IN UINT32 ByteIndex, + IN UINT8 BitMask + ) +{ + ASSERT (ByteIndex < VIRT_HSTI_SECURITY_FEATURE_SIZE); + return VirtHsti->SecurityFeaturesImplemented[ByteIndex] & BitMask; +} + +VOID +VirtHstiTestResult ( + CHAR16 *ErrorMsg, + IN UINT32 ByteIndex, + IN UINT8 BitMask + ) +{ + EFI_STATUS Status; + + ASSERT (ByteIndex < VIRT_HSTI_SECURITY_FEATURE_SIZE); + + if (ErrorMsg) { + DEBUG ((DEBUG_ERROR, "VirtHsti: Test failed: %s\n", ErrorMsg)); + Status = HstiLibAppendErrorString ( + PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, + NULL, + ErrorMsg + ); + ASSERT_EFI_ERROR (Status); + } else { + Status = HstiLibSetFeaturesVerified ( + PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, + NULL, + ByteIndex, + BitMask + ); + ASSERT_EFI_ERROR (Status); + } +} + +STATIC +UINT16 +VirtHstiGetHostBridgeDevId ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_HOB_PLATFORM_INFO *PlatformInfo; + + GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid); + ASSERT (GuidHob); + PlatformInfo = (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob); + return PlatformInfo->HostBridgeDevId; +} + +STATIC +VOID +EFIAPI +VirtHstiOnReadyToBoot ( + EFI_EVENT Event, + VOID *Context + ) +{ + switch (VirtHstiGetHostBridgeDevId ()) { + case INTEL_82441_DEVICE_ID: + VirtHstiQemuPCVerify (); + break; + case INTEL_Q35_MCH_DEVICE_ID: + VirtHstiQemuQ35Verify (); + break; + default: + ASSERT (FALSE); + } + + if (Event != NULL) { + gBS->CloseEvent (Event); + } +} + +/** + The driver's entry point. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. +**/ +EFI_STATUS +EFIAPI +VirtHstiDxeEntrypoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + VIRT_ADAPTER_INFO_PLATFORM_SECURITY *VirtHsti; + UINT16 DevId; + EFI_STATUS Status; + EFI_EVENT Event; + + DevId = VirtHstiGetHostBridgeDevId (); + switch (DevId) { + case INTEL_82441_DEVICE_ID: + VirtHsti = VirtHstiQemuPCInit (); + break; + case INTEL_Q35_MCH_DEVICE_ID: + VirtHsti = VirtHstiQemuQ35Init (); + break; + default: + DEBUG ((DEBUG_INFO, "%a: unknown platform (0x%x)\n", __func__, DevId)); + return EFI_UNSUPPORTED; + } + + Status = HstiLibSetTable (VirtHsti, sizeof (*VirtHsti)); + if (EFI_ERROR (Status)) { + if (Status != EFI_ALREADY_STARTED) { + ASSERT_EFI_ERROR (Status); + } + } + + EfiCreateEventReadyToBootEx ( + TPL_NOTIFY, + VirtHstiOnReadyToBoot, + NULL, + &Event + ); + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/VirtHstiDxe/VirtHstiDxe.h b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.h new file mode 100644 index 0000000000..cf0d77fc3a --- /dev/null +++ b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.h @@ -0,0 +1,67 @@ +/** @file + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#define VIRT_HSTI_SECURITY_FEATURE_SIZE 2 + +#define VIRT_HSTI_BYTE0_SMM_SMRAM_LOCK BIT0 + +typedef struct { + // ADAPTER_INFO_PLATFORM_SECURITY + UINT32 Version; + UINT32 Role; + CHAR16 ImplementationID[256]; + UINT32 SecurityFeaturesSize; + // bitfields + UINT8 SecurityFeaturesRequired[VIRT_HSTI_SECURITY_FEATURE_SIZE]; + UINT8 SecurityFeaturesImplemented[VIRT_HSTI_SECURITY_FEATURE_SIZE]; + UINT8 SecurityFeaturesVerified[VIRT_HSTI_SECURITY_FEATURE_SIZE]; + CHAR16 ErrorString[1]; +} VIRT_ADAPTER_INFO_PLATFORM_SECURITY; + +VOID +VirtHstiSetSupported ( + VIRT_ADAPTER_INFO_PLATFORM_SECURITY *VirtHsti, + IN UINT32 ByteIndex, + IN UINT8 BitMask + ); + +BOOLEAN +VirtHstiIsSupported ( + VIRT_ADAPTER_INFO_PLATFORM_SECURITY *VirtHsti, + IN UINT32 ByteIndex, + IN UINT8 BitMask + ); + +VOID +VirtHstiTestResult ( + CHAR16 *ErrorMsg, + IN UINT32 ByteIndex, + IN UINT8 BitMask + ); + +/* QemuQ35.c */ + +VIRT_ADAPTER_INFO_PLATFORM_SECURITY * +VirtHstiQemuQ35Init ( + VOID + ); + +VOID +VirtHstiQemuQ35Verify ( + VOID + ); + +/* QemuPC.c */ + +VIRT_ADAPTER_INFO_PLATFORM_SECURITY * +VirtHstiQemuPCInit ( + VOID + ); + +VOID +VirtHstiQemuPCVerify ( + VOID + ); diff --git a/OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf new file mode 100644 index 0000000000..8c63ff6a89 --- /dev/null +++ b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf @@ -0,0 +1,50 @@ +## @file +# Component description file for Virt Hsti Driver +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation.
+# Copyright (c) 2024, Red Hat. Inc +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VirtHstiDxe + FILE_GUID = 60740CF3-D428-4500-80E6-04A5798241ED + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = VirtHstiDxeEntrypoint + +[Sources] + VirtHstiDxe.h + VirtHstiDxe.c + QemuPC.c + QemuQ35.c + +[Packages] + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiLib + BaseLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + HobLib + HstiLib + PcdLib + PciLib + UefiBootServicesTableLib + +[Guids] + gUefiOvmfPkgPlatformInfoGuid + +[FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire + +[Depex] + TRUE