mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-29 16:44:10 +02:00
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:
parent
6ced1e91ef
commit
ee89b59430
@ -62,6 +62,7 @@
|
|||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
|
||||||
[LibraryClasses.IA32, LibraryClasses.X64]
|
[LibraryClasses.IA32, LibraryClasses.X64]
|
||||||
|
AmdSvsmLib
|
||||||
CcExitLib
|
CcExitLib
|
||||||
LocalApicLib
|
LocalApicLib
|
||||||
MicrocodeLib
|
MicrocodeLib
|
||||||
|
@ -49,26 +49,6 @@ SevSnpCreateAP (
|
|||||||
ASSERT (FALSE);
|
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.
|
Determine if the SEV-SNP AP Create protocol should be used.
|
||||||
|
|
||||||
|
@ -883,20 +883,6 @@ FillExchangeInfoDataSevEs (
|
|||||||
IN volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo
|
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.
|
Create an SEV-SNP AP save area (VMSA) for use in running the vCPU.
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
SynchronizationLib
|
SynchronizationLib
|
||||||
|
|
||||||
[LibraryClasses.IA32, LibraryClasses.X64]
|
[LibraryClasses.IA32, LibraryClasses.X64]
|
||||||
|
AmdSvsmLib
|
||||||
CcExitLib
|
CcExitLib
|
||||||
LocalApicLib
|
LocalApicLib
|
||||||
MicrocodeLib
|
MicrocodeLib
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "MpLib.h"
|
#include "MpLib.h"
|
||||||
#include <Library/CcExitLib.h>
|
#include <Library/CcExitLib.h>
|
||||||
|
#include <Library/AmdSvsmLib.h>
|
||||||
#include <Register/Amd/Fam17Msr.h>
|
#include <Register/Amd/Fam17Msr.h>
|
||||||
#include <Register/Amd/Ghcb.h>
|
#include <Register/Amd/Ghcb.h>
|
||||||
|
|
||||||
@ -38,20 +39,15 @@ SevSnpPerformApAction (
|
|||||||
BOOLEAN InterruptState;
|
BOOLEAN InterruptState;
|
||||||
UINT64 ExitInfo1;
|
UINT64 ExitInfo1;
|
||||||
UINT64 ExitInfo2;
|
UINT64 ExitInfo2;
|
||||||
UINT32 RmpAdjustStatus;
|
|
||||||
UINT64 VmgExitStatus;
|
UINT64 VmgExitStatus;
|
||||||
|
EFI_STATUS VmsaStatus;
|
||||||
|
|
||||||
if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
|
if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
|
||||||
//
|
//
|
||||||
// To turn the page into a recognized VMSA page, issue RMPADJUST:
|
// Turn the page into a recognized VMSA page.
|
||||||
// Target VMPL but numerically higher than current VMPL
|
|
||||||
// Target PermissionMask is not used
|
|
||||||
//
|
//
|
||||||
RmpAdjustStatus = SevSnpRmpAdjust (
|
VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
|
||||||
(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
|
if (EFI_ERROR (VmsaStatus)) {
|
||||||
TRUE
|
|
||||||
);
|
|
||||||
if (RmpAdjustStatus != 0) {
|
|
||||||
DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA creation\n"));
|
DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA creation\n"));
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
|
|
||||||
@ -94,11 +90,8 @@ SevSnpPerformApAction (
|
|||||||
// Make the current VMSA not runnable and accessible to be
|
// Make the current VMSA not runnable and accessible to be
|
||||||
// reprogrammed.
|
// reprogrammed.
|
||||||
//
|
//
|
||||||
RmpAdjustStatus = SevSnpRmpAdjust (
|
VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
|
||||||
(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
|
if (EFI_ERROR (VmsaStatus)) {
|
||||||
FALSE
|
|
||||||
);
|
|
||||||
if (RmpAdjustStatus != 0) {
|
|
||||||
DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA reset\n"));
|
DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA reset\n"));
|
||||||
ASSERT (FALSE);
|
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.
|
Determine if the SEV-SNP AP Create protocol should be used.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user