From: Konstantin Kostiuk <kkost...@redhat.com>

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+tianoc...@kernel.org>
Cc: Jiewen Yao <jiewen....@intel.com>
Cc: Konstantin Kostiuk <kkost...@redhat.com>
Initial-patch-by: Konstantin Kostiuk <kkost...@redhat.com>
Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
---
 OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf |  50 ++++++++
 OvmfPkg/VirtHstiDxe/VirtHstiDxe.h   |  67 +++++++++++
 OvmfPkg/VirtHstiDxe/QemuPC.c        |  38 +++++++
 OvmfPkg/VirtHstiDxe/QemuQ35.c       |  58 ++++++++++
 OvmfPkg/VirtHstiDxe/VirtHstiDxe.c   | 169 ++++++++++++++++++++++++++++
 5 files changed, 382 insertions(+)
 create mode 100644 OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf
 create mode 100644 OvmfPkg/VirtHstiDxe/VirtHstiDxe.h
 create mode 100644 OvmfPkg/VirtHstiDxe/QemuPC.c
 create mode 100644 OvmfPkg/VirtHstiDxe/QemuQ35.c
 create mode 100644 OvmfPkg/VirtHstiDxe/VirtHstiDxe.c

diff --git a/OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf 
b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.inf
new file mode 100644
index 000000000000..8c63ff6a8953
--- /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
diff --git a/OvmfPkg/VirtHstiDxe/VirtHstiDxe.h 
b/OvmfPkg/VirtHstiDxe/VirtHstiDxe.h
new file mode 100644
index 000000000000..cf0d77fc3af9
--- /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/QemuPC.c b/OvmfPkg/VirtHstiDxe/QemuPC.c
new file mode 100644
index 000000000000..aa0459e8b6c6
--- /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 000000000000..5eab4aab29d1
--- /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 000000000000..74e5e6bd9d4f
--- /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;
+}
-- 
2.44.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118022): https://edk2.groups.io/g/devel/message/118022
Mute This Topic: https://groups.io/mt/105616657/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to