OvmfPkg: Add TdxMailboxLib

RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429

In Tdx BSP may issues commands to APs for some task, for example, to
accept pages paralelly. BSP also need to wait until all the APs have
done the task. TdxMailboxLib wraps these common funtions for BSP.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
This commit is contained in:
Min Xu 2021-07-18 10:45:30 +08:00 committed by mergify[bot]
parent 352eabdcd5
commit 6a608255bb
5 changed files with 358 additions and 0 deletions

View File

@ -0,0 +1,76 @@
/** @file
Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef TDX_MAILBOX_LIB_H_
#define TDX_MAILBOX_LIB_H_
#include <Library/BaseLib.h>
#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
#include <Pi/PiPeiCis.h>
#include <Library/DebugLib.h>
#include <Protocol/DebugSupport.h>
/**
This function will be called by BSP to get the CPU number.
@retval CPU number
**/
UINT32
EFIAPI
GetCpusNum (
VOID
);
/**
Get the address of Td mailbox.
**/
volatile VOID *
EFIAPI
GetTdxMailBox (
VOID
);
/**
This function will be called by BSP to wakeup APs the are spinning on mailbox
in protected mode
@param[in] Command Command to send APs
@param[in] WakeupVector If used, address for APs to start executing
@param[in] WakeArgsX Args to pass to APs for excuting commands
**/
VOID
EFIAPI
MpSendWakeupCommand (
IN UINT16 Command,
IN UINT64 WakeupVector,
IN UINT64 WakeupArgs1,
IN UINT64 WakeupArgs2,
IN UINT64 WakeupArgs3,
IN UINT64 WakeupArgs4
);
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is started.
**/
VOID
EFIAPI
MpSerializeStart (
VOID
);
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is ended.
**/
VOID
EFIAPI
MpSerializeEnd (
VOID
);
#endif

View File

@ -0,0 +1,141 @@
/** @file
Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiCpuLib.h>
#include <Library/SynchronizationLib.h>
#include <Uefi/UefiBaseType.h>
#include <Library/TdxLib.h>
#include <IndustryStandard/IntelTdx.h>
#include <IndustryStandard/Tdx.h>
#include <Library/TdxMailboxLib.h>
volatile VOID *mMailBox = NULL;
UINT32 mNumOfCpus = 0;
/**
This function will be called by BSP to get the CPU number.
@retval CPU number
**/
UINT32
EFIAPI
GetCpusNum (
VOID
)
{
if (mNumOfCpus == 0) {
mNumOfCpus = TdVCpuNum ();
}
return mNumOfCpus;
}
/**
Get the address of Td mailbox.
**/
volatile VOID *
EFIAPI
GetTdxMailBox (
VOID
)
{
if (mMailBox == NULL) {
mMailBox = (VOID *)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase);
}
return mMailBox;
}
/**
This function will be called by BSP to wakeup APs the are spinning on mailbox
in protected mode
@param[in] Command Command to send APs
@param[in] WakeupVector If used, address for APs to start executing
@param[in] WakeArgsX Args to pass to APs for excuting commands
**/
VOID
EFIAPI
MpSendWakeupCommand (
IN UINT16 Command,
IN UINT64 WakeupVector,
IN UINT64 WakeupArgs1,
IN UINT64 WakeupArgs2,
IN UINT64 WakeupArgs3,
IN UINT64 WakeupArgs4
)
{
volatile MP_WAKEUP_MAILBOX *MailBox;
MailBox = (volatile MP_WAKEUP_MAILBOX *)GetTdxMailBox ();
MailBox->ApicId = MP_CPU_PROTECTED_MODE_MAILBOX_APICID_INVALID;
MailBox->WakeUpVector = 0;
MailBox->Command = MpProtectedModeWakeupCommandNoop;
MailBox->ApicId = MP_CPU_PROTECTED_MODE_MAILBOX_APICID_BROADCAST;
MailBox->WakeUpVector = WakeupVector;
MailBox->WakeUpArgs1 = WakeupArgs1;
MailBox->WakeUpArgs2 = WakeupArgs2;
MailBox->WakeUpArgs3 = WakeupArgs3;
MailBox->WakeUpArgs4 = WakeupArgs4;
AsmCpuid (0x01, NULL, NULL, NULL, NULL);
MailBox->Command = Command;
AsmCpuid (0x01, NULL, NULL, NULL, NULL);
return;
}
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is started.
**/
VOID
EFIAPI
MpSerializeStart (
VOID
)
{
volatile MP_WAKEUP_MAILBOX *MailBox;
UINT32 NumOfCpus;
NumOfCpus = GetCpusNum ();
MailBox = (volatile MP_WAKEUP_MAILBOX *)GetTdxMailBox ();
DEBUG ((DEBUG_VERBOSE, "Waiting for APs to arriving. NumOfCpus=%d, MailBox=%p\n", NumOfCpus, MailBox));
while (MailBox->NumCpusArriving != (NumOfCpus -1)) {
CpuPause ();
}
DEBUG ((DEBUG_VERBOSE, "Releasing APs\n"));
MailBox->NumCpusExiting = NumOfCpus;
InterlockedIncrement ((UINT32 *)&MailBox->NumCpusArriving);
}
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is ended.
**/
VOID
EFIAPI
MpSerializeEnd (
VOID
)
{
volatile MP_WAKEUP_MAILBOX *MailBox;
MailBox = (volatile MP_WAKEUP_MAILBOX *)GetTdxMailBox ();
DEBUG ((DEBUG_VERBOSE, "Waiting for APs to finish\n"));
while (MailBox->NumCpusExiting != 1 ) {
CpuPause ();
}
DEBUG ((DEBUG_VERBOSE, "Restarting APs\n"));
MailBox->Command = MpProtectedModeWakeupCommandNoop;
MailBox->NumCpusArriving = 0;
InterlockedDecrement ((UINT32 *)&MailBox->NumCpusExiting);
}

View File

@ -0,0 +1,52 @@
#/** @file
#
# TBD
#
# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = TdxMailboxLib
FILE_GUID = 2F81A9BA-748E-4519-BB11-A63A039D561E
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = TdxMailboxLib
#
# VALID_ARCHITECTURES = X64 IA32
#
[Sources.IA32]
TdxMailboxNull.c
[Sources.X64]
TdxMailbox.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
DebugLib
BaseMemoryLib
PcdLib
UefiCpuLib
DebugAgentLib
IoLib
SynchronizationLib
MemoryAllocationLib
[Guids]
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize

View File

@ -0,0 +1,85 @@
/** @file
Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/DebugLib.h>
#include <Library/TdxMailboxLib.h>
/**
This function will be called by BSP to get the CPU number.
@retval CPU number
**/
UINT32
EFIAPI
GetCpusNum (
VOID
)
{
ASSERT (FALSE);
return 0;
}
/**
Get the address of Td mailbox.
**/
volatile VOID *
EFIAPI
GetTdxMailBox (
VOID
)
{
ASSERT (FALSE);
return (volatile VOID *)NULL;
}
/**
This function will be called by BSP to wakeup APs the are spinning on mailbox
in protected mode
@param[in] Command Command to send APs
@param[in] WakeupVector If used, address for APs to start executing
@param[in] WakeArgsX Args to pass to APs for excuting commands
**/
VOID
EFIAPI
MpSendWakeupCommand (
IN UINT16 Command,
IN UINT64 WakeupVector,
IN UINT64 WakeupArgs1,
IN UINT64 WakeupArgs2,
IN UINT64 WakeupArgs3,
IN UINT64 WakeupArgs4
)
{
ASSERT (FALSE);
}
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is started.
**/
VOID
EFIAPI
MpSerializeStart (
VOID
)
{
ASSERT (FALSE);
}
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is ended.
**/
VOID
EFIAPI
MpSerializeEnd (
VOID
)
{
ASSERT (FALSE);
}

View File

@ -109,6 +109,10 @@
#
XenPlatformLib|Include/Library/XenPlatformLib.h
## @libraryclass TdxMailboxLib
#
TdxMailboxLib|Include/Library/TdxMailboxLib.h
[Guids]
gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}