Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new Ovmf package to include and launch SVSM module in FV #1

Open
wants to merge 16 commits into
base: svsm
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion BaseTools/Source/C/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ all: makerootdir subdirs
LIBRARIES = Common
VFRAUTOGEN = VfrCompile/VfrLexer.h
APPLICATIONS = \
BrotliCompress \
VfrCompile \
EfiRom \
GenFfs \
Expand Down
3 changes: 0 additions & 3 deletions MdeModulePkg/MdeModulePkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
[Includes]
Include

[Includes.Common.Private]
Library/BrotliCustomDecompressLib/brotli/c/include

[LibraryClasses]
## @libraryclass Defines a set of methods to reset whole system.
ResetSystemLib|Include/Library/ResetSystemLib.h
Expand Down
1 change: 0 additions & 1 deletion MdeModulePkg/MdeModulePkg.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,6 @@
MdeModulePkg/Universal/EbcDxe/EbcDebuggerConfig.inf

[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliCustomDecompressLib.inf
MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
MdeModulePkg/Core/Dxe/DxeMain.inf {
Expand Down
28 changes: 28 additions & 0 deletions MdePkg/Include/Library/BaseLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -7587,6 +7587,34 @@ AsmVmgExit (
VOID
);

/**
Executes a VMGEXIT instruction (VMMCALL with a REP prefix) with arguments
and return code

Executes a VMGEXIT instruction placing the specified arguments in the
corresponding registers before invocation and returning the returned RAX
register value as a return code. This function is intended for use with an
SVSM. This function is only available on IA-32 and x64.

@param[in] Rcx Value to be placed in the RCX register
@param[in] Rdx Value to be placed in the RDX register
@param[in] R8 Value to be placed in the R8 register
@param[in] R9 Value to be placed in the R9 register
@param[in] Rax Value to be placed in the RAX register

@return Value of the RAX register on return

**/
UINT32
EFIAPI
AsmVmgExitSvsm (
IN UINT64 Rcx,
IN UINT64 Rdx,
IN UINT64 R8,
IN UINT64 R9,
IN UINT64 Rax
);

/**
Patch the immediate operand of an IA32 or X64 instruction such that the byte,
word, dword or qword operand is encoded at the end of the instruction's
Expand Down
17 changes: 17 additions & 0 deletions MdePkg/Include/Register/Amd/Fam17Msr.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,24 @@ typedef union {
UINT32 ErrorCode;
} SnpPageStateChangeResponse;

struct {
UINT64 Function : 12;
UINT64 Reserved1 : 20;
UINT64 Vmpl : 8;
UINT64 Reserved2 : 56;
} SnpVmplRequest;

struct {
UINT32 Function : 12;
UINT32 Reserved : 20;
UINT32 ErrorCode;
} SnpVmplResponse;

VOID *Ghcb;

UINT64 GhcbPhysicalAddress;

UINT64 Uint64;
} MSR_SEV_ES_GHCB_REGISTER;

#define GHCB_INFO_SEV_INFO 1
Expand All @@ -84,6 +99,8 @@ typedef union {
#define GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE 19
#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_REQUEST 20
#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_RESPONSE 21
#define GHCB_INFO_SNP_VMPL_REQUEST 22
#define GHCB_INFO_SNP_VMPL_RESPONSE 23
#define GHCB_HYPERVISOR_FEATURES_REQUEST 128
#define GHCB_HYPERVISOR_FEATURES_RESPONSE 129
#define GHCB_INFO_TERMINATE_REQUEST 256
Expand Down
17 changes: 14 additions & 3 deletions MdePkg/Include/Register/Amd/Ghcb.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#define SVM_EXIT_AP_JUMP_TABLE 0x80000005ULL
#define SVM_EXIT_SNP_PAGE_STATE_CHANGE 0x80000010ULL
#define SVM_EXIT_SNP_AP_CREATION 0x80000013ULL
#define SVM_EXIT_GET_APIC_IDS 0x80000017ULL
#define SVM_EXIT_HYPERVISOR_FEATURES 0x8000FFFDULL
#define SVM_EXIT_UNSUPPORTED 0x8000FFFFULL

Expand Down Expand Up @@ -170,6 +171,7 @@ typedef union {
#define GHCB_HV_FEATURES_SNP_AP_CREATE (GHCB_HV_FEATURES_SNP | BIT1)
#define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION (GHCB_HV_FEATURES_SNP_AP_CREATE | BIT2)
#define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION_TIMER (GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION | BIT3)
#define GHCB_HV_FEATURES_SNP_SVSM (GHCB_HV_FEATURES_SNP_AP_CREATE | BIT4)

//
// SNP Page State Change.
Expand All @@ -195,13 +197,22 @@ typedef struct {
UINT32 Reserved;
} SNP_PAGE_STATE_HEADER;

#define SNP_PAGE_STATE_MAX_ENTRY 253

typedef struct {
SNP_PAGE_STATE_HEADER Header;
SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
SNP_PAGE_STATE_ENTRY Entry[];
} SNP_PAGE_STATE_CHANGE_INFO;

#define SNP_PAGE_STATE_MAX_ENTRY \
((sizeof (((GHCB *)0)->SharedBuffer) - sizeof (SNP_PAGE_STATE_HEADER)) / sizeof (SNP_PAGE_STATE_ENTRY))

//
// Get APIC IDs
//
typedef struct {
UINT32 NumEntries;
UINT32 ApicIds[];
} GHCB_APIC_IDS;

//
// SEV-ES save area mapping structures used for SEV-SNP AP Creation.
// Only the fields required to be set to a non-zero value are defined.
Expand Down
2 changes: 2 additions & 0 deletions MdePkg/Library/BaseLib/BaseLib.inf
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@
Ia32/XGetBv.nasm
Ia32/XSetBv.nasm
Ia32/VmgExit.nasm
Ia32/VmgExitSvsm.nasm

Ia32/DivS64x64Remainder.c
Ia32/InternalSwitchStack.c | MSFT
Expand Down Expand Up @@ -328,6 +329,7 @@
X64/XGetBv.nasm
X64/XSetBv.nasm
X64/VmgExit.nasm
X64/VmgExitSvsm.nasm
ChkStkGcc.c | GCC

[Sources.EBC]
Expand Down
43 changes: 43 additions & 0 deletions MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
;------------------------------------------------------------------------------
;
; Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; VmgExitSvsm.Asm
;
; Abstract:
;
; AsmVmgExitSvsm function
;
; Notes:
;
;------------------------------------------------------------------------------

DEFAULT REL
SECTION .text

;------------------------------------------------------------------------------
; UINT32
; EFIAPI
; AsmVmgExitSvsm (
; UINT64 Rcx,
; UINT64 Rdx,
; UINT64 R8,
; UINT64 R9,
; UINT64 Rax
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmVmgExitSvsm)
ASM_PFX(AsmVmgExitSvsm):
;
; NASM doesn't support the vmmcall instruction in 32-bit mode and NASM versions
; before 2.12 cannot translate the 64-bit "rep vmmcall" instruction into elf32
; format. Given that VMGEXIT does not make sense on IA32, provide a stub
; implementation that is identical to CpuBreakpoint(). In practice,
; AsmVmgExitSvsm() should never be called on IA32.
;
int 3
ret

41 changes: 41 additions & 0 deletions MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
;------------------------------------------------------------------------------
;
; Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; VmgExitSvsm.Asm
;
; Abstract:
;
; AsmVmgExitSvsm function
;
; Notes:
;
;------------------------------------------------------------------------------

DEFAULT REL
SECTION .text

;------------------------------------------------------------------------------
; UINT32
; EFIAPI
; AsmVmgExitSvsm (
; UINT64 Rcx,
; UINT64 Rdx,
; UINT64 R8,
; UINT64 R9,
; UINT64 Rax
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmVmgExitSvsm)
ASM_PFX(AsmVmgExitSvsm):
;
; Calling convention puts Rcx/Rdx/R8/R9 arguments in the proper registers already.
; Only Rax needs to be loaded (from the stack).
;
mov rax, [rsp + 40] ; Get Rax parameter from the stack
rep vmmcall
ret

1 change: 1 addition & 0 deletions OvmfPkg/Include/Library/PlatformInitLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ typedef struct {

UINT64 PcdConfidentialComputingGuestAttr;
BOOLEAN SevEsIsEnabled;
BOOLEAN SevSnpIsEnabled;

UINT32 BootMode;
BOOLEAN S3Supported;
Expand Down
7 changes: 7 additions & 0 deletions OvmfPkg/Include/WorkArea.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
// detection in OvmfPkg/ResetVector/Ia32/AmdSev.c
//
UINT8 ReceivedVc;
UINT8 Reserved[7];

// Used by SEC to generate Page State Change requests. This should be
// sized less than an equal to the GHCB shared buffer area to allow a
// single call to the hypervisor.
//
UINT8 WorkBuffer[1024];
} SEC_SEV_ES_WORK_AREA;

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "SnpPageStateChange.h"
#include "VirtualMemory.h"

STATIC VOID *mPscBuffer = NULL;

/**
Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.

Expand Down Expand Up @@ -52,5 +54,16 @@ MemEncryptSevSnpPreValidateSystemRam (
}
}

InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
if (mPscBuffer == NULL) {
mPscBuffer = AllocateReservedPages (1);
ASSERT (mPscBuffer != NULL);
}

InternalSetPageState (
BaseAddress,
NumPages,
SevSnpPagePrivate,
TRUE,
mPscBuffer,
EFI_PAGE_SIZE);
}
25 changes: 23 additions & 2 deletions OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ STATIC BOOLEAN mAddressEncMaskChecked = FALSE;
STATIC UINT64 mAddressEncMask;
STATIC PAGE_TABLE_POOL *mPageTablePool = NULL;

STATIC VOID *mPscBuffer = NULL;

typedef enum {
SetCBit,
ClearCBit
Expand Down Expand Up @@ -762,7 +764,19 @@ SetMemoryEncDec (
// The InternalSetPageState() is used for setting the page state in the RMP table.
//
if (!Mmio && (Mode == ClearCBit) && MemEncryptSevSnpIsEnabled ()) {
InternalSetPageState (PhysicalAddress, EFI_SIZE_TO_PAGES (Length), SevSnpPageShared, FALSE);
if (mPscBuffer == NULL) {
mPscBuffer = AllocateReservedPages (1);
ASSERT (mPscBuffer != NULL);
}

InternalSetPageState (
PhysicalAddress,
EFI_SIZE_TO_PAGES (Length),
SevSnpPageShared,
FALSE,
mPscBuffer,
EFI_PAGE_SIZE
);
}

//
Expand Down Expand Up @@ -951,11 +965,18 @@ SetMemoryEncDec (
// The InternalSetPageState() is used for setting the page state in the RMP table.
//
if ((Mode == SetCBit) && MemEncryptSevSnpIsEnabled ()) {
if (mPscBuffer == NULL) {
mPscBuffer = AllocateReservedPages (1);
ASSERT (mPscBuffer != NULL);
}

InternalSetPageState (
OrigPhysicalAddress,
EFI_SIZE_TO_PAGES (OrigLength),
SevSnpPagePrivate,
FALSE
FALSE,
mPscBuffer,
EFI_PAGE_SIZE
);
}

Expand Down
21 changes: 19 additions & 2 deletions OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,15 @@ MemEncryptSevSnpPreValidateSystemRam (
{
PHYSICAL_ADDRESS EndAddress;
SNP_PRE_VALIDATED_RANGE OverlapRange;
SEC_SEV_ES_WORK_AREA *SevEsWorkArea;
EFI_STATUS Status;

if (!MemEncryptSevSnpIsEnabled ()) {
return;
}

SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);

EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);

//
Expand Down Expand Up @@ -113,7 +116,14 @@ MemEncryptSevSnpPreValidateSystemRam (
if (BaseAddress < OverlapRange.StartAddress) {
NumPages = EFI_SIZE_TO_PAGES (OverlapRange.StartAddress - BaseAddress);

InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
InternalSetPageState (
BaseAddress,
NumPages,
SevSnpPagePrivate,
TRUE,
SevEsWorkArea->WorkBuffer,
sizeof (SevEsWorkArea->WorkBuffer)
);
}

BaseAddress = OverlapRange.EndAddress;
Expand All @@ -122,7 +132,14 @@ MemEncryptSevSnpPreValidateSystemRam (

// Validate the remaining pages.
NumPages = EFI_SIZE_TO_PAGES (EndAddress - BaseAddress);
InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
InternalSetPageState (
BaseAddress,
NumPages,
SevSnpPagePrivate,
TRUE,
SevEsWorkArea->WorkBuffer,
sizeof (SevEsWorkArea->WorkBuffer)
);
BaseAddress = EndAddress;
}
}
Loading