From 28fecae8a39268e1e21ec1845f3f1e0176db1aa7 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Fri, 8 Mar 2024 07:32:37 -0800 Subject: 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 Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Laszlo Ersek Acked-by: Gerd Hoffmann Signed-off-by: Tom Lendacky --- OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c | 54 ++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) 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 @@ -377,6 +377,57 @@ AmdSvsmSnpPvalidate ( AmdSvsmIsSvsmPresent () ? SvsmPvalidate (Info) : BasePvalidate (Info); } +/** + 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. @@ -444,5 +495,6 @@ AmdSvsmSnpVmsaRmpAdjust ( IN BOOLEAN SetVmsa ) { - return BaseVmsaRmpAdjust (Vmsa, SetVmsa); + return AmdSvsmIsSvsmPresent () ? SvsmVmsaRmpAdjust (Vmsa, ApicId, SetVmsa) + : BaseVmsaRmpAdjust (Vmsa, SetVmsa); } -- cgit v1.2.3