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>
This commit is contained in:
Konstantin Kostiuk 2024-04-22 12:47:25 +02:00 committed by mergify[bot]
parent be92e09206
commit d0906f602b
5 changed files with 382 additions and 0 deletions

View File

@ -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
)
{
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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
);

View File

@ -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