summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Kostiuk <kkostiuk@redhat.com>2024-04-22 12:47:25 +0200
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-04-22 13:05:21 +0000
commitd0906f602ba3939c1d5d46c6cead17b7b4232161 (patch)
tree8629c3c61ac9ceff02a68e646a0815de0f3ee437
parentbe92e09206c2e4bb388e7c9127f048689841dd01 (diff)
downloadedk2-d0906f602ba3939c1d5d46c6cead17b7b4232161.tar.gz
edk2-d0906f602ba3939c1d5d46c6cead17b7b4232161.tar.bz2
edk2-d0906f602ba3939c1d5d46c6cead17b7b4232161.zip
OvmfPkg: Add VirtHstiDxe driver
The driver supports qemu machine types 'pc' and 'q35'. This patch adds some helper functions to manage the bitmasks. The implemented features depend on both OVMF build configuration and qemu VM configuration. For q35 a single security feature is supported and checked: In SMM-enabled builds the driver will verify smram is properly locked. That test should never fail. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Konstantin Kostiuk <kkostiuk@redhat.com> Initial-patch-by: Konstantin Kostiuk <kkostiuk@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
-rw-r--r--OvmfPkg/VirtHstiDxe/QemuPC.c38
-rw-r--r--OvmfPkg/VirtHstiDxe/QemuQ35.c58
-rw-r--r--OvmfPkg/VirtHstiDxe/VirtHstiDxe.c169
-rw-r--r--OvmfPkg/VirtHstiDxe/VirtHstiDxe.h67
-rw-r--r--OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf50
5 files changed, 382 insertions, 0 deletions
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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HstiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+
+#include <IndustryStandard/Hsti.h>
+#include <IndustryStandard/Q35MchIch9.h>
+
+#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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HstiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+
+#include <IndustryStandard/Hsti.h>
+#include <IndustryStandard/Q35MchIch9.h>
+
+#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.<BR>
+Copyright (c) 2024, Red Hat. Inc
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/HstiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PlatformInitLib.h>
+
+#include <IndustryStandard/Hsti.h>
+#include <IndustryStandard/I440FxPiix4.h>
+#include <IndustryStandard/Q35MchIch9.h>
+
+#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.<BR>
+# Copyright (c) Microsoft Corporation.<BR>
+# 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