summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2024-03-08 07:32:37 -0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-04-17 20:04:41 +0000
commit28fecae8a39268e1e21ec1845f3f1e0176db1aa7 (patch)
tree17f2fe68261729f6121580073c7ad3b7e6b859c9
parent18fdffe825683df40d7a4a9eba11b8630bcef050 (diff)
downloadedk2-28fecae8a39268e1e21ec1845f3f1e0176db1aa7.tar.gz
edk2-28fecae8a39268e1e21ec1845f3f1e0176db1aa7.tar.bz2
edk2-28fecae8a39268e1e21ec1845f3f1e0176db1aa7.zip
OvmfPkg/AmdSvsmLib: Add support for the SVSM create/delete vCPU calls
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 The RMPADJUST instruction is used to alter the VMSA attribute of a page, but the VMSA attribute can only be changed when running at VMPL0. When an SVSM is present, use the SVSM_CORE_CREATE_VCPU and SVSM_CORE_DELTE_VCPU calls to add or remove the VMSA attribute on a page instead of issuing the RMPADJUST instruction directly. Implement the AmdSvsmSnpVmsaRmpAdjust() API to perform the proper operation to update the VMSA attribute. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-rw-r--r--OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
index fb3fda70e9..6c79ee7d91 100644
--- a/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
+++ b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
@@ -378,6 +378,57 @@ AmdSvsmSnpPvalidate (
}
/**
+ Perform an RMPADJUST operation to alter the VMSA setting of a page.
+
+ Add or remove the VMSA attribute for a page.
+
+ @param[in] Vmsa Pointer to an SEV-ES save area page
+ @param[in] ApicId APIC ID associated with the VMSA
+ @param[in] SetVmsa Boolean indicator as to whether to set or
+ or clear the VMSA setting for the page
+
+ @retval EFI_SUCCESS RMPADJUST operation successful
+ @retval EFI_UNSUPPORTED Operation is not supported
+ @retval EFI_INVALID_PARAMETER RMPADJUST operation failed, an invalid
+ parameter was supplied
+
+**/
+STATIC
+EFI_STATUS
+SvsmVmsaRmpAdjust (
+ IN SEV_ES_SAVE_AREA *Vmsa,
+ IN UINT32 ApicId,
+ IN BOOLEAN SetVmsa
+ )
+{
+ SVSM_CALL_DATA SvsmCallData;
+ SVSM_FUNCTION Function;
+ UINTN Ret;
+
+ SvsmCallData.Caa = (SVSM_CAA *)AmdSvsmSnpGetCaa ();
+
+ Function.Id.Protocol = 0;
+
+ if (SetVmsa) {
+ Function.Id.CallId = 2;
+
+ SvsmCallData.RaxIn = Function.Uint64;
+ SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+ SvsmCallData.RdxIn = (UINT64)(UINTN)Vmsa + SIZE_4KB;
+ SvsmCallData.R8In = ApicId;
+ } else {
+ Function.Id.CallId = 3;
+
+ SvsmCallData.RaxIn = Function.Uint64;
+ SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+ }
+
+ Ret = SvsmMsrProtocol (&SvsmCallData);
+
+ return (Ret == 0) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
+}
+
+/**
Perform a native RMPADJUST operation to alter the VMSA setting of a page.
Add or remove the VMSA attribute for a page.
@@ -444,5 +495,6 @@ AmdSvsmSnpVmsaRmpAdjust (
IN BOOLEAN SetVmsa
)
{
- return BaseVmsaRmpAdjust (Vmsa, SetVmsa);
+ return AmdSvsmIsSvsmPresent () ? SvsmVmsaRmpAdjust (Vmsa, ApicId, SetVmsa)
+ : BaseVmsaRmpAdjust (Vmsa, SetVmsa);
}