mirror of https://github.com/acidanthera/audk.git
OvmfPkg/SecMain: move SEV specific routines in AmdSev.c
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275 Move all the SEV specific function in AmdSev.c. No functional change intended. Cc: Michael Roth <michael.roth@amd.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Jiewen Yao <Jiewen.yao@intel.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
This commit is contained in:
parent
c82ab4d8c1
commit
2ddacfb6b8
|
@ -0,0 +1,164 @@
|
|||
/** @file
|
||||
File defines the Sec routines for the AMD SEV
|
||||
|
||||
Copyright (c) 2021, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemEncryptSevLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Register/Amd/Ghcb.h>
|
||||
#include <Register/Amd/Msr.h>
|
||||
|
||||
#include "AmdSev.h"
|
||||
|
||||
/**
|
||||
Handle an SEV-ES/GHCB protocol check failure.
|
||||
|
||||
Notify the hypervisor using the VMGEXIT instruction that the SEV-ES guest
|
||||
wishes to be terminated.
|
||||
|
||||
@param[in] ReasonCode Reason code to provide to the hypervisor for the
|
||||
termination request.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SevEsProtocolFailure (
|
||||
IN UINT8 ReasonCode
|
||||
)
|
||||
{
|
||||
MSR_SEV_ES_GHCB_REGISTER Msr;
|
||||
|
||||
//
|
||||
// Use the GHCB MSR Protocol to request termination by the hypervisor
|
||||
//
|
||||
Msr.GhcbPhysicalAddress = 0;
|
||||
Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;
|
||||
Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;
|
||||
Msr.GhcbTerminate.ReasonCode = ReasonCode;
|
||||
AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
|
||||
|
||||
AsmVmgExit ();
|
||||
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
/**
|
||||
Validate the SEV-ES/GHCB protocol level.
|
||||
|
||||
Verify that the level of SEV-ES/GHCB protocol supported by the hypervisor
|
||||
and the guest intersect. If they don't intersect, request termination.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SevEsProtocolCheck (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
MSR_SEV_ES_GHCB_REGISTER Msr;
|
||||
GHCB *Ghcb;
|
||||
|
||||
//
|
||||
// Use the GHCB MSR Protocol to obtain the GHCB SEV-ES Information for
|
||||
// protocol checking
|
||||
//
|
||||
Msr.GhcbPhysicalAddress = 0;
|
||||
Msr.GhcbInfo.Function = GHCB_INFO_SEV_INFO_GET;
|
||||
AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
|
||||
|
||||
AsmVmgExit ();
|
||||
|
||||
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
|
||||
|
||||
if (Msr.GhcbInfo.Function != GHCB_INFO_SEV_INFO) {
|
||||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
|
||||
}
|
||||
|
||||
if (Msr.GhcbProtocol.SevEsProtocolMin > Msr.GhcbProtocol.SevEsProtocolMax) {
|
||||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
|
||||
}
|
||||
|
||||
if ((Msr.GhcbProtocol.SevEsProtocolMin > GHCB_VERSION_MAX) ||
|
||||
(Msr.GhcbProtocol.SevEsProtocolMax < GHCB_VERSION_MIN))
|
||||
{
|
||||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
|
||||
}
|
||||
|
||||
//
|
||||
// SEV-ES protocol checking succeeded, set the initial GHCB address
|
||||
//
|
||||
Msr.GhcbPhysicalAddress = FixedPcdGet32 (PcdOvmfSecGhcbBase);
|
||||
AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
|
||||
|
||||
Ghcb = Msr.Ghcb;
|
||||
SetMem (Ghcb, sizeof (*Ghcb), 0);
|
||||
|
||||
//
|
||||
// Set the version to the maximum that can be supported
|
||||
//
|
||||
Ghcb->ProtocolVersion = MIN (Msr.GhcbProtocol.SevEsProtocolMax, GHCB_VERSION_MAX);
|
||||
Ghcb->GhcbUsage = GHCB_STANDARD_USAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
Determine if the SEV is active.
|
||||
|
||||
During the early booting, GuestType is set in the work area. Verify that it
|
||||
is an SEV guest.
|
||||
|
||||
@retval TRUE SEV is enabled
|
||||
@retval FALSE SEV is not enabled
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsSevGuest (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
OVMF_WORK_AREA *WorkArea;
|
||||
|
||||
//
|
||||
// Ensure that the size of the Confidential Computing work area header
|
||||
// is same as what is provided through a fixed PCD.
|
||||
//
|
||||
ASSERT (
|
||||
(UINTN)FixedPcdGet32 (PcdOvmfConfidentialComputingWorkAreaHeader) ==
|
||||
sizeof (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER)
|
||||
);
|
||||
|
||||
WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
|
||||
|
||||
return ((WorkArea != NULL) && (WorkArea->Header.GuestType == GUEST_TYPE_AMD_SEV));
|
||||
}
|
||||
|
||||
/**
|
||||
Determine if SEV-ES is active.
|
||||
|
||||
During early booting, SEV-ES support code will set a flag to indicate that
|
||||
SEV-ES is enabled. Return the value of this flag as an indicator that SEV-ES
|
||||
is enabled.
|
||||
|
||||
@retval TRUE SEV-ES is enabled
|
||||
@retval FALSE SEV-ES is not enabled
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
SevEsIsEnabled (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
SEC_SEV_ES_WORK_AREA *SevEsWorkArea;
|
||||
|
||||
if (!IsSevGuest ()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);
|
||||
|
||||
return (SevEsWorkArea->SevEsEnabled != 0);
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/** @file
|
||||
File defines the Sec routines for the AMD SEV
|
||||
|
||||
Copyright (c) 2021, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _AMD_SEV_SEC_INTERNAL_H__
|
||||
#define _AMD_SEV_SEC_INTERNAL_H__
|
||||
|
||||
/**
|
||||
Handle an SEV-ES/GHCB protocol check failure.
|
||||
|
||||
Notify the hypervisor using the VMGEXIT instruction that the SEV-ES guest
|
||||
wishes to be terminated.
|
||||
|
||||
@param[in] ReasonCode Reason code to provide to the hypervisor for the
|
||||
termination request.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SevEsProtocolFailure (
|
||||
IN UINT8 ReasonCode
|
||||
);
|
||||
|
||||
/**
|
||||
Validate the SEV-ES/GHCB protocol level.
|
||||
|
||||
Verify that the level of SEV-ES/GHCB protocol supported by the hypervisor
|
||||
and the guest intersect. If they don't intersect, request termination.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SevEsProtocolCheck (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Determine if the SEV is active.
|
||||
|
||||
During the early booting, GuestType is set in the work area. Verify that it
|
||||
is an SEV guest.
|
||||
|
||||
@retval TRUE SEV is enabled
|
||||
@retval FALSE SEV is not enabled
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsSevGuest (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Determine if SEV-ES is active.
|
||||
|
||||
During early booting, SEV-ES support code will set a flag to indicate that
|
||||
SEV-ES is enabled. Return the value of this flag as an indicator that SEV-ES
|
||||
is enabled.
|
||||
|
||||
@retval TRUE SEV-ES is enabled
|
||||
@retval FALSE SEV-ES is not enabled
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
SevEsIsEnabled (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
|
@ -26,12 +26,11 @@
|
|||
#include <Library/ExtractGuidedSectionLib.h>
|
||||
#include <Library/LocalApicLib.h>
|
||||
#include <Library/CpuExceptionHandlerLib.h>
|
||||
#include <Library/MemEncryptSevLib.h>
|
||||
#include <Register/Amd/Ghcb.h>
|
||||
#include <Register/Amd/Msr.h>
|
||||
|
||||
#include <Ppi/TemporaryRamSupport.h>
|
||||
|
||||
#include "AmdSev.h"
|
||||
|
||||
#define SEC_IDT_ENTRY_COUNT 34
|
||||
|
||||
typedef struct _SEC_IDT_TABLE {
|
||||
|
@ -726,157 +725,6 @@ FindAndReportEntryPoints (
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
Handle an SEV-ES/GHCB protocol check failure.
|
||||
|
||||
Notify the hypervisor using the VMGEXIT instruction that the SEV-ES guest
|
||||
wishes to be terminated.
|
||||
|
||||
@param[in] ReasonCode Reason code to provide to the hypervisor for the
|
||||
termination request.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SevEsProtocolFailure (
|
||||
IN UINT8 ReasonCode
|
||||
)
|
||||
{
|
||||
MSR_SEV_ES_GHCB_REGISTER Msr;
|
||||
|
||||
//
|
||||
// Use the GHCB MSR Protocol to request termination by the hypervisor
|
||||
//
|
||||
Msr.GhcbPhysicalAddress = 0;
|
||||
Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;
|
||||
Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;
|
||||
Msr.GhcbTerminate.ReasonCode = ReasonCode;
|
||||
AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
|
||||
|
||||
AsmVmgExit ();
|
||||
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
/**
|
||||
Validate the SEV-ES/GHCB protocol level.
|
||||
|
||||
Verify that the level of SEV-ES/GHCB protocol supported by the hypervisor
|
||||
and the guest intersect. If they don't intersect, request termination.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SevEsProtocolCheck (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
MSR_SEV_ES_GHCB_REGISTER Msr;
|
||||
GHCB *Ghcb;
|
||||
|
||||
//
|
||||
// Use the GHCB MSR Protocol to obtain the GHCB SEV-ES Information for
|
||||
// protocol checking
|
||||
//
|
||||
Msr.GhcbPhysicalAddress = 0;
|
||||
Msr.GhcbInfo.Function = GHCB_INFO_SEV_INFO_GET;
|
||||
AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
|
||||
|
||||
AsmVmgExit ();
|
||||
|
||||
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
|
||||
|
||||
if (Msr.GhcbInfo.Function != GHCB_INFO_SEV_INFO) {
|
||||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
|
||||
}
|
||||
|
||||
if (Msr.GhcbProtocol.SevEsProtocolMin > Msr.GhcbProtocol.SevEsProtocolMax) {
|
||||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
|
||||
}
|
||||
|
||||
if ((Msr.GhcbProtocol.SevEsProtocolMin > GHCB_VERSION_MAX) ||
|
||||
(Msr.GhcbProtocol.SevEsProtocolMax < GHCB_VERSION_MIN))
|
||||
{
|
||||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
|
||||
}
|
||||
|
||||
//
|
||||
// SEV-ES protocol checking succeeded, set the initial GHCB address
|
||||
//
|
||||
Msr.GhcbPhysicalAddress = FixedPcdGet32 (PcdOvmfSecGhcbBase);
|
||||
AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
|
||||
|
||||
Ghcb = Msr.Ghcb;
|
||||
SetMem (Ghcb, sizeof (*Ghcb), 0);
|
||||
|
||||
//
|
||||
// Set the version to the maximum that can be supported
|
||||
//
|
||||
Ghcb->ProtocolVersion = MIN (Msr.GhcbProtocol.SevEsProtocolMax, GHCB_VERSION_MAX);
|
||||
Ghcb->GhcbUsage = GHCB_STANDARD_USAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
Determine if the SEV is active.
|
||||
|
||||
During the early booting, GuestType is set in the work area. Verify that it
|
||||
is an SEV guest.
|
||||
|
||||
@retval TRUE SEV is enabled
|
||||
@retval FALSE SEV is not enabled
|
||||
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
IsSevGuest (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
OVMF_WORK_AREA *WorkArea;
|
||||
|
||||
//
|
||||
// Ensure that the size of the Confidential Computing work area header
|
||||
// is same as what is provided through a fixed PCD.
|
||||
//
|
||||
ASSERT (
|
||||
(UINTN)FixedPcdGet32 (PcdOvmfConfidentialComputingWorkAreaHeader) ==
|
||||
sizeof (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER)
|
||||
);
|
||||
|
||||
WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
|
||||
|
||||
return ((WorkArea != NULL) && (WorkArea->Header.GuestType == GUEST_TYPE_AMD_SEV));
|
||||
}
|
||||
|
||||
/**
|
||||
Determine if SEV-ES is active.
|
||||
|
||||
During early booting, SEV-ES support code will set a flag to indicate that
|
||||
SEV-ES is enabled. Return the value of this flag as an indicator that SEV-ES
|
||||
is enabled.
|
||||
|
||||
@retval TRUE SEV-ES is enabled
|
||||
@retval FALSE SEV-ES is not enabled
|
||||
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
SevEsIsEnabled (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
SEC_SEV_ES_WORK_AREA *SevEsWorkArea;
|
||||
|
||||
if (!IsSevGuest ()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);
|
||||
|
||||
return (SevEsWorkArea->SevEsEnabled != 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SecCoreStartupWithStack (
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
[Sources]
|
||||
SecMain.c
|
||||
AmdSev.c
|
||||
AmdSev.h
|
||||
|
||||
[Sources.IA32]
|
||||
Ia32/SecEntry.nasm
|
||||
|
|
Loading…
Reference in New Issue