UefiCpuPkg/MpInitLib: Use AmdSvsmSnpVmsaRmpAdjust() to set/clear VMSA

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The RMPADJUST instruction is used to change the VMSA attribute of a page,
but the VMSA attribute can only be changed when running at VMPL0. To
prepare for running at a less priviledged VMPL, use the AmdSvsmLib library
API to perform the RMPADJUST. The AmdSvsmLib library will perform the
proper operation on behalf of the caller.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
Tom Lendacky 2024-03-08 07:32:09 -08:00 committed by mergify[bot]
parent 6ced1e91ef
commit ee89b59430
5 changed files with 9 additions and 81 deletions

View File

@ -62,6 +62,7 @@
UefiBootServicesTableLib
[LibraryClasses.IA32, LibraryClasses.X64]
AmdSvsmLib
CcExitLib
LocalApicLib
MicrocodeLib

View File

@ -49,26 +49,6 @@ SevSnpCreateAP (
ASSERT (FALSE);
}
/**
Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
@param[in] PageAddress
@param[in] VmsaPage
@return RMPADJUST return value
**/
UINT32
SevSnpRmpAdjust (
IN EFI_PHYSICAL_ADDRESS PageAddress,
IN BOOLEAN VmsaPage
)
{
//
// RMPADJUST is not supported in 32-bit mode
//
return RETURN_UNSUPPORTED;
}
/**
Determine if the SEV-SNP AP Create protocol should be used.

View File

@ -883,20 +883,6 @@ FillExchangeInfoDataSevEs (
IN volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo
);
/**
Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
@param[in] PageAddress
@param[in] VmsaPage
@return RMPADJUST return value
**/
UINT32
SevSnpRmpAdjust (
IN EFI_PHYSICAL_ADDRESS PageAddress,
IN BOOLEAN VmsaPage
);
/**
Create an SEV-SNP AP save area (VMSA) for use in running the vCPU.

View File

@ -59,6 +59,7 @@
SynchronizationLib
[LibraryClasses.IA32, LibraryClasses.X64]
AmdSvsmLib
CcExitLib
LocalApicLib
MicrocodeLib

View File

@ -10,6 +10,7 @@
#include "MpLib.h"
#include <Library/CcExitLib.h>
#include <Library/AmdSvsmLib.h>
#include <Register/Amd/Fam17Msr.h>
#include <Register/Amd/Ghcb.h>
@ -38,20 +39,15 @@ SevSnpPerformApAction (
BOOLEAN InterruptState;
UINT64 ExitInfo1;
UINT64 ExitInfo2;
UINT32 RmpAdjustStatus;
UINT64 VmgExitStatus;
EFI_STATUS VmsaStatus;
if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
//
// To turn the page into a recognized VMSA page, issue RMPADJUST:
// Target VMPL but numerically higher than current VMPL
// Target PermissionMask is not used
// Turn the page into a recognized VMSA page.
//
RmpAdjustStatus = SevSnpRmpAdjust (
(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
TRUE
);
if (RmpAdjustStatus != 0) {
VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
if (EFI_ERROR (VmsaStatus)) {
DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA creation\n"));
ASSERT (FALSE);
@ -94,11 +90,8 @@ SevSnpPerformApAction (
// Make the current VMSA not runnable and accessible to be
// reprogrammed.
//
RmpAdjustStatus = SevSnpRmpAdjust (
(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
FALSE
);
if (RmpAdjustStatus != 0) {
VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
if (EFI_ERROR (VmsaStatus)) {
DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA reset\n"));
ASSERT (FALSE);
@ -328,39 +321,6 @@ SevSnpCreateAP (
}
}
/**
Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
@param[in] PageAddress
@param[in] VmsaPage
@return RMPADJUST return value
**/
UINT32
SevSnpRmpAdjust (
IN EFI_PHYSICAL_ADDRESS PageAddress,
IN BOOLEAN VmsaPage
)
{
UINT64 Rdx;
//
// The RMPADJUST instruction is used to set or clear the VMSA bit for a
// page. The VMSA change is only made when running at VMPL0 and is ignored
// otherwise. If too low a target VMPL is specified, the instruction can
// succeed without changing the VMSA bit when not running at VMPL0. Using a
// target VMPL level of 1, RMPADJUST will return a FAIL_PERMISSION error if
// not running at VMPL0, thus ensuring that the VMSA bit is set appropriately
// when no error is returned.
//
Rdx = 1;
if (VmsaPage) {
Rdx |= RMPADJUST_VMSA_PAGE_BIT;
}
return AsmRmpAdjust ((UINT64)PageAddress, 0, Rdx);
}
/**
Determine if the SEV-SNP AP Create protocol should be used.