From df70f2976f672a16539e36f1d07c3595081aa2ed Mon Sep 17 00:00:00 2001 From: Zhao Hang Date: Thu, 14 Dec 2023 17:29:35 +0800 Subject: [PATCH 1/2] update to edk2-20220126gitbb1bba3d77-6.el8.src.rpm Signed-off-by: Zhao Hang --- ...g-Add-StandardSignatureIsHygonGenuin.patch | 140 ---- ...g-LocalApicLib-Exclude-second-SendIp.patch | 83 -- ...dd-CSV-secure-call-library-on-Hygon-.patch | 672 ---------------- ...cg-Add-CsvLib-for-TpmMmioSevDecryptP.patch | 27 - ...esetVector-Support-CSV-in-ResetVecto.patch | 222 ------ ...latformPei-Initialize-CSV-VM-s-memor.patch | 202 ----- ...aseMemcryptSevLib-update-page-status.patch | 75 -- 0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch | 616 --------------- ...mfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch | 724 ------------------ ...eserve-a-CPUID-table-page-for-CSV-gu.patch | 137 ---- ...ncryptLib-Detect-SEV-live-migration-.patch | 325 -------- ...ncryptLib-Hypercall-API-for-page-enc.patch | 298 ------- ...ncryptLib-Invoke-page-encryption-sta.patch | 91 --- ...ib-Encryption-state-change-hypercall.patch | 46 -- ...Pei-Mark-SEC-GHCB-page-as-unencrypte.patch | 43 -- ...e-Add-support-for-SEV-live-migration.patch | 185 ----- ...aseMemcryptSevLib-Correct-the-calcul.patch | 35 - ...aseMemEncryptLib-Return-SUCCESS-if-n.patch | 36 - dist | 1 - ...mageVerificationLib-Check-result-of-.patch | 109 +++ ...nitLib-fix-apic-mode-for-cpu-hotplug.patch | 49 ++ edk2.spec | 39 +- 22 files changed, 173 insertions(+), 3982 deletions(-) delete mode 100644 0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch delete mode 100644 0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch delete mode 100644 0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch delete mode 100644 0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch delete mode 100644 0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch delete mode 100644 0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch delete mode 100644 0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch delete mode 100644 0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch delete mode 100644 0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch delete mode 100644 0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch delete mode 100644 0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch delete mode 100644 0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch delete mode 100644 0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch delete mode 100644 0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch delete mode 100644 0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch delete mode 100644 0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch delete mode 100644 0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch delete mode 100644 0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch delete mode 100644 dist create mode 100644 edk2-SecurityPkg-DxeImageVerificationLib-Check-result-of-.patch create mode 100644 edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch diff --git a/0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch b/0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch deleted file mode 100644 index 5abf6fc..0000000 --- a/0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch +++ /dev/null @@ -1,140 +0,0 @@ -From c5906a1813f0a370e76d0e4910f1959edd552af4 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Thu, 21 Apr 2022 16:03:08 +0800 -Subject: [PATCH 29/46] anolis: UefiCpuPkg: Add - StandardSignatureIsHygonGenuine() in BaseUefiCpuLib - -This function allows IA32/X64 code to determine if it is running on an -Hygon brand processor. - -Signed-off-by: Xin Jiang -Change-Id: I72594196f0ce6003fce43856120e3ca4609b8bb2 ---- - UefiCpuPkg/Include/Library/UefiCpuLib.h | 13 +++++ - UefiCpuPkg/Include/Register/Hygon/Cpuid.h | 47 +++++++++++++++++++ - .../Library/BaseUefiCpuLib/BaseUefiCpuLib.c | 24 ++++++++++ - 3 files changed, 84 insertions(+) - create mode 100644 UefiCpuPkg/Include/Register/Hygon/Cpuid.h - -diff --git a/UefiCpuPkg/Include/Library/UefiCpuLib.h b/UefiCpuPkg/Include/Library/UefiCpuLib.h -index 092c1d2..c64fe26 100644 ---- a/UefiCpuPkg/Include/Library/UefiCpuLib.h -+++ b/UefiCpuPkg/Include/Library/UefiCpuLib.h -@@ -43,6 +43,19 @@ StandardSignatureIsAuthenticAMD ( - VOID - ); - -+/** -+ Determine if the standard CPU signature is "HygonGenuine". -+ -+ @retval TRUE The CPU signature matches. -+ @retval FALSE The CPU signature does not match. -+ -+**/ -+BOOLEAN -+EFIAPI -+StandardSignatureIsHygonGenuine ( -+ VOID -+ ); -+ - /** - Return the 32bit CPU family and model value. - -diff --git a/UefiCpuPkg/Include/Register/Hygon/Cpuid.h b/UefiCpuPkg/Include/Register/Hygon/Cpuid.h -new file mode 100644 -index 0000000..e8a2c76 ---- /dev/null -+++ b/UefiCpuPkg/Include/Register/Hygon/Cpuid.h -@@ -0,0 +1,47 @@ -+/** @file -+ CPUID leaf definitions. -+ -+ Provides defines for CPUID leaf indexes. Data structures are provided for -+ registers returned by a CPUID leaf that contain one or more bit fields. -+ If a register returned is a single 32-bit value, then a data structure is -+ not provided for that register. -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+**/ -+ -+#ifndef __HYGON_CPUID_H__ -+#define __HYGON_CPUID_H__ -+ -+/** -+CPUID Signature Information -+ -+@param EAX CPUID_SIGNATURE (0x00) -+ -+@retval EAX Returns the highest value the CPUID instruction recognizes for -+ returning basic processor information. The value is returned is -+ processor specific. -+@retval EBX First 4 characters of a vendor identification string. -+@retval ECX Last 4 characters of a vendor identification string. -+@retval EDX Middle 4 characters of a vendor identification string. -+ -+**/ -+ -+/// -+/// @{ CPUID signature values returned by HYGON processors -+/// -+#define CPUID_SIGNATURE_AUTHENTIC_HYGON_EBX SIGNATURE_32 ('H', 'y', 'g', 'o') -+#define CPUID_SIGNATURE_AUTHENTIC_HYGON_EDX SIGNATURE_32 ('n', 'G', 'e', 'n') -+#define CPUID_SIGNATURE_AUTHENTIC_HYGON_ECX SIGNATURE_32 ('u', 'i', 'n', 'e') -+/// -+/// @} -+/// -+ -+#endif -diff --git a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c -index 5089161..700d633 100644 ---- a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c -+++ b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c -@@ -11,6 +11,7 @@ - - #include - #include -+#include - - #include - #include -@@ -38,6 +39,29 @@ StandardSignatureIsAuthenticAMD ( - RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); - } - -+/** -+ Determine if the standard CPU signature is "HygonGenuine". -+ -+ @retval TRUE The CPU signature matches. -+ @retval FALSE The CPU signature does not match. -+ -+**/ -+BOOLEAN -+EFIAPI -+StandardSignatureIsHygonGenuine ( -+ VOID -+ ) -+{ -+ UINT32 RegEbx; -+ UINT32 RegEcx; -+ UINT32 RegEdx; -+ -+ AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); -+ return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_HYGON_EBX && -+ RegEcx == CPUID_SIGNATURE_AUTHENTIC_HYGON_ECX && -+ RegEdx == CPUID_SIGNATURE_AUTHENTIC_HYGON_EDX); -+} -+ - /** - Return the 32bit CPU family and model value. - --- -2.17.1 - diff --git a/0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch b/0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch deleted file mode 100644 index ccb5fd6..0000000 --- a/0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 573b40aeb685842d7fd4e7985cd197fc79fe8cff Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Sun, 10 Apr 2022 21:50:15 -0400 -Subject: [PATCH 30/46] anolis: UefiCpuPkg/LocalApicLib: Exclude second SendIpi - sequence on HYGON hardware - -On HYGON processors the second SendIpi in the SendInitSipiSipi and -SendInitSipiSipiAllExcludingSelf routines is not required, and may cause -undesired side-effects during MP initialization. - -This patch leverages the StandardSignatureIsHygonGenuine check to exclude -the second SendIpi and its associated MicroSecondDelay (200). - -Signed-off-by: Xin Jiang -Change-Id: I59defdaf10fb36981c5dfb7e3b69e8bf5aaf46cc ---- - UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 5 +++-- - UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 5 +++-- - 2 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c -index 52bd90d..fac41bd 100644 ---- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c -+++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - // - // Library internal functions -@@ -527,7 +528,7 @@ SendInitSipiSipi ( - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; - IcrLow.Bits.Level = 1; - SendIpi (IcrLow.Uint32, ApicId); -- if (!StandardSignatureIsAuthenticAMD ()) { -+ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, ApicId); - } -@@ -563,7 +564,7 @@ SendInitSipiSipiAllExcludingSelf ( - IcrLow.Bits.Level = 1; - IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; - SendIpi (IcrLow.Uint32, 0); -- if (!StandardSignatureIsAuthenticAMD ()) { -+ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, 0); - } -diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c -index cdcbca0..a8fea8b 100644 ---- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c -+++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - // - // Library internal functions -@@ -622,7 +623,7 @@ SendInitSipiSipi ( - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; - IcrLow.Bits.Level = 1; - SendIpi (IcrLow.Uint32, ApicId); -- if (!StandardSignatureIsAuthenticAMD ()) { -+ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, ApicId); - } -@@ -658,7 +659,7 @@ SendInitSipiSipiAllExcludingSelf ( - IcrLow.Bits.Level = 1; - IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; - SendIpi (IcrLow.Uint32, 0); -- if (!StandardSignatureIsAuthenticAMD ()) { -+ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, 0); - } --- -2.17.1 - diff --git a/0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch b/0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch deleted file mode 100644 index 72ebc6f..0000000 --- a/0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch +++ /dev/null @@ -1,672 +0,0 @@ -From 98354124fe8c4cd7e6aed0fb6feabbe3a4de1836 Mon Sep 17 00:00:00 2001 -From: Liu Zixing -Date: Fri, 25 Feb 2022 14:25:11 +0800 -Subject: [PATCH 31/46] anolis: OvmfPkg: Add CSV secure call library on Hygon - CPU - -CSV is the secure virtualization feature on Hygon CPU. -A CSV virtual machine is composed of private memory and shared memory. -The private memory or shared memory can be converted to the other by -the following steps: - - guest clear/set the c-bit in the guest page table - - guest send a update command to Hygon Secure Processor - -While the update command has to be forwarded by the VMM to the Secure -Processor, to prevent the malicious VMM from attacking the update -command, a reliable command channel is required between the CSV VM -and the Hygon Secure Processor. - -The secure call library is created to build a secure command channel -between the VM and the Secure Processor by #NPF on a special private -page which the VMM is not able to access. -This special page is called secure call page. -The VM puts command in the secure call page and triggers a #NPF -to reach the Secure Processor. -The Secure Processor then puts the response in the same page and -finishes the #NPF. -The information is protected in the secure call page all the way. - -CsvLib is added to implement the functionality and new PCDs are added -accordingly. - -Signed-off-by: Xin Jiang -Change-Id: If62f0cb37faf003a79ed8a117bf582f8b90cdf89 ---- - OvmfPkg/Include/Library/CsvLib.h | 84 +++++++ - OvmfPkg/Library/CsvLib/CsvLib.c | 82 ++++++ - OvmfPkg/Library/CsvLib/CsvLib.inf | 55 ++++ - .../Library/CsvLib/Ia32/UpdateMemoryCsvLib.c | 53 ++++ - .../Library/CsvLib/X64/UpdateMemoryCsvLib.c | 238 ++++++++++++++++++ - OvmfPkg/OvmfPkg.dec | 8 + - OvmfPkg/OvmfPkgIa32.dsc | 1 + - OvmfPkg/OvmfPkgIa32X64.dsc | 1 + - OvmfPkg/OvmfPkgX64.dsc | 1 + - OvmfPkg/OvmfPkgX64.fdf | 3 + - 10 files changed, 526 insertions(+) - create mode 100644 OvmfPkg/Include/Library/CsvLib.h - create mode 100644 OvmfPkg/Library/CsvLib/CsvLib.c - create mode 100644 OvmfPkg/Library/CsvLib/CsvLib.inf - create mode 100644 OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c - create mode 100644 OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c - -diff --git a/OvmfPkg/Include/Library/CsvLib.h b/OvmfPkg/Include/Library/CsvLib.h -new file mode 100644 -index 0000000..0cb6218 ---- /dev/null -+++ b/OvmfPkg/Include/Library/CsvLib.h -@@ -0,0 +1,84 @@ -+/** @file -+ -+ CSV base library helper function -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#ifndef _CSV_LIB_H_ -+#define _CSV_LIB_H_ -+ -+#include -+ -+typedef struct { -+ IN UINT64 BaseAddress; -+ IN UINT64 Size; -+} CSV_SECURE_CMD_SHARED_REGION; -+ -+typedef enum { -+ CsvSecureCmdEnc = 1, -+ CsvSecureCmdDec, -+ CsvSecureCmdReset, -+ CsvSecureCmdUpdateSecureCallTable, -+ CsvSecureCmdMapLowerMemory, //secure memory range below 4G -+ CsvSecureCmdMapUpperMemory //secure memory range above 4G -+} CSV_SECURE_COMMAND_TYPE; -+ -+/** -+ Returns a boolean to indicate whether CSV is enabled -+ -+ @retval TRUE CSV is enabled -+ @retval FALSE CSV is not enabled -+**/ -+BOOLEAN -+EFIAPI -+CsvIsEnabled ( -+ VOID -+ ); -+ -+#define CSV_SHARED_MEMORY_SIGNATURE SIGNATURE_32('C','S','V',' ') -+ -+typedef struct { -+ UINTN Signature; -+ LIST_ENTRY Link; -+ UINT64 Start; -+ UINT64 Length; -+} CsvSharedMemoryEntry; -+ -+VOID -+EFIAPI -+CsvUpdateMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages, -+ IN BOOLEAN Dec -+); -+ -+VOID -+EFIAPI -+CsvResetMemory ( -+ VOID -+); -+ -+VOID -+EFIAPI -+CsvUpdateMapLowerMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+); -+ -+VOID -+EFIAPI -+CsvUpdateMapUpperMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+); -+#endif // _CSV_LIB_H_ -diff --git a/OvmfPkg/Library/CsvLib/CsvLib.c b/OvmfPkg/Library/CsvLib/CsvLib.c -new file mode 100644 -index 0000000..7e7f8ef ---- /dev/null -+++ b/OvmfPkg/Library/CsvLib/CsvLib.c -@@ -0,0 +1,82 @@ -+/** @file -+ -+ CSV library helper function -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+STATIC BOOLEAN mCsvStatus = FALSE; -+STATIC BOOLEAN mCsvStatusChecked = FALSE; -+ -+/** -+ -+ Reads and sets the status of CSV features -+ **/ -+STATIC -+VOID -+EFIAPI -+InternalCsvStatus ( -+ VOID -+ ) -+{ -+ UINT32 RegEax; -+ -+ // -+ // Check if memory encryption leaf exist -+ // -+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); -+ if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) { -+ if(StandardSignatureIsHygonGenuine ()){ -+ // -+ // Check MSR_0xC0010131 Bit 30 (Csv Enabled) -+ // -+ MSR_SEV_STATUS_REGISTER Msr; -+ Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS); -+ if (Msr.Uint32 & (1 << 30)) { -+ mCsvStatus = TRUE; -+ DEBUG ((EFI_D_INFO, "CSV is enabled\n")); -+ } -+ } -+ } -+ mCsvStatusChecked = TRUE; -+} -+ -+/** -+ Returns a boolean to indicate whether CSV is enabled -+ -+ @retval TRUE CSV is enabled -+ @retval FALSE CSV is not enabled -+**/ -+BOOLEAN -+EFIAPI -+CsvIsEnabled ( -+ VOID -+ ) -+{ -+ if (!mCsvStatusChecked) { -+ InternalCsvStatus (); -+ } -+ -+ return MemEncryptSevEsIsEnabled () && mCsvStatus; -+} -diff --git a/OvmfPkg/Library/CsvLib/CsvLib.inf b/OvmfPkg/Library/CsvLib/CsvLib.inf -new file mode 100644 -index 0000000..25859c3 ---- /dev/null -+++ b/OvmfPkg/Library/CsvLib/CsvLib.inf -@@ -0,0 +1,55 @@ -+## @file -+# Library provides the helper functions for CSV guest -+# -+# Copyright (c) 2022 HYGON. All rights reserved.
-+# -+# This program and the accompanying materials -+# are licensed and made available under the terms and conditions of the BSD -+# License which accompanies this distribution. The full text of the license -+# may be found at http://opensource.org/licenses/bsd-license.php -+# -+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED. -+# -+# -+## -+ -+[Defines] -+ INF_VERSION = 1.25 -+ BASE_NAME = CsvLib -+ FILE_GUID = 9460ef3a-b9c3-11e9-8324-7371ac35e1e3 -+ MODULE_TYPE = BASE -+ VERSION_STRING = 1.0 -+ LIBRARY_CLASS = CsvLib|PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER -+ -+# -+# The following information is for reference only and not required by the build -+# tools. -+# -+# VALID_ARCHITECTURES = Ia32 X64 -+# -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ OvmfPkg/OvmfPkg.dec -+ UefiCpuPkg/UefiCpuPkg.dec -+ -+[Sources] -+ CsvLib.c -+ -+[Sources.X64] -+ X64/UpdateMemoryCsvLib.c -+[Sources.IA32] -+ Ia32/UpdateMemoryCsvLib.c -+ -+[LibraryClasses] -+ BaseLib -+ CpuLib -+ DebugLib -+ MemEncryptSevLib -+ UefiCpuLib -+ -+[Pcd] -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize -diff --git a/OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c b/OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c -new file mode 100644 -index 0000000..15d3aa8 ---- /dev/null -+++ b/OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c -@@ -0,0 +1,53 @@ -+/** @file -+ -+ CSV library helper function -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include -+ -+VOID -+EFIAPI -+CsvUpdateMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages, -+ IN BOOLEAN Dec -+) -+{ -+} -+ -+VOID -+EFIAPI -+CsvResetMemory ( -+ VOID -+) -+{ -+} -+ -+VOID -+EFIAPI -+CsvUpdateMapLowerMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+) -+{ -+} -+ -+VOID -+EFIAPI -+CsvUpdateMapUpperMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+) -+{ -+} -diff --git a/OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c b/OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c -new file mode 100644 -index 0000000..13d06d7 ---- /dev/null -+++ b/OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c -@@ -0,0 +1,238 @@ -+/** @file -+ -+ CSV library helper function -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define SECURE_CALL_ENTRY_MAX (254) -+ -+ -+typedef struct { -+ union { -+ UINT8 Guid[16]; -+ UINT64 Guid64[2]; -+ }; -+ UINT32 CmdType; -+ UINT32 Nums; -+ UINT64 Unused; -+ struct { -+ UINT64 BaseAddress; -+ UINT64 Size; -+ } Entry[SECURE_CALL_ENTRY_MAX]; -+} CSV_SECURE_CALL_CMD; -+ -+STATIC UINT32 SecureCallPageIdx = 0; -+ -+STATIC UINTN MemorySizeBelow4G = (UINTN)-1; -+STATIC UINTN MemorySizeAbove4G = (UINTN)-1; -+ -+STATIC -+VOID -+EFIAPI -+CsvSecureCall( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages, -+ IN CSV_SECURE_COMMAND_TYPE CmdType -+) -+{ -+ volatile CSV_SECURE_COMMAND_TYPE CmdAck = 0; -+ -+ CSV_SECURE_CALL_CMD *SecureCallPageRead; -+ CSV_SECURE_CALL_CMD *SecureCallPageWrite; -+ UINTN SecureCallBase = 0; -+ -+ if (CsvIsEnabled () == FALSE) { -+ return ; -+ } -+ -+ SecureCallBase = FixedPcdGet32 (PcdCsvDefaultSecureCallBase); -+ -+ SecureCallPageRead = -+ (CSV_SECURE_CALL_CMD *)(UINT64) -+ (EFI_PAGE_SIZE * SecureCallPageIdx + SecureCallBase); -+ -+ SecureCallPageWrite = -+ (CSV_SECURE_CALL_CMD *) -+ (UINT64)(EFI_PAGE_SIZE * (1 - SecureCallPageIdx) + SecureCallBase); -+ -+ while(1) { -+ SecureCallPageWrite->CmdType = (UINT32)CmdType; -+ SecureCallPageWrite->Nums = 1; -+ SecureCallPageWrite->Entry[0].BaseAddress = (UINT64)BaseAddress; -+ SecureCallPageWrite->Entry[0].Size = (UINT64)NumPages << EFI_PAGE_SHIFT; -+ -+ MemoryFence (); -+ -+ CmdAck = SecureCallPageRead->CmdType; -+ if (CmdAck != CmdType) -+ break; -+ } -+ SecureCallPageIdx = 1 - SecureCallPageIdx; -+} -+ -+STATIC -+UINT8 -+CmosRead8 ( -+ IN UINTN Index -+ ) -+{ -+ IoWrite8 (0x70, (UINT8) Index); -+ return IoRead8 (0x71); -+} -+ -+ -+STATIC -+VOID -+EFIAPI -+CsvGetSystemMemory( -+ VOID -+ ) -+{ -+ UINT8 Cmos0x34; -+ UINT8 Cmos0x35; -+ UINT32 Size; -+ UINTN CmosIndex; -+ -+ // -+ // system memory below 4GB MB -+ // -+ -+ Cmos0x34 = (UINT8) CmosRead8 (0x34); -+ Cmos0x35 = (UINT8) CmosRead8 (0x35); -+ -+ MemorySizeBelow4G = -+ (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); -+ -+ // -+ // system memory above 4GB MB -+ // -+ -+ Size = 0; -+ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) { -+ Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex); -+ } -+ -+ MemorySizeAbove4G = LShiftU64 (Size, 16); -+} -+ -+STATIC -+BOOLEAN -+EFIAPI -+CsvIsDRAM( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+ ) -+{ -+ UINTN Size = EFI_PAGES_TO_SIZE (NumPages); -+ PHYSICAL_ADDRESS EndAddress; -+ -+ Size = EFI_PAGES_TO_SIZE (NumPages); -+ EndAddress = BaseAddress + Size; -+ -+ if (MemorySizeBelow4G == (UINTN)-1 || -+ MemorySizeAbove4G == (UINTN)-1) { -+ CsvGetSystemMemory (); -+ } -+ -+ if (BaseAddress < MemorySizeBelow4G) { -+ return TRUE; -+ } else if (BaseAddress >= BASE_4GB && -+ BaseAddress < (BASE_4GB + MemorySizeAbove4G)) { -+ return TRUE; -+ } else if (EndAddress > BASE_4GB && -+ EndAddress <= (BASE_4GB + MemorySizeAbove4G)) { -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+STATIC -+VOID -+EFIAPI -+CsvUpdateEncryptMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+) -+{ -+ PHYSICAL_ADDRESS PageAddress = BaseAddress & ~EFI_PAGE_MASK; -+ -+ if (CsvIsDRAM (PageAddress, NumPages)) { -+ CsvSecureCall (PageAddress, NumPages, CsvSecureCmdEnc); -+ } -+} -+ -+STATIC -+VOID -+EFIAPI -+CsvUpdateDecryptMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+) -+{ -+ PHYSICAL_ADDRESS PageAddress = BaseAddress & ~EFI_PAGE_MASK; -+ -+ if (CsvIsDRAM (PageAddress, NumPages)) { -+ CsvSecureCall (PageAddress, NumPages, CsvSecureCmdDec); -+ } -+} -+ -+VOID -+EFIAPI -+CsvUpdateMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages, -+ IN BOOLEAN Dec -+ ) -+{ -+ if (Dec) -+ CsvUpdateDecryptMemory (BaseAddress, NumPages); -+ else -+ CsvUpdateEncryptMemory (BaseAddress, NumPages); -+} -+ -+VOID -+EFIAPI -+CsvResetMemory ( -+ VOID -+) -+{ -+ CsvSecureCall (0, 0, CsvSecureCmdReset); -+} -+ -+VOID -+EFIAPI -+CsvUpdateMapLowerMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+) -+{ -+ CsvSecureCall (BaseAddress, NumPages, CsvSecureCmdMapLowerMemory); -+} -+ -+VOID -+EFIAPI -+CsvUpdateMapUpperMemory ( -+ IN PHYSICAL_ADDRESS BaseAddress, -+ IN UINTN NumPages -+) -+{ -+ CsvSecureCall (BaseAddress, NumPages, CsvSecureCmdMapUpperMemory); -+} -diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec -index 340d83f..6f4afb8 100644 ---- a/OvmfPkg/OvmfPkg.dec -+++ b/OvmfPkg/OvmfPkg.dec -@@ -109,6 +109,10 @@ - # - XenPlatformLib|Include/Library/XenPlatformLib.h - -+ ## @libraryclass CSV Library -+ # -+ CsvLib|Include/Library/CsvLib.h -+ - [Guids] - gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}} - gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}} -@@ -350,6 +354,10 @@ - gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset|0|UINT32|0x56 - gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize|0|UINT32|0x57 - -+ ## the base address of the secure call pages used by CSV. -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|0|UINT32|0x58 -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize|0|UINT32|0x59 -+ - [PcdsDynamic, PcdsDynamicEx] - gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 -diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc -index a066693..d623ed3 100644 ---- a/OvmfPkg/OvmfPkgIa32.dsc -+++ b/OvmfPkg/OvmfPkgIa32.dsc -@@ -176,6 +176,7 @@ - VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf - LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf - MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -+ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf - !if $(SMM_REQUIRE) == FALSE - LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf - !endif -diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc -index 5efeb42..9e4dcce 100644 ---- a/OvmfPkg/OvmfPkgIa32X64.dsc -+++ b/OvmfPkg/OvmfPkgIa32X64.dsc -@@ -180,6 +180,7 @@ - VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf - LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf - MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -+ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf - !if $(SMM_REQUIRE) == FALSE - LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf - !endif -diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc -index 10fb7d7..e62b533 100644 ---- a/OvmfPkg/OvmfPkgX64.dsc -+++ b/OvmfPkg/OvmfPkgX64.dsc -@@ -180,6 +180,7 @@ - VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf - LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf - MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -+ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf - !if $(SMM_REQUIRE) == FALSE - LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf - !endif -diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf -index 85b4b23..a3634dd 100644 ---- a/OvmfPkg/OvmfPkgX64.fdf -+++ b/OvmfPkg/OvmfPkgX64.fdf -@@ -88,6 +88,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm - 0x00C000|0x001000 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize - -+0x00D000|0x002000 -+gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize -+ - 0x010000|0x010000 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize - --- -2.17.1 - diff --git a/0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch b/0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch deleted file mode 100644 index c00ebcd..0000000 --- a/0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 40c0763c88a6a895d4fc58158f3c0f9a17798049 Mon Sep 17 00:00:00 2001 -From: Xin Jiang -Date: Fri, 18 Aug 2023 16:48:03 +0800 -Subject: [PATCH 32/46] anolis: OvmfPkg/Tcg: Add CsvLib for - TpmMmioSevDecryptPei - -Signed-off-by: Xin Jiang -Change-Id: I4a11065abcc679538aabcb7602185f785df60496 ---- - OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf -index 51ad6d0..402e4c9 100644 ---- a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf -+++ b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf -@@ -29,6 +29,7 @@ - PcdLib - PeimEntryPoint - PeiServicesLib -+ CsvLib - - [Ppis] - gOvmfTpmMmioAccessiblePpiGuid ## PRODUCES --- -2.17.1 - diff --git a/0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch b/0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch deleted file mode 100644 index b30e7df..0000000 --- a/0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch +++ /dev/null @@ -1,222 +0,0 @@ -From b08f9e4b2d4aa1f1baec02ecda6ae481ed58c64f Mon Sep 17 00:00:00 2001 -From: Liu Zixing -Date: Fri, 25 Feb 2022 15:55:44 +0800 -Subject: [PATCH 33/46] anolis: OvmfPkg/ResetVector: Support CSV in ResetVector - phase - -- A GUID is written along with the first secure call page address, -by which the Secure Processor can locate the first secure call page -address. - -- Check whether the VM is a CSV VM when setting the first page table - -- CSV VM will update first shared GHCB page address to Secure Processor -by secure call page - -Signed-off-by: Xin Jiang -Change-Id: I422bff00dc88d6738d1dae2d9f6c5c49ec601e95 ---- - OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 15 +++ - OvmfPkg/ResetVector/Ia32/AmdSev.asm | 10 ++ - OvmfPkg/ResetVector/Ia32/CsvInit.asm | 107 +++++++++++++++++++ - OvmfPkg/ResetVector/ResetVector.inf | 2 + - OvmfPkg/ResetVector/ResetVector.nasmb | 4 + - 5 files changed, 138 insertions(+) - create mode 100644 OvmfPkg/ResetVector/Ia32/CsvInit.asm - -diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm -index dee2e3f..c32b608 100644 ---- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm -+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm -@@ -48,6 +48,21 @@ TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0 - guidedStructureStart: - - %ifdef ARCH_X64 -+; -+; CSV secure call table -+; -+; Provide secure call pages when boot up for CSV guest. -+; -+; GUID : 9a5d926f-2fa5-ceba-ab21-6b275d5556a5 -+; -+csvSecureCallBase: -+ DD CSV_DEFAULT_SECURE_CALL_SIZE -+ DD CSV_DEFAULT_SECURE_CALL_BASE -+ DW csvSecureCallEnd - csvSecureCallBase -+ DB 0x6F, 0x92, 0x5D, 0x9A, 0xA5, 0x2F, 0xBA, 0xCE -+ DB 0xAB, 0x21, 0x6B, 0x27, 0x5D, 0x55, 0x56, 0xA5 -+csvSecureCallEnd: -+ - ; - ; TDX Metadata offset block - ; -diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm -index 250ac8d..8ce5eb0 100644 ---- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm -+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm -@@ -177,6 +177,16 @@ pageTableEntries4kLoop: - mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12 - mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0 - -+ OneTimeCall CheckCsvFeature -+ test eax, eax -+ jz clearGhcbStart -+ -+ OneTimeCall CsvInit -+ mov eax, 1 -+ test ecx, ecx -+ jz SevEsUnexpectedRespTerminate -+ -+clearGhcbStart: - mov ecx, GHCB_SIZE / 4 - xor eax, eax - clearGhcbMemoryLoop: -diff --git a/OvmfPkg/ResetVector/Ia32/CsvInit.asm b/OvmfPkg/ResetVector/Ia32/CsvInit.asm -new file mode 100644 -index 0000000..0744a35 ---- /dev/null -+++ b/OvmfPkg/ResetVector/Ia32/CsvInit.asm -@@ -0,0 +1,107 @@ -+;------------------------------------------------------------------------------ -+; @file -+; Provide the functions to check whether CSV is enabled. -+; -+; Copyright (c) 2022, HYGON. All rights reserved.
-+; SPDX-License-Identifier: BSD-2-Clause-Patent -+; -+;------------------------------------------------------------------------------ -+ -+BITS 32 -+ -+; If Secure Command returns ok then ECX will be non-zero. -+; If Secure Command returns error then ECX will be zero. -+CsvInit: -+ mov esp, SEV_ES_VC_TOP_OF_STACK -+ push esi -+ push edi -+ -+ ; copy SECURE_CALL_GUID to CSV_DEFAULT_SECURE_CALL_BASE + 4096 -+ cld -+ mov esi, ADDR_OF(SECURE_CALL_GUID) -+ mov edi, CSV_DEFAULT_SECURE_CALL_BASE -+ add edi, 4096 -+ mov ecx, 4 -+ rep movsd -+ -+ ; secure call begin -+ mov esi, CSV_DEFAULT_SECURE_CALL_BASE -+ ; write secure cmd to page B -+ ; 16 bytes of page A/B is GUID, just ignore -+ mov [esi + 4096 + 16], DWORD 2 ; dec command -+ mov [esi + 4096 + 20], DWORD 1 ; 1 entry -+ ; 8 bytes is unused -+ mov [esi + 4096 + 32], DWORD GHCB_BASE; lower address -+ mov [esi + 4096 + 36], DWORD 0 ; upper address -+ mov [esi + 4096 + 40], DWORD 4096 ; lower 32 bit of page size -+ mov [esi + 4096 + 44], DWORD 0 ; upper 32 bit of page size -+ mfence -+ ; read from page A -+ mov ecx, [esi + 16] -+ ; check if the response comes -+ cmp ecx, 2 -+ jne SecureCommandDone -+ ; no secure command response, clean ecx -+ xor ecx, ecx -+ ; secure call end -+ -+SecureCommandDone: -+ pop edi -+ pop esi -+ mov esp, 0 -+ -+ OneTimeCallRet CsvInit -+ -+; Check if CSV feature is enabled. -+; -+; Modified: EAX, EBX, ECX, EDX -+; -+; If CSV is enabled then EAX will be non-zero. -+; If CSV is disabled then EAX will be zero. -+; -+CheckCsvFeature: -+ mov esp, SEV_ES_VC_TOP_OF_STACK -+ mov eax, ADDR_OF(Idtr) -+ lidt [cs:eax] -+ -+ ; Check if vendor Hygon CPUID_SIGNATURE(0x0) -+ ; CPUID raises a #VC exception if running as an SEV-ES guest -+ mov eax, 0 -+ cpuid -+ -+ cmp ebx, 0x6f677948 -+ jne NoCsv -+ cmp ecx, 0x656e6975 -+ jne NoCsv -+ cmp edx, 0x6e65476e -+ jne NoCsv -+ -+ ; Check if CSV is enabled -+ ; MSR_0xC0010131 - Bit 30 (CSV enabled) -+ mov ecx, 0xc0010131 -+ rdmsr -+ and eax, 0x40000000 -+ jmp CsvExit -+ -+NoCsv: -+ xor eax, eax -+ -+CsvExit: -+ ; -+ ; Clear exception handlers and stack -+ ; -+ push eax -+ mov eax, ADDR_OF(IdtrClear) -+ lidt [cs:eax] -+ pop eax -+ mov esp, 0 -+ -+ OneTimeCallRet CheckCsvFeature -+ -+SECURE_CALL_GUID: -+; low 0xceba2fa59a5d926f -+; high 0xa556555d276b21ab -+ dd 0x9a5d926f -+ dd 0xceba2fa5 -+ dd 0x276b21ab -+ dd 0xa556555d -diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf -index 320e5f2..38c1720 100644 ---- a/OvmfPkg/ResetVector/ResetVector.inf -+++ b/OvmfPkg/ResetVector/ResetVector.inf -@@ -35,6 +35,8 @@ - - [Pcd] - gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase -diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb -index 87effed..ca00f64 100644 ---- a/OvmfPkg/ResetVector/ResetVector.nasmb -+++ b/OvmfPkg/ResetVector/ResetVector.nasmb -@@ -104,11 +104,15 @@ - %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16) - %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) - -+ %define CSV_DEFAULT_SECURE_CALL_BASE FixedPcdGet32 (PcdCsvDefaultSecureCallBase) -+ %define CSV_DEFAULT_SECURE_CALL_SIZE FixedPcdGet32 (PcdCsvDefaultSecureCallSize) -+ - %include "X64/IntelTdxMetadata.asm" - %include "Ia32/Flat32ToFlat64.asm" - %include "Ia32/AmdSev.asm" - %include "Ia32/PageTables64.asm" - %include "Ia32/IntelTdx.asm" -+%include "Ia32/CsvInit.asm" - %endif - - %include "Ia16/Real16ToFlat32.asm" --- -2.17.1 - diff --git a/0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch b/0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch deleted file mode 100644 index 3a55e93..0000000 --- a/0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 9c52c4e45c2fc51308628c8118edb3740bbfae47 Mon Sep 17 00:00:00 2001 -From: Liu Zixing -Date: Fri, 25 Feb 2022 16:12:38 +0800 -Subject: [PATCH 34/46] anolis: OvmfPkg/PlatformPei: Initialize CSV VM's memory - -For CSV VM, the Secure Processor builds a temporary nested -page table to help the guest to run into the PEI phase. - -In PEI phase, CSV VM detects the start address and size of the -guest physical memory. - -The CSV VM sends the memory information to the Secure Processor -to build the permanent nested page table. - -Signed-off-by: Xin Jiang -Change-Id: I853d17ffa4146037038018d934f224fcbf79be1a ---- - OvmfPkg/PlatformPei/Csv.c | 81 +++++++++++++++++++++++++++++ - OvmfPkg/PlatformPei/MemDetect.c | 2 - - OvmfPkg/PlatformPei/Platform.c | 2 + - OvmfPkg/PlatformPei/Platform.h | 14 +++++ - OvmfPkg/PlatformPei/PlatformPei.inf | 4 ++ - 5 files changed, 101 insertions(+), 2 deletions(-) - create mode 100644 OvmfPkg/PlatformPei/Csv.c - -diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c -new file mode 100644 -index 0000000..44e81e1 ---- /dev/null -+++ b/OvmfPkg/PlatformPei/Csv.c -@@ -0,0 +1,81 @@ -+/** @file -+ -+ CSV initialization in PEI -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "Platform.h" -+ -+VOID -+CsvInitializeMemInfo ( -+ VOID -+ ) -+{ -+ UINT64 LowerMemorySize; -+ UINT64 UpperMemorySize; -+ -+ if (!CsvIsEnabled ()) { -+ return ; -+ } -+ -+ LowerMemorySize = GetSystemMemorySizeBelow4gb (); -+ UpperMemorySize = GetSystemMemorySizeAbove4gb (); -+ -+ CsvUpdateMapLowerMemory ( -+ 0, -+ LowerMemorySize >> EFI_PAGE_SHIFT -+ ); -+ -+ if (UpperMemorySize > 0) { -+ CsvUpdateMapUpperMemory ( -+ BASE_4GB, -+ UpperMemorySize >> EFI_PAGE_SHIFT -+ ); -+ } -+ -+ BuildMemoryAllocationHob ( -+ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdCsvDefaultSecureCallBase), -+ (UINT64)(UINTN) FixedPcdGet32 (PcdCsvDefaultSecureCallSize), -+ EfiReservedMemoryType -+ ); -+} -+ -+VOID -+CsvInitializeGhcb ( -+ VOID -+ ) -+{ -+ RETURN_STATUS EncryptStatus; -+ -+ if (!CsvIsEnabled ()) { -+ return ; -+ } -+ -+ // -+ // Encrypt the SecGhcb as it's not a Ghcb any more -+ // -+ EncryptStatus = MemEncryptSevSetPageEncMask( -+ 0, -+ PcdGet32 (PcdOvmfSecGhcbBase), -+ 1 -+ ); -+ ASSERT_RETURN_ERROR (EncryptStatus); -+} -diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c -index d736b85..c2c3cf7 100644 ---- a/OvmfPkg/PlatformPei/MemDetect.c -+++ b/OvmfPkg/PlatformPei/MemDetect.c -@@ -301,8 +301,6 @@ GetSystemMemorySizeBelow4gb ( - return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); - } - -- --STATIC - UINT64 - GetSystemMemorySizeAbove4gb ( - ) -diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c -index d0e2c08..79bf4e7 100644 ---- a/OvmfPkg/PlatformPei/Platform.c -+++ b/OvmfPkg/PlatformPei/Platform.c -@@ -743,6 +743,7 @@ InitializePlatform ( - QemuUc32BaseInitialization (); - - InitializeRamRegions (); -+ CsvInitializeMemInfo (); - - if (mBootMode != BOOT_ON_S3_RESUME) { - if (!FeaturePcdGet (PcdSmmSmramRequire)) { -@@ -757,6 +758,7 @@ InitializePlatform ( - - InstallClearCacheCallback (); - AmdSevInitialize (); -+ CsvInitializeGhcb (); - MiscInitialization (); - InstallFeatureControlCallback (); - -diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h -index 8b1d270..89c3bd8 100644 ---- a/OvmfPkg/PlatformPei/Platform.h -+++ b/OvmfPkg/PlatformPei/Platform.h -@@ -102,6 +102,20 @@ AmdSevInitialize ( - VOID - ); - -+VOID -+CsvInitializeMemInfo ( -+ VOID -+); -+ -+VOID -+CsvInitializeGhcb ( -+ VOID -+); -+ -+UINT64 -+GetSystemMemorySizeAbove4gb ( -+); -+ - extern EFI_BOOT_MODE mBootMode; - - extern BOOLEAN mS3Supported; -diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf -index 69eb3ed..cb0582c 100644 ---- a/OvmfPkg/PlatformPei/PlatformPei.inf -+++ b/OvmfPkg/PlatformPei/PlatformPei.inf -@@ -33,6 +33,7 @@ - MemTypeInfo.c - Platform.c - Platform.h -+ Csv.c - - [Packages] - EmbeddedPkg/EmbeddedPkg.dec -@@ -62,6 +63,7 @@ - MtrrLib - MemEncryptSevLib - PcdLib -+ CsvLib - - [Pcd] - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase -@@ -119,6 +121,8 @@ - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize - - [FeaturePcd] - gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable --- -2.17.1 - diff --git a/0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch b/0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch deleted file mode 100644 index 1938b99..0000000 --- a/0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 16936ea22fc052576844dfdad6987531aa27a8ec Mon Sep 17 00:00:00 2001 -From: Liu Zixing -Date: Sat, 26 Feb 2022 14:39:06 +0800 -Subject: [PATCH 35/46] anolis: OvmfPkg/BaseMemcryptSevLib: update page status - to Secure Processor for CSV - -For CSV VM, when encrypting/decrypting a shared/private memory region, -guest needs to - - set/clear the c-bit in guest page table - - the Secure Processor should be updated accordingly - -The BaseMemcryptSevLib has done the first step. -Calling the secure call library for second step. - -Signed-off-by: Xin Jiang -Change-Id: Icab502ee201d887d6056bcb0116b2e5a1b9eb6b9 ---- - .../BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 1 + - .../BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 14 ++++++++++++++ - 2 files changed, 15 insertions(+) - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -index f2e162d..dc32929 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -@@ -49,6 +49,7 @@ - DebugLib - MemoryAllocationLib - PcdLib -+ CsvLib - - [FeaturePcd] - gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -index c696745..6726010 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -@@ -18,6 +18,8 @@ - - #include "VirtualMemory.h" - -+#include -+ - STATIC BOOLEAN mAddressEncMaskChecked = FALSE; - STATIC UINT64 mAddressEncMask; - STATIC PAGE_TABLE_POOL *mPageTablePool = NULL; -@@ -585,6 +587,11 @@ SetMemoryEncDec ( - UINT64 AddressEncMask; - BOOLEAN IsWpEnabled; - RETURN_STATUS Status; -+ PHYSICAL_ADDRESS PageAddress; -+ UINTN PageNum; -+ -+ PageAddress = PhysicalAddress; -+ PageNum = EFI_SIZE_TO_PAGES (Length); - - // - // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings. -@@ -816,6 +823,13 @@ Done: - EnableReadOnlyPageWriteProtect (); - } - -+ if (CsvIsEnabled () && Status == EFI_SUCCESS) { -+ if (Mode == ClearCBit) -+ CsvUpdateMemory (PageAddress, PageNum, TRUE); -+ else -+ CsvUpdateMemory (PageAddress, PageNum, FALSE); -+ } -+ - return Status; - } - --- -2.17.1 - diff --git a/0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch b/0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch deleted file mode 100644 index 0bf6d40..0000000 --- a/0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch +++ /dev/null @@ -1,616 +0,0 @@ -From 4569ddd201843a1fd1e9b0431e971cd4edefff5d Mon Sep 17 00:00:00 2001 -From: Liu Zixing -Date: Fri, 25 Feb 2022 16:34:25 +0800 -Subject: [PATCH 36/46] anolis: OvmfPkg: Add CsvDxe driver - -CsvDxe creates and installs the CsvSharedMemory protocol. - -CSV VM needs the shared memory to exchange data with external devices. - -To improve the performance, CsvSharedMemory protocol pre-allocates -huge shared memory chunk as a pool. - -When reqeusted, it allocates small pieces of shared memory from the -pool and records the allocated memory in a list. - -When finished, the shared memory pieces are returned to the pool and -removed from the record list. - -Signed-off-by: Xin Jiang -Change-Id: I6b41c6e1af34b4f8ad58a61cce2e7fd8e8b5795b ---- - OvmfPkg/CsvDxe/CsvDxe.c | 104 +++++++++++ - OvmfPkg/CsvDxe/CsvDxe.inf | 45 +++++ - OvmfPkg/CsvDxe/CsvSharedMemory.c | 208 +++++++++++++++++++++ - OvmfPkg/CsvDxe/CsvSharedMemory.h | 29 +++ - OvmfPkg/Include/Protocol/CsvSharedMemory.h | 99 ++++++++++ - OvmfPkg/OvmfPkg.dec | 1 + - OvmfPkg/OvmfPkgIa32X64.dsc | 1 + - OvmfPkg/OvmfPkgIa32X64.fdf | 1 + - OvmfPkg/OvmfPkgX64.dsc | 1 + - OvmfPkg/OvmfPkgX64.fdf | 1 + - 10 files changed, 490 insertions(+) - create mode 100644 OvmfPkg/CsvDxe/CsvDxe.c - create mode 100644 OvmfPkg/CsvDxe/CsvDxe.inf - create mode 100644 OvmfPkg/CsvDxe/CsvSharedMemory.c - create mode 100644 OvmfPkg/CsvDxe/CsvSharedMemory.h - create mode 100644 OvmfPkg/Include/Protocol/CsvSharedMemory.h - -diff --git a/OvmfPkg/CsvDxe/CsvDxe.c b/OvmfPkg/CsvDxe/CsvDxe.c -new file mode 100644 -index 0000000..552f3cf ---- /dev/null -+++ b/OvmfPkg/CsvDxe/CsvDxe.c -@@ -0,0 +1,104 @@ -+/** @file -+ -+ Hygon CSV DXE. -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT -+ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "CsvSharedMemory.h" -+ -+ -+#define HUGE_PAGE_SIZE 0x200000ULL -+ -+EFI_STATUS -+EFIAPI -+CsvDxeEntryPoint ( -+ IN EFI_HANDLE ImageHandle, -+ IN EFI_SYSTEM_TABLE *SystemTable -+ ) -+{ -+ EFI_STATUS Status; -+ RETURN_STATUS DecryptStatus; -+ CSV_SHARED_MEMORY_PROTOCOL *SharedMemory; -+ EFI_PHYSICAL_ADDRESS Memory; -+ EFI_PHYSICAL_ADDRESS EndMemory; -+ EFI_ALLOCATE_TYPE AllocateType; -+ UINT64 Size; -+ -+ Status = CsvInstallSharedMemoryProtocol (); -+ -+ if (EFI_ERROR (Status)) { -+ DEBUG ((EFI_D_ERROR, "fail to install CsvSharedMemory protocol\n")); -+ return Status; -+ } -+ -+ // -+ // Do nothing more when CSV is not enabled -+ // -+ if (!CsvIsEnabled ()) { -+ return EFI_SUCCESS; -+ } -+ -+ Status = gBS->LocateProtocol ( -+ &gCsvSharedMemoryProtocolGuid, -+ NULL, -+ (VOID**)&SharedMemory -+ ); -+ -+ if (Status == EFI_SUCCESS) { -+ -+ AllocateType = AllocateMaxAddress; -+ Memory = BASE_4GB - 1; -+ -+ Status = gBS->AllocatePages ( -+ AllocateType, -+ EfiBootServicesData, -+ CSV_SHARED_MEMORY_PAGE_NUMBER, -+ &Memory -+ ); -+ -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "fail to allocate CsvSharedMemory\n", SharedMemory)); -+ } else { -+ //Align to huge page -+ EndMemory = (Memory + CSV_SHARED_MEMORY_SIZE) & (~(HUGE_PAGE_SIZE - 1)); -+ Memory = ALIGN_VALUE(Memory, HUGE_PAGE_SIZE); -+ Size = (EndMemory > Memory) ? EndMemory - Memory : 0; -+ DecryptStatus = MemEncryptSevClearPageEncMask ( -+ 0, -+ Memory, -+ Size >> EFI_PAGE_SHIFT -+ ); -+ ASSERT_RETURN_ERROR (DecryptStatus); -+ -+ SharedMemory->CsvInitializeSharedMemoryList ( -+ SharedMemory, -+ (UINT64)Memory, -+ Size -+ ); -+ } -+ } else { -+ DEBUG ((DEBUG_ERROR, "fail to LocateProtocol gCsvSharedMemoryProtocolGuid\n")); -+ } -+ -+ return EFI_SUCCESS; -+} -diff --git a/OvmfPkg/CsvDxe/CsvDxe.inf b/OvmfPkg/CsvDxe/CsvDxe.inf -new file mode 100644 -index 0000000..89e3703 ---- /dev/null -+++ b/OvmfPkg/CsvDxe/CsvDxe.inf -@@ -0,0 +1,45 @@ -+#/** @file -+# -+# Secure Isolated Virtualization -+# -+# Copyright (c) 2022, HYGON Inc. All rights reserved.
-+# -+# This program and the accompanying materials are licensed and made available -+# under the terms and conditions of the BSD License which accompanies this -+# distribution. The full text of the license may be found at -+# http://opensource.org/licenses/bsd-license.php -+# -+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED. -+# -+#**/ -+ -+[Defines] -+ INF_VERSION = 1.25 -+ BASE_NAME = CsvDxe -+ FILE_GUID = 829310c0-b9c4-11e9-9e16-9b10d744f884 -+ MODULE_TYPE = DXE_DRIVER -+ VERSION_STRING = 1.0 -+ ENTRY_POINT = CsvDxeEntryPoint -+ -+[Sources] -+ CsvDxe.c -+ CsvSharedMemory.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ OvmfPkg/OvmfPkg.dec -+ -+[LibraryClasses] -+ BaseLib -+ BaseMemoryLib -+ DebugLib -+ CsvLib -+ UefiDriverEntryPoint -+ -+[Depex] -+ TRUE -+ -+[Protocols] -+ gCsvSharedMemoryProtocolGuid -diff --git a/OvmfPkg/CsvDxe/CsvSharedMemory.c b/OvmfPkg/CsvDxe/CsvSharedMemory.c -new file mode 100644 -index 0000000..8674eaf ---- /dev/null -+++ b/OvmfPkg/CsvDxe/CsvSharedMemory.c -@@ -0,0 +1,208 @@ -+/** @file -+ -+ The protocol provides allocate, free the CSV shared memory. -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+STATIC LIST_ENTRY CsvSharedMemoryList = INITIALIZE_LIST_HEAD_VARIABLE (CsvSharedMemoryList); -+ -+// -+// Insert the initial shared memory address and length to list. -+// -+ -+EFI_STATUS -+EFIAPI -+CsvInitializeSharedMemoryList ( -+ IN CSV_SHARED_MEMORY_PROTOCOL *Protocol, -+ IN UINT64 Address, -+ IN UINT64 Length -+ ) -+{ -+ CsvSharedMemoryEntry *Entry; -+ -+ if (Length == 0) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ Entry = AllocatePool (sizeof (*Entry)); -+ if (Entry == NULL) { -+ DEBUG((DEBUG_ERROR, "CsvInitializeSharedMemoryList AllocatePool error\n")); -+ return EFI_OUT_OF_RESOURCES; -+ } -+ -+ Entry->Start = Address; -+ Entry->Length = Length; -+ Entry->Signature = CSV_SHARED_MEMORY_SIGNATURE; -+ -+ InsertTailList (&CsvSharedMemoryList, &Entry->Link); -+ -+ return EFI_SUCCESS; -+} -+ -+EFI_STATUS -+EFIAPI -+CsvAllocateSharedMemory ( -+ IN CSV_SHARED_MEMORY_PROTOCOL *Protocol, -+ IN UINTN NumberOfPages, -+ OUT UINT64 *Memory -+ ) -+{ -+ LIST_ENTRY *Link; -+ CsvSharedMemoryEntry *Entry; -+ UINT64 MemoryLength; -+ -+ MemoryLength = (UINT64)NumberOfPages << EFI_PAGE_SHIFT; -+ -+ for (Link = CsvSharedMemoryList.ForwardLink; Link != &CsvSharedMemoryList; Link = Link->ForwardLink) { -+ Entry = CR (Link, CsvSharedMemoryEntry, Link, CSV_SHARED_MEMORY_SIGNATURE); -+ if (Entry->Length > MemoryLength) { -+ *Memory = (EFI_PHYSICAL_ADDRESS)Entry->Start; -+ Entry->Start = *Memory + MemoryLength; -+ Entry->Length -= MemoryLength; -+ break; -+ } else if (Entry->Length == MemoryLength) { -+ *Memory = (EFI_PHYSICAL_ADDRESS)Entry->Start; -+ RemoveEntryList (&Entry->Link); -+ FreePool (Entry); -+ break; -+ } -+ } -+ -+ -+ -+ if (Link == &CsvSharedMemoryList) { -+ DEBUG ((EFI_D_ERROR, "CsvAllocateSharedMemory fail to allocate %u pages\n", NumberOfPages)); -+ return EFI_NOT_FOUND; -+ } -+ else { -+ return EFI_SUCCESS; -+ } -+} -+ -+ -+ -+EFI_STATUS -+EFIAPI -+CsvFreeSharedMemory ( -+ IN CSV_SHARED_MEMORY_PROTOCOL *Protocol, -+ IN UINTN Pages, -+ IN UINT64 HostAddress -+ ) -+{ -+ LIST_ENTRY *Link; -+ CsvSharedMemoryEntry *Entry; -+ CsvSharedMemoryEntry *NewEntry; -+ UINT64 Memory; -+ UINT64 MemoryLength; -+ CsvSharedMemoryEntry *Previous = NULL; -+ BOOLEAN Inserted = FALSE; -+ -+ Memory = (UINT64)HostAddress; -+ MemoryLength = (UINT64)Pages << EFI_PAGE_SHIFT; -+ -+ for (Link = CsvSharedMemoryList.ForwardLink; -+ Link != &CsvSharedMemoryList; -+ Link = Link->ForwardLink) { -+ Entry = CR (Link, CsvSharedMemoryEntry, Link, CSV_SHARED_MEMORY_SIGNATURE); -+ if (Inserted) -+ goto Merge; -+ if (Entry->Start + Entry->Length == Memory) { -+ Entry->Length += MemoryLength; -+ Inserted = TRUE; -+ goto Merge; -+ } else if (Memory + MemoryLength < Entry->Start) { -+ NewEntry = AllocatePool (sizeof *NewEntry); -+ if (NewEntry == NULL) { -+ return EFI_OUT_OF_RESOURCES; -+ } -+ -+ NewEntry->Start = Memory; -+ NewEntry->Length = MemoryLength; -+ NewEntry->Signature = CSV_SHARED_MEMORY_SIGNATURE; -+ -+ InsertTailList (&Entry->Link, &NewEntry->Link); -+ break; -+ } else if (Memory + MemoryLength == Entry->Start) { -+ Entry->Start = Memory; -+ Entry->Length += MemoryLength; -+ break; -+ } else if (Link->ForwardLink == &CsvSharedMemoryList) { -+ // -+ // Insert to tail -+ // -+ NewEntry = AllocatePool (sizeof *NewEntry); -+ if (NewEntry == NULL) { -+ return EFI_OUT_OF_RESOURCES; -+ } -+ -+ NewEntry->Start = Memory; -+ NewEntry->Length = MemoryLength; -+ NewEntry->Signature = CSV_SHARED_MEMORY_SIGNATURE; -+ InsertHeadList (Link, &NewEntry->Link); -+ break; -+ } -+ -+Merge: -+ if (Previous) { -+ if (Previous->Start + Previous->Length == Entry->Start) { -+ Entry->Start = Previous->Start; -+ Entry->Length += Previous->Length; -+ RemoveEntryList (&Previous->Link); -+ FreePool (Previous); -+ } -+ break; -+ } else { -+ Previous = Entry; -+ } -+ } -+ -+ return EFI_SUCCESS; -+} -+ -+CSV_SHARED_MEMORY_PROTOCOL mCsvSharedMemory = { -+ CsvInitializeSharedMemoryList, -+ CsvAllocateSharedMemory, -+ CsvFreeSharedMemory -+}; -+ -+/** -+ Initialize CsvSharedMemory Protocol. -+ -+**/ -+EFI_STATUS -+EFIAPI -+CsvInstallSharedMemoryProtocol ( -+ VOID -+ ) -+{ -+ EFI_STATUS Status; -+ EFI_HANDLE Handle; -+ -+ Handle = NULL; -+ Status = gBS->InstallMultipleProtocolInterfaces ( -+ &Handle, -+ &gCsvSharedMemoryProtocolGuid, -+ &mCsvSharedMemory, -+ NULL -+ ); -+ return Status; -+} -diff --git a/OvmfPkg/CsvDxe/CsvSharedMemory.h b/OvmfPkg/CsvDxe/CsvSharedMemory.h -new file mode 100644 -index 0000000..8828515 ---- /dev/null -+++ b/OvmfPkg/CsvDxe/CsvSharedMemory.h -@@ -0,0 +1,29 @@ -+/** @file -+ CSV shared memory management protocol -+ -+ Copyright (C) 2022 HYGON. -+ -+ This program and the accompanying materials -+ are licensed and made available under the terms and conditions of the BSD License -+ which accompanies this distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#ifndef _CSV_SHARED_MEMORY_H_ -+#define _CSV_SHARED_MEMORY_H_ -+ -+// -+// Install SHARED_MEMORY protocol . -+// -+ -+EFI_STATUS -+EFIAPI -+CsvInstallSharedMemoryProtocol ( -+ VOID -+ ); -+ -+#endif -diff --git a/OvmfPkg/Include/Protocol/CsvSharedMemory.h b/OvmfPkg/Include/Protocol/CsvSharedMemory.h -new file mode 100644 -index 0000000..0c3f23d ---- /dev/null -+++ b/OvmfPkg/Include/Protocol/CsvSharedMemory.h -@@ -0,0 +1,99 @@ -+/** @file -+ CSV shared memory management protocol -+ -+ Copyright (C) 2022 HYGON. -+ -+ This program and the accompanying materials -+ are licensed and made available under the terms and conditions of the BSD License -+ which accompanies this distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#ifndef __PROTOCOL_CSV_SHARED_MEMORY_H__ -+#define __PROTOCOL_CSV_SHARED_MEMORY_H__ -+ -+#define CSV_SHARED_MEMORY_PAGE_NUMBER (16384ULL) -+#define CSV_SHARED_MEMORY_SIZE ((CSV_SHARED_MEMORY_PAGE_NUMBER)*(SIZE_4KB)) -+ -+/// -+/// Forward declaration -+/// -+typedef struct _CSV_SHARED_MEMORY_PROTOCOL CSV_SHARED_MEMORY_PROTOCOL; -+ -+ -+/// -+/// Function prototypes -+/// -+ -+/** -+ Initialize the list to manage the CSV shared memory. -+ Insert the start address and length. -+ -+ @param This A pointer to CSV_SHARED_MEMORY_PROTOCOL instance. -+ @param Address The start address of the shared memory. -+ @param Length The length of the shared memory. -+ -+**/ -+typedef -+EFI_STATUS -+(EFIAPI *CSV_INITIALIZE_SHARED_MEMORY_LIST)( -+ IN CSV_SHARED_MEMORY_PROTOCOL *This, -+ IN UINT64 Address, -+ IN UINT64 Length -+ ); -+ -+/** -+ Allocate buffer from the shared memory. -+ -+ @param This A pointer to CSV_SHARED_MEMORY_PROTOCOL instance. -+ @param NumberOfPages The length of page number. -+ @param Memory When success, allocated memory will be stored in. -+ -+ @return On success, EFI_SUCCESS. Otherwise an errno value -+ indicating the type of failure. -+**/ -+typedef -+EFI_STATUS -+(EFIAPI *CSV_ALLOCATE_SHARED_MEMORY)( -+ IN CSV_SHARED_MEMORY_PROTOCOL *This, -+ IN UINTN NumberOfPages, -+ OUT UINT64 *Memory -+ ); -+ -+/** -+ Free buffer to the shared memory. -+ -+ @param This A pointer to CSV_SHARED_MEMORY_PROTOCOL instance. -+ @param NumberOfPages The page number. -+ @param Memory The allocated memory to be freed. -+ -+ @return On success, EFI_SUCCESS. Otherwise an errno value -+ indicating the type of failure. -+**/ -+typedef -+EFI_STATUS -+(EFIAPI *CSV_FREE_SHARED_MEMORY)( -+ IN CSV_SHARED_MEMORY_PROTOCOL *This, -+ IN UINTN NumberOfPages, -+ IN UINT64 Memory -+ ); -+ -+/// -+/// Protocol structure -+/// -+struct _CSV_SHARED_MEMORY_PROTOCOL { -+ // -+ // Protocol data fields -+ // -+ CSV_INITIALIZE_SHARED_MEMORY_LIST CsvInitializeSharedMemoryList; -+ CSV_ALLOCATE_SHARED_MEMORY CsvAllocateSharedMemory; -+ CSV_FREE_SHARED_MEMORY CsvFreeSharedMemory; -+}; -+ -+extern EFI_GUID gCsvSharedMemoryProtocolGuid; -+ -+#endif -diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec -index 6f4afb8..d8f9be3 100644 ---- a/OvmfPkg/OvmfPkg.dec -+++ b/OvmfPkg/OvmfPkg.dec -@@ -152,6 +152,7 @@ - gEfiLegacyInterruptProtocolGuid = {0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}} - gEfiVgaMiniPortProtocolGuid = {0xc7735a2f, 0x88f5, 0x4882, {0xae, 0x63, 0xfa, 0xac, 0x8c, 0x8b, 0x86, 0xb3}} - gOvmfLoadedX86LinuxKernelProtocolGuid = {0xa3edc05d, 0xb618, 0x4ff6, {0x95, 0x52, 0x76, 0xd7, 0x88, 0x63, 0x43, 0xc8}} -+ gCsvSharedMemoryProtocolGuid = {0x0c795ed0, 0xbf0a, 0x11e9, {0x99, 0xbe, 0x50, 0x9a, 0x4c, 0x01, 0x1e, 0xd1}} - - [PcdsFixedAtBuild] - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|0x0|UINT32|0 -diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc -index 9e4dcce..edc0f0e 100644 ---- a/OvmfPkg/OvmfPkgIa32X64.dsc -+++ b/OvmfPkg/OvmfPkgIa32X64.dsc -@@ -982,6 +982,7 @@ - OvmfPkg/PlatformDxe/Platform.inf - OvmfPkg/AmdSevDxe/AmdSevDxe.inf - OvmfPkg/IoMmuDxe/IoMmuDxe.inf -+ OvmfPkg/CsvDxe/CsvDxe.inf - - !if $(SMM_REQUIRE) == TRUE - OvmfPkg/SmmAccess/SmmAccess2Dxe.inf -diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf -index e33a40c..f05405b 100644 ---- a/OvmfPkg/OvmfPkgIa32X64.fdf -+++ b/OvmfPkg/OvmfPkgIa32X64.fdf -@@ -339,6 +339,7 @@ INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf - INF OvmfPkg/PlatformDxe/Platform.inf - INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf - INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf -+INF OvmfPkg/CsvDxe/CsvDxe.inf - - !if $(SMM_REQUIRE) == TRUE - INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf -diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc -index e62b533..763214d 100644 ---- a/OvmfPkg/OvmfPkgX64.dsc -+++ b/OvmfPkg/OvmfPkgX64.dsc -@@ -980,6 +980,7 @@ - OvmfPkg/PlatformDxe/Platform.inf - OvmfPkg/AmdSevDxe/AmdSevDxe.inf - OvmfPkg/IoMmuDxe/IoMmuDxe.inf -+ OvmfPkg/CsvDxe/CsvDxe.inf - - !if $(SMM_REQUIRE) == TRUE - OvmfPkg/SmmAccess/SmmAccess2Dxe.inf -diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf -index a3634dd..0f04acb 100644 ---- a/OvmfPkg/OvmfPkgX64.fdf -+++ b/OvmfPkg/OvmfPkgX64.fdf -@@ -358,6 +358,7 @@ INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf - INF OvmfPkg/PlatformDxe/Platform.inf - INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf - INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf -+INF OvmfPkg/CsvDxe/CsvDxe.inf - - !if $(SMM_REQUIRE) == TRUE - INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf --- -2.17.1 - diff --git a/0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch b/0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch deleted file mode 100644 index 9b4b800..0000000 --- a/0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch +++ /dev/null @@ -1,724 +0,0 @@ -From 8f82f4b8d86ca1b10b9353b484c403c628b3b560 Mon Sep 17 00:00:00 2001 -From: Liu Zixing -Date: Fri, 25 Feb 2022 16:54:44 +0800 -Subject: [PATCH 37/46] anolis: OvmfPkg/IoMmuDxe: Add CsvIoMmu protocol - -Create the dedicated IoMmu protocol for CSV virtual machine. -And Install it during CSV VM boots up. - -It calls the CsvSharedMemoryProtocol to allocate shared memory -for DMA operations. - -- AllocateBuffer() allocates the shared memory. - -- FreeBuffer() frees the shared memory. - -- Map() does nothing when BusMasterCommonBuffer[64] is requested - Otherwise, Map() allocates shared memory. - -- Unmap() does nothing when cleaning up a BusMasterCommonBuffer[64] - operation. Otherwise, Unmap() frees the shared memory. - -Signed-off-by: Xin Jiang -Change-Id: If49857f45c639341a96605722b06babfa1553874 ---- - OvmfPkg/IoMmuDxe/CsvIoMmu.c | 592 ++++++++++++++++++++++++++++++++++ - OvmfPkg/IoMmuDxe/CsvIoMmu.h | 29 ++ - OvmfPkg/IoMmuDxe/IoMmuDxe.c | 10 + - OvmfPkg/IoMmuDxe/IoMmuDxe.inf | 6 +- - 4 files changed, 636 insertions(+), 1 deletion(-) - create mode 100644 OvmfPkg/IoMmuDxe/CsvIoMmu.c - create mode 100644 OvmfPkg/IoMmuDxe/CsvIoMmu.h - -diff --git a/OvmfPkg/IoMmuDxe/CsvIoMmu.c b/OvmfPkg/IoMmuDxe/CsvIoMmu.c -new file mode 100644 -index 0000000..c5df6b9 ---- /dev/null -+++ b/OvmfPkg/IoMmuDxe/CsvIoMmu.c -@@ -0,0 +1,592 @@ -+/** @file -+ -+ The protocol provides support to allocate, free, map and umap a DMA buffer -+ for bus master (e.g PciHostBridge). When CSV is enabled, the DMA operations -+ must be performed on non-secure memory so we have to allocate the DMA buffer -+ from non-secure memory. -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "CsvIoMmu.h" -+ -+#define MAP_INFO_SIG SIGNATURE_64 ('M', 'A', 'P', '_', 'I', 'N', 'F', 'O') -+ -+typedef struct { -+ UINT64 Signature; -+ LIST_ENTRY Link; -+ EDKII_IOMMU_OPERATION Operation; -+ UINTN NumberOfBytes; -+ UINTN NumberOfPages; -+ EFI_PHYSICAL_ADDRESS SecureAddress; -+ EFI_PHYSICAL_ADDRESS UnSecureAddress; -+} MAP_INFO; -+ -+// -+// List of the MAP_INFO structures that have been set up by IoMmuMap() and not -+// yet torn down by IoMmuUnmap(). The list represents the full set of mappings -+// currently in effect. -+// -+STATIC LIST_ENTRY mMapInfos = INITIALIZE_LIST_HEAD_VARIABLE (mMapInfos); -+ -+// -+// ASCII names for EDKII_IOMMU_OPERATION constants, for debug logging. -+// -+STATIC CONST CHAR8 * CONST -+mBusMasterOperationName[EdkiiIoMmuOperationMaximum] = { -+ "Read", -+ "Write", -+ "CommonBuffer", -+ "Read64", -+ "Write64", -+ "CommonBuffer64" -+}; -+ -+STATIC CSV_SHARED_MEMORY_PROTOCOL *SharedMemory; -+STATIC -+EFI_STATUS -+EFIAPI -+CsvAllocSharedPage( -+ IN UINTN Pages, -+ OUT EFI_PHYSICAL_ADDRESS *Address -+ ) -+{ -+ EFI_STATUS Status; -+ -+ Status = SharedMemory->CsvAllocateSharedMemory ( -+ SharedMemory, -+ Pages, -+ (UINT64*)Address -+ ); -+ -+ return Status; -+} -+ -+STATIC -+EFI_STATUS -+EFIAPI -+CsvFreeSharedPage( -+ IN UINTN Pages, -+ IN VOID *HostAddress -+ ) -+{ -+ EFI_STATUS Status; -+ -+ Status = SharedMemory->CsvFreeSharedMemory ( -+ SharedMemory, -+ Pages, -+ (UINTN)HostAddress -+ ); -+ -+ return Status; -+} -+ -+/** -+ Provides the controller-specific addresses required to access system memory -+ from a DMA bus master. -+ On CSV guest, the DMA openerations must be done on non-secure memory which -+ is the shared memory between the guest and QEMU. -+ -+ @param This The protocol instance pointer. -+ @param Operation Indicates if the bus master is going to read or -+ write to system memory. -+ @param HostAddress The system memory address to map to the PCI -+ controller. -+ @param NumberOfBytes On input the number of bytes to map. On output -+ the number of bytes that were mapped. -+ @param DeviceAddress The resulting map address for the bus master -+ PCI controller to use to access the hosts -+ HostAddress. -+ @param Mapping A resulting value to pass to Unmap(). -+ -+ @retval EFI_SUCCESS The range was mapped for the returned -+ NumberOfBytes. -+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common -+ buffer. -+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid. -+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a -+ lack of resources. -+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested -+ address. -+ -+**/ -+EFI_STATUS -+EFIAPI -+CsvIoMmuMap ( -+ IN EDKII_IOMMU_PROTOCOL *This, -+ IN EDKII_IOMMU_OPERATION Operation, -+ IN VOID *HostAddress, -+ IN OUT UINTN *NumberOfBytes, -+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, -+ OUT VOID **Mapping -+ ) -+{ -+ EFI_STATUS Status; -+ MAP_INFO *MapInfo; -+ -+ DEBUG (( -+ DEBUG_VERBOSE, -+ "%a: Operation=%a Operation=%u Host=0x%p Bytes=0x%Lx\n", -+ __FUNCTION__, -+ ((Operation >= 0 && -+ Operation < ARRAY_SIZE (mBusMasterOperationName)) ? -+ mBusMasterOperationName[Operation] : -+ "Invalid"), -+ Operation, -+ HostAddress, -+ (UINT64)((NumberOfBytes == NULL) ? 0 : *NumberOfBytes) -+ )); -+ -+ if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || -+ Mapping == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // Allocate a MAP_INFO structure to remember the mapping when Unmap() is -+ // called later. -+ // -+ MapInfo = AllocatePool (sizeof (MAP_INFO)); -+ if (MapInfo == NULL) { -+ Status = EFI_OUT_OF_RESOURCES; -+ goto Failed; -+ } -+ -+ ZeroMem (&MapInfo->Link, sizeof MapInfo->Link); -+ MapInfo->Operation = Operation; -+ MapInfo->NumberOfBytes = *NumberOfBytes; -+ MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes); -+ MapInfo->Signature = MAP_INFO_SIG; -+ -+ switch (Operation) { -+ // -+ // For BusMasterRead[64] and BusMasterWrite[64] operations, a bounce buffer -+ // is necessary regardless of whether the original (crypted) buffer crosses -+ // the 4GB limit or not -- we have to allocate a separate plaintext buffer. -+ // The only variable is whether the plaintext buffer should be under 4GB. -+ // -+ case EdkiiIoMmuOperationBusMasterRead: -+ case EdkiiIoMmuOperationBusMasterWrite: -+ // -+ // fall through -+ // -+ case EdkiiIoMmuOperationBusMasterRead64: -+ case EdkiiIoMmuOperationBusMasterWrite64: -+ // -+ // Allocate the implicit plaintext bounce buffer. -+ // -+ Status = CsvAllocSharedPage ( -+ MapInfo->NumberOfPages, -+ &MapInfo->UnSecureAddress -+ ); -+ if (EFI_ERROR (Status)) { -+ goto FreeMapInfo; -+ } -+ MapInfo->SecureAddress = (UINTN)HostAddress; -+ if (Operation == EdkiiIoMmuOperationBusMasterRead || -+ Operation == EdkiiIoMmuOperationBusMasterRead64) { -+ CopyMem ( -+ (VOID *) (UINTN) MapInfo->UnSecureAddress, -+ (VOID *) (UINTN) MapInfo->SecureAddress, -+ MapInfo->NumberOfBytes -+ ); -+ } -+ break; -+ -+ // -+ // For BusMasterCommonBuffer[64] operations, -+ // AllocateBuffer already returns the plain-text, -+ // No need to decrypt the data. -+ // -+ case EdkiiIoMmuOperationBusMasterCommonBuffer: -+ case EdkiiIoMmuOperationBusMasterCommonBuffer64: -+ MapInfo->UnSecureAddress = (UINTN)HostAddress; -+ MapInfo->SecureAddress = (UINTN)HostAddress; -+ break; -+ -+ default: -+ // -+ // Operation is invalid -+ // -+ Status = EFI_INVALID_PARAMETER; -+ goto FreeMapInfo; -+ } -+ -+ // -+ // Track all MAP_INFO structures. -+ // -+ InsertHeadList (&mMapInfos, &MapInfo->Link); -+ // -+ // Populate output parameters. -+ // -+ *DeviceAddress = MapInfo->UnSecureAddress; -+ *Mapping = MapInfo; -+ -+ DEBUG (( -+ DEBUG_VERBOSE, -+ "%a: Mapping=0x%p Device=0x%Lx Host=0x%Lx Pages=0x%Lx\n", -+ __FUNCTION__, -+ MapInfo, -+ MapInfo->UnSecureAddress, -+ MapInfo->SecureAddress, -+ (UINT64)MapInfo->NumberOfPages -+ )); -+ -+ return EFI_SUCCESS; -+ -+FreeMapInfo: -+ FreePool (MapInfo); -+ -+Failed: -+ *NumberOfBytes = 0; -+ return Status; -+} -+ -+/** -+ Completes the Map() operation and releases any corresponding resources. -+ -+ This is an internal worker function that only extends the Map() API with -+ the MemoryMapLocked parameter. -+ -+ @param This The protocol instance pointer. -+ @param Mapping The mapping value returned from Map(). -+ @param MemoryMapLocked The function is executing on the stack of -+ gBS->ExitBootServices(); changes to the UEFI -+ memory map are forbidden. -+ -+ @retval EFI_SUCCESS The range was unmapped. -+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by -+ Map(). -+ @retval EFI_DEVICE_ERROR The data was not committed to the target system -+ memory. -+**/ -+STATIC -+EFI_STATUS -+EFIAPI -+CsvIoMmuUnmapWorker ( -+ IN EDKII_IOMMU_PROTOCOL *This, -+ IN VOID *Mapping, -+ IN BOOLEAN MemoryMapLocked -+ ) -+{ -+ MAP_INFO *MapInfo; -+ EDKII_IOMMU_OPERATION Operation; -+ -+ if (Mapping == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ MapInfo = (MAP_INFO *)Mapping; -+ Operation = MapInfo->Operation; -+ -+ DEBUG (( -+ DEBUG_VERBOSE, -+ "%a: Mapping=0x%p MemoryMapLocked=%d Operation %a Operation %d\n", -+ __FUNCTION__, -+ Mapping, -+ MemoryMapLocked, -+ ((Operation >= 0 && -+ Operation < ARRAY_SIZE (mBusMasterOperationName)) ? -+ mBusMasterOperationName[Operation] : -+ "Invalid"), -+ Operation -+ )); -+ -+ switch (MapInfo->Operation) { -+ case EdkiiIoMmuOperationBusMasterWrite: -+ case EdkiiIoMmuOperationBusMasterWrite64: -+ CopyMem ( -+ (VOID *) (UINTN) MapInfo->SecureAddress, -+ (VOID *) (UINTN) MapInfo->UnSecureAddress, -+ MapInfo->NumberOfBytes -+ ); -+ case EdkiiIoMmuOperationBusMasterRead: -+ case EdkiiIoMmuOperationBusMasterRead64: -+ ZeroMem ( -+ (VOID *)(UINTN)MapInfo->UnSecureAddress, -+ EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages) -+ ); -+ CsvFreeSharedPage( -+ MapInfo->NumberOfPages, -+ (VOID*)(UINTN)MapInfo->UnSecureAddress -+ ); -+ -+ default: -+ break; -+ } -+ -+ // -+ // Forget the MAP_INFO structure, then free it (unless the UEFI memory map is -+ // locked). -+ // -+ RemoveEntryList (&MapInfo->Link); -+ if (!MemoryMapLocked) { -+ FreePool (MapInfo); -+ } -+ -+ return EFI_SUCCESS; -+ -+} -+ -+/** -+ Completes the Map() operation and releases any corresponding resources. -+ -+ @param This The protocol instance pointer. -+ @param Mapping The mapping value returned from Map(). -+ -+ @retval EFI_SUCCESS The range was unmapped. -+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by -+ Map(). -+ @retval EFI_DEVICE_ERROR The data was not committed to the target system -+ memory. -+**/ -+EFI_STATUS -+EFIAPI -+CsvIoMmuUnmap ( -+ IN EDKII_IOMMU_PROTOCOL *This, -+ IN VOID *Mapping -+ ) -+{ -+ return CsvIoMmuUnmapWorker ( -+ This, -+ Mapping, -+ FALSE // MemoryMapLocked -+ ); -+} -+ -+/** -+ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or -+ OperationBusMasterCommonBuffer64 mapping. -+ -+ @param This The protocol instance pointer. -+ @param Type This parameter is not used and must be ignored. -+ @param MemoryType The type of memory to allocate, -+ EfiBootServicesData or EfiRuntimeServicesData. -+ @param Pages The number of pages to allocate. -+ @param HostAddress A pointer to store the base system memory -+ address of the allocated range. -+ @param Attributes The requested bit mask of attributes for the -+ allocated range. -+ -+ @retval EFI_SUCCESS The requested memory pages were allocated. -+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal -+ attribute bits are MEMORY_WRITE_COMBINE and -+ MEMORY_CACHED. -+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid. -+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. -+ -+**/ -+EFI_STATUS -+EFIAPI -+CsvIoMmuAllocateBuffer ( -+ IN EDKII_IOMMU_PROTOCOL *This, -+ IN EFI_ALLOCATE_TYPE Type, -+ IN EFI_MEMORY_TYPE MemoryType, -+ IN UINTN Pages, -+ IN OUT VOID **HostAddress, -+ IN UINT64 Attributes -+ ) -+{ -+ EFI_STATUS Status; -+ EFI_PHYSICAL_ADDRESS PhysicalAddress; -+ -+ DEBUG (( -+ DEBUG_VERBOSE, -+ "%a: MemoryType=%u Pages=0x%Lx Attributes=0x%Lx\n", -+ __FUNCTION__, -+ (UINT32)MemoryType, -+ (UINT64)Pages, -+ Attributes -+ )); -+ -+ // -+ // Validate Attributes -+ // -+ if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) { -+ return EFI_UNSUPPORTED; -+ } -+ -+ // -+ // Check for invalid inputs -+ // -+ if (HostAddress == NULL) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // The only valid memory types are EfiBootServicesData and -+ // EfiRuntimeServicesData -+ // -+ if (MemoryType != EfiBootServicesData && -+ MemoryType != EfiRuntimeServicesData) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ // -+ // We'll need a header page for the COMMON_BUFFER_HEADER structure. -+ // -+ if (Pages > MAX_UINTN - 1) { -+ return EFI_OUT_OF_RESOURCES; -+ } -+ -+ Status = CsvAllocSharedPage (Pages,&PhysicalAddress); -+ if (Status != EFI_SUCCESS){ -+ goto error; -+ } -+ -+ -+ *HostAddress = (VOID *)(UINTN)PhysicalAddress; -+ -+ return EFI_SUCCESS; -+ -+error: -+ return Status; -+} -+ -+/** -+ Frees memory that was allocated with AllocateBuffer(). -+ -+ @param This The protocol instance pointer. -+ @param Pages The number of pages to free. -+ @param HostAddress The base system memory address of the allocated -+ range. -+ -+ @retval EFI_SUCCESS The requested memory pages were freed. -+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and -+ Pages was not allocated with AllocateBuffer(). -+ -+**/ -+EFI_STATUS -+EFIAPI -+CsvIoMmuFreeBuffer ( -+ IN EDKII_IOMMU_PROTOCOL *This, -+ IN UINTN Pages, -+ IN VOID *HostAddress -+ ) -+{ -+ -+ EFI_STATUS Status; -+ -+ if (HostAddress == NULL || Pages == 0) { -+ return EFI_INVALID_PARAMETER; -+ } -+ -+ DEBUG (( -+ DEBUG_VERBOSE, -+ "%a: Host=0x%p Pages=0x%Lx\n", -+ __FUNCTION__, -+ HostAddress, -+ (UINT64)Pages -+ )); -+ -+ Status = CsvFreeSharedPage (Pages, HostAddress); -+ -+ return Status; -+} -+ -+ -+/** -+ Set IOMMU attribute for a system memory. -+ -+ @param[in] This The protocol instance pointer. -+ @param[in] DeviceHandle The device who initiates the DMA access -+ request. -+ @param[in] Mapping The mapping value returned from Map(). -+ @param[in] IoMmuAccess The IOMMU access. -+ -+ @retval EFI_SUCCESS The IoMmuAccess is set for the memory range -+ specified by DeviceAddress and Length. -+ @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle. -+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by -+ Map(). -+ @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination -+ of access. -+ @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU. -+ @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported -+ by the IOMMU. -+ @retval EFI_UNSUPPORTED The IOMMU does not support the memory range -+ specified by Mapping. -+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to -+ modify the IOMMU access. -+ @retval EFI_DEVICE_ERROR The IOMMU device reported an error while -+ attempting the operation. -+ -+**/ -+EFI_STATUS -+EFIAPI -+CsvIoMmuSetAttribute ( -+ IN EDKII_IOMMU_PROTOCOL *This, -+ IN EFI_HANDLE DeviceHandle, -+ IN VOID *Mapping, -+ IN UINT64 IoMmuAccess -+ ) -+{ -+ return EFI_UNSUPPORTED; -+} -+ -+EDKII_IOMMU_PROTOCOL mCsv = { -+ EDKII_IOMMU_PROTOCOL_REVISION, -+ CsvIoMmuSetAttribute, -+ CsvIoMmuMap, -+ CsvIoMmuUnmap, -+ CsvIoMmuAllocateBuffer, -+ CsvIoMmuFreeBuffer, -+}; -+ -+/** -+ Initialize Iommu Protocol. -+ -+**/ -+EFI_STATUS -+EFIAPI -+CsvInstallIoMmuProtocol ( -+ VOID -+ ) -+{ -+ EFI_STATUS Status; -+ EFI_HANDLE Handle; -+ -+ Status = gBS->LocateProtocol ( -+ &gCsvSharedMemoryProtocolGuid, -+ NULL, -+ (VOID**)&SharedMemory -+ ); -+ -+ if (EFI_ERROR (Status)) { -+ goto error; -+ } -+ -+ Handle = NULL; -+ Status = gBS->InstallMultipleProtocolInterfaces ( -+ &Handle, -+ &gEdkiiIoMmuProtocolGuid, -+ &mCsv, -+ NULL -+ ); -+ if (EFI_ERROR (Status)) { -+ goto error; -+ } -+ -+ return EFI_SUCCESS; -+ -+error: -+ return Status; -+} -diff --git a/OvmfPkg/IoMmuDxe/CsvIoMmu.h b/OvmfPkg/IoMmuDxe/CsvIoMmu.h -new file mode 100644 -index 0000000..d48a02c ---- /dev/null -+++ b/OvmfPkg/IoMmuDxe/CsvIoMmu.h -@@ -0,0 +1,29 @@ -+/** @file -+ -+ The protocol provides support to allocate, free, map and umap a DMA buffer -+ for bus master (e.g PciHostBridge). When CSV is enabled, the DMA operations -+ must be performed on unencrypted buffer hence protocol clear the encryption -+ bit from the DMA buffer. -+ -+ Copyright (c) 2022, HYGON. All rights reserved.
-+ -+ This program and the accompanying materials are licensed and made available -+ under the terms and conditions of the BSD License which accompanies this -+ distribution. The full text of the license may be found at -+ http://opensource.org/licenses/bsd-license.php -+ -+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#ifndef _CSV_IOMMU_H_ -+#define _CSV_IOMMU_H_ -+ -+EFI_STATUS -+EFIAPI -+CsvInstallIoMmuProtocol ( -+ VOID -+ ); -+ -+#endif -diff --git a/OvmfPkg/IoMmuDxe/IoMmuDxe.c b/OvmfPkg/IoMmuDxe/IoMmuDxe.c -index 13df8ba..35e5df9 100644 ---- a/OvmfPkg/IoMmuDxe/IoMmuDxe.c -+++ b/OvmfPkg/IoMmuDxe/IoMmuDxe.c -@@ -9,7 +9,9 @@ - - **/ - -+#include - #include "AmdSevIoMmu.h" -+#include "CsvIoMmu.h" - - EFI_STATUS - EFIAPI -@@ -21,6 +23,14 @@ IoMmuDxeEntryPoint ( - EFI_STATUS Status; - EFI_HANDLE Handle; - -+ if (CsvIsEnabled ()) { -+ Status = CsvInstallIoMmuProtocol (); -+ if (Status != EFI_SUCCESS) { -+ DEBUG((EFI_D_ERROR, "fail to install CSV IOMMU\n")); -+ } -+ return Status; -+ } -+ - // - // When SEV is enabled, install IoMmu protocol otherwise install the - // placeholder protocol so that other dependent module can run. -diff --git a/OvmfPkg/IoMmuDxe/IoMmuDxe.inf b/OvmfPkg/IoMmuDxe/IoMmuDxe.inf -index 2ebd74e..6b89c6a 100644 ---- a/OvmfPkg/IoMmuDxe/IoMmuDxe.inf -+++ b/OvmfPkg/IoMmuDxe/IoMmuDxe.inf -@@ -21,6 +21,8 @@ - AmdSevIoMmu.c - AmdSevIoMmu.h - IoMmuDxe.c -+ CsvIoMmu.c -+ CsvIoMmu.h - - [Packages] - MdePkg/MdePkg.dec -@@ -35,10 +37,12 @@ - MemoryAllocationLib - UefiBootServicesTableLib - UefiDriverEntryPoint -+ CsvLib - - [Protocols] - gEdkiiIoMmuProtocolGuid ## SOMETIME_PRODUCES - gIoMmuAbsentProtocolGuid ## SOMETIME_PRODUCES -+ gCsvSharedMemoryProtocolGuid - - [Depex] -- TRUE -+ gCsvSharedMemoryProtocolGuid --- -2.17.1 - diff --git a/0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch b/0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch deleted file mode 100644 index 6aeeadf..0000000 --- a/0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 8a7ac3e25c1e8a62852a64d0a303e948b0e1499a Mon Sep 17 00:00:00 2001 -From: Xin Jiang -Date: Tue, 15 Aug 2023 17:15:53 +0800 -Subject: [PATCH 38/46] anolis: OvmfPkg: Reserve a CPUID table page for CSV - guest - -Reserve a page for CPUID table which will be initialized by firmware. -In future, A CSV guest should get CPUID value from a CPUID table -which has been validated by firmware rather than requesting them from -hypervisor via a VMGEXIT. - -Signed-off-by: Xin Jiang -Change-Id: Ic09af8667c65ac83eef5a2a4a1e69d0506cd89d7 ---- - OvmfPkg/OvmfPkg.dec | 4 ++++ - OvmfPkg/OvmfPkgX64.fdf | 3 +++ - OvmfPkg/PlatformPei/Csv.c | 6 ++++++ - OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++ - OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 15 +++++++++++++++ - OvmfPkg/ResetVector/ResetVector.inf | 2 ++ - OvmfPkg/ResetVector/ResetVector.nasmb | 2 ++ - 7 files changed, 34 insertions(+) - -diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec -index d8f9be3..7e6a6a2 100644 ---- a/OvmfPkg/OvmfPkg.dec -+++ b/OvmfPkg/OvmfPkg.dec -@@ -359,6 +359,10 @@ - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|0|UINT32|0x58 - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize|0|UINT32|0x59 - -+ ## the base address of the cpuid table page used by CSV. -+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|0|UINT32|0x60 -+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize|0|UINT32|0x61 -+ - [PcdsDynamic, PcdsDynamicEx] - gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 -diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf -index 0f04acb..04efa62 100644 ---- a/OvmfPkg/OvmfPkgX64.fdf -+++ b/OvmfPkg/OvmfPkgX64.fdf -@@ -91,6 +91,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.P - 0x00D000|0x002000 - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize - -+0x00F000|0x001000 -+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize -+ - 0x010000|0x010000 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize - -diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c -index 44e81e1..f7c87ac 100644 ---- a/OvmfPkg/PlatformPei/Csv.c -+++ b/OvmfPkg/PlatformPei/Csv.c -@@ -56,6 +56,12 @@ CsvInitializeMemInfo ( - (UINT64)(UINTN) FixedPcdGet32 (PcdCsvDefaultSecureCallSize), - EfiReservedMemoryType - ); -+ -+ BuildMemoryAllocationHob ( -+ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdOvmfCsvCpuidBase), -+ (UINT64)(UINTN) FixedPcdGet32 (PcdOvmfCsvCpuidSize), -+ EfiReservedMemoryType -+ ); - } - - VOID -diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf -index cb0582c..bed4dcf 100644 ---- a/OvmfPkg/PlatformPei/PlatformPei.inf -+++ b/OvmfPkg/PlatformPei/PlatformPei.inf -@@ -123,6 +123,8 @@ - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize -+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize - - [FeaturePcd] - gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable -diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm -index c32b608..f282692 100644 ---- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm -+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm -@@ -63,6 +63,21 @@ csvSecureCallBase: - DB 0xAB, 0x21, 0x6B, 0x27, 0x5D, 0x55, 0x56, 0xA5 - csvSecureCallEnd: - -+; -+; CSV cpuid table -+; -+; Provide cpuid table page when boot up for CSV guest -+; -+; GUID : 1b4c70e6-07e6-4e4e-8f28-0eaf871a0752 -+; -+csvCpuidTableBase: -+ DD CSV_CPUID_TABLE_SIZE -+ DD CSV_CPUID_TABLE_BASE -+ DW csvCpuidTableEnd - csvCpuidTableBase -+ DB 0xE6, 0x70, 0x4C, 0x1B, 0xE6, 0x07, 0x4E, 0x4E -+ DB 0x8F, 0x28, 0x0E, 0xAF, 0x87, 0x1A, 0x07, 0x52 -+csvCpuidTableEnd: -+ - ; - ; TDX Metadata offset block - ; -diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf -index 38c1720..e35c17b 100644 ---- a/OvmfPkg/ResetVector/ResetVector.inf -+++ b/OvmfPkg/ResetVector/ResetVector.inf -@@ -37,6 +37,8 @@ - gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize -+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase -diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb -index ca00f64..4e7c7ad 100644 ---- a/OvmfPkg/ResetVector/ResetVector.nasmb -+++ b/OvmfPkg/ResetVector/ResetVector.nasmb -@@ -106,6 +106,8 @@ - - %define CSV_DEFAULT_SECURE_CALL_BASE FixedPcdGet32 (PcdCsvDefaultSecureCallBase) - %define CSV_DEFAULT_SECURE_CALL_SIZE FixedPcdGet32 (PcdCsvDefaultSecureCallSize) -+ %define CSV_CPUID_TABLE_BASE FixedPcdGet32 (PcdOvmfCsvCpuidBase) -+ %define CSV_CPUID_TABLE_SIZE FixedPcdGet32 (PcdOvmfCsvCpuidSize) - - %include "X64/IntelTdxMetadata.asm" - %include "Ia32/Flat32ToFlat64.asm" --- -2.17.1 - diff --git a/0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch b/0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch deleted file mode 100644 index a8c2c34..0000000 --- a/0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch +++ /dev/null @@ -1,325 +0,0 @@ -From 118d8bd819dfd2300798481d8c89a9c37e54a32c Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Thu, 19 Aug 2021 12:35:50 +0000 -Subject: [PATCH 39/46] OvmfPkg/BaseMemEncryptLib: Detect SEV live migration - feature. - -Add support to check if we are running inside KVM HVM and -KVM HVM supports SEV Live Migration feature. - -Cc: Jordan Justen -Cc: Ard Biesheuvel -Signed-off-by: Ashish Kalra -Change-Id: I29fa5047198c9c3c6965c36b5e221b48c277dfc9 ---- - OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 ++++ - .../DxeMemEncryptSevLibInternal.c | 41 +++++++++++++ - .../PeiDxeMemEncryptSevLibInternal.c | 57 +++++++++++++++++++ - .../PeiDxeMemEncryptSevLibInternal.h | 31 ++++++++++ - .../PeiMemEncryptSevLibInternal.c | 41 +++++++++++++ - .../SecMemEncryptSevLibInternal.c | 18 ++++++ - 6 files changed, 200 insertions(+) - create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h - -diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h -index adc490e..ea251f1 100644 ---- a/OvmfPkg/Include/Library/MemEncryptSevLib.h -+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h -@@ -71,6 +71,18 @@ MemEncryptSevIsEnabled ( - VOID - ); - -+/** -+ Returns a boolean to indicate whether SEV live migration is enabled. -+ -+ @retval TRUE SEV live migration is enabled -+ @retval FALSE SEV live migration is not enabled -+**/ -+BOOLEAN -+EFIAPI -+MemEncryptSevLiveMigrationIsEnabled ( -+ VOID -+ ); -+ - /** - This function clears memory encryption bit for the memory region specified by - BaseAddress and NumPages from the current page table context. -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c -index 2816f85..df73a83 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c -@@ -17,9 +17,13 @@ - #include - #include - -+#include "PeiDxeMemEncryptSevLibInternal.h" -+ - STATIC BOOLEAN mSevStatus = FALSE; - STATIC BOOLEAN mSevEsStatus = FALSE; - STATIC BOOLEAN mSevStatusChecked = FALSE; -+STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; -+STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; - - STATIC UINT64 mSevEncryptionMask = 0; - STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; -@@ -106,6 +110,24 @@ MemEncryptSevEsIsEnabled ( - return mSevEsStatus; - } - -+/** -+ Figures out if we are running inside KVM HVM and -+ KVM HVM supports SEV Live Migration feature. -+**/ -+STATIC -+VOID -+EFIAPI -+InternalDetectSevLiveMigrationFeature ( -+ VOID -+ ) -+{ -+ if (KvmDetectSevLiveMigrationFeature ()) { -+ mSevLiveMigrationStatus = TRUE; -+ } -+ -+ mSevLiveMigrationStatusChecked = TRUE; -+} -+ - /** - Returns a boolean to indicate whether SEV is enabled. - -@@ -125,6 +147,25 @@ MemEncryptSevIsEnabled ( - return mSevStatus; - } - -+/** -+ Returns a boolean to indicate whether SEV live migration is enabled. -+ -+ @retval TRUE SEV live migration is enabled -+ @retval FALSE SEV live migration is not enabled -+**/ -+BOOLEAN -+EFIAPI -+MemEncryptSevLiveMigrationIsEnabled ( -+ VOID -+ ) -+{ -+ if (!mSevLiveMigrationStatusChecked) { -+ InternalDetectSevLiveMigrationFeature (); -+ } -+ -+ return mSevLiveMigrationStatus; -+} -+ - /** - Returns the SEV encryption mask. - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c -index b4a9f46..30f2d90 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c -@@ -16,6 +16,8 @@ - #include - #include - -+#include "PeiDxeMemEncryptSevLibInternal.h" -+ - /** - Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM - Save State Map. -@@ -61,3 +63,58 @@ MemEncryptSevLocateInitialSmramSaveStateMapPages ( - - return RETURN_SUCCESS; - } -+ -+/** -+ Figures out if we are running inside KVM HVM and -+ KVM HVM supports SEV Live Migration feature. -+ -+ @retval TRUE SEV live migration is supported. -+ @retval FALSE SEV live migration is not supported. -+**/ -+BOOLEAN -+EFIAPI -+KvmDetectSevLiveMigrationFeature ( -+ VOID -+ ) -+{ -+ CHAR8 Signature[13]; -+ UINT32 mKvmLeaf; -+ UINT32 RegEax; -+ UINT32 RegEbx; -+ UINT32 RegEcx; -+ UINT32 RegEdx; -+ -+ Signature[12] = '\0'; -+ for (mKvmLeaf = 0x40000000; mKvmLeaf < 0x40010000; mKvmLeaf += 0x100) { -+ AsmCpuid ( -+ mKvmLeaf, -+ NULL, -+ (UINT32 *) &Signature[0], -+ (UINT32 *) &Signature[4], -+ (UINT32 *) &Signature[8]); -+ -+ if (AsciiStrCmp (Signature, "KVMKVMKVM") == 0) { -+ DEBUG (( -+ DEBUG_INFO, -+ "%a: KVM Detected, signature = %a\n", -+ __FUNCTION__, -+ Signature -+ )); -+ -+ RegEax = mKvmLeaf + 1; -+ RegEcx = 0; -+ AsmCpuid (mKvmLeaf + 1, &RegEax, &RegEbx, &RegEcx, &RegEdx); -+ if ((RegEax & KVM_FEATURE_MIGRATION_CONTROL) != 0) { -+ DEBUG (( -+ DEBUG_INFO, -+ "%a: SEV Live Migration feature supported\n", -+ __FUNCTION__ -+ )); -+ -+ return TRUE; -+ } -+ } -+ } -+ -+ return FALSE; -+} -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h -new file mode 100644 -index 0000000..30cf5de ---- /dev/null -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h -@@ -0,0 +1,31 @@ -+/** @file -+ -+ Secure Encrypted Virtualization (SEV) library helper function -+ -+ Copyright (c) 2021, AMD Incorporated. All rights reserved.
-+ -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+ -+**/ -+ -+#ifndef PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_ -+#define PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_ -+ -+#include -+ -+#define KVM_FEATURE_MIGRATION_CONTROL BIT17 -+ -+/** -+ Figures out if we are running inside KVM HVM and -+ KVM HVM supports SEV Live Migration feature. -+ -+ @retval TRUE SEV live migration is supported. -+ @retval FALSE SEV live migration is not supported. -+**/ -+BOOLEAN -+EFIAPI -+KvmDetectSevLiveMigrationFeature( -+ VOID -+ ); -+ -+#endif // PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_ -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c -index e2fd109..9293b56 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c -@@ -17,9 +17,13 @@ - #include - #include - -+#include "PeiDxeMemEncryptSevLibInternal.h" -+ - STATIC BOOLEAN mSevStatus = FALSE; - STATIC BOOLEAN mSevEsStatus = FALSE; - STATIC BOOLEAN mSevStatusChecked = FALSE; -+STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; -+STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; - - STATIC UINT64 mSevEncryptionMask = 0; - STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; -@@ -87,6 +91,24 @@ InternalMemEncryptSevStatus ( - mSevStatusChecked = TRUE; - } - -+/** -+ Figures out if we are running inside KVM HVM and -+ KVM HVM supports SEV Live Migration feature. -+**/ -+STATIC -+VOID -+EFIAPI -+InternalDetectSevLiveMigrationFeature ( -+ VOID -+ ) -+{ -+ if (KvmDetectSevLiveMigrationFeature ()) { -+ mSevLiveMigrationStatus = TRUE; -+ } -+ -+ mSevLiveMigrationStatusChecked = TRUE; -+} -+ - /** - Returns a boolean to indicate whether SEV-ES is enabled. - -@@ -125,6 +147,25 @@ MemEncryptSevIsEnabled ( - return mSevStatus; - } - -+/** -+ Returns a boolean to indicate whether SEV live migration is enabled. -+ -+ @retval TRUE SEV live migration is enabled -+ @retval FALSE SEV live migration is not enabled -+**/ -+BOOLEAN -+EFIAPI -+MemEncryptSevLiveMigrationIsEnabled ( -+ VOID -+ ) -+{ -+ if (!mSevLiveMigrationStatusChecked) { -+ InternalDetectSevLiveMigrationFeature (); -+ } -+ -+ return mSevLiveMigrationStatus; -+} -+ - /** - Returns the SEV encryption mask. - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c -index 56d8f3f..d9f7bef 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c -@@ -100,6 +100,24 @@ MemEncryptSevIsEnabled ( - return Msr.Bits.SevBit ? TRUE : FALSE; - } - -+/** -+ Returns a boolean to indicate whether SEV live migration is enabled. -+ -+ @retval TRUE SEV live migration is enabled -+ @retval FALSE SEV live migration is not enabled -+**/ -+BOOLEAN -+EFIAPI -+MemEncryptSevLiveMigrationIsEnabled ( -+ VOID -+ ) -+{ -+ // -+ // Not used in SEC phase. -+ // -+ return FALSE; -+} -+ - /** - Returns the SEV encryption mask. - --- -2.17.1 - diff --git a/0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch b/0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch deleted file mode 100644 index 205c5b1..0000000 --- a/0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch +++ /dev/null @@ -1,298 +0,0 @@ -From f622069729e0abc9b676af25a90b9e142419cf1a Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Thu, 19 Aug 2021 13:03:00 +0000 -Subject: [PATCH 40/46] OvmfPkg/BaseMemEncryptLib: Hypercall API for page - encryption state change - -Add API to issue hypercall on page encryption state change. - -By default all the SEV guest memory regions are considered encrypted, -if a guest changes the encryption attribute of the page (e.g mark a -page as decrypted) then notify hypervisor. Hypervisor will need to -track the unencrypted pages. The information will be used during -guest live migration, guest page migration and guest debugging. - -This hypercall is used to notify hypervisor when the page's -encryption state changes. - -Cc: Jordan Justen -Cc: Ard Biesheuvel -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -Change-Id: Ic0dcf854947f35f633137d2bb052dc79d111971f ---- - OvmfPkg/Include/Library/MemEncryptSevLib.h | 52 +++++++++++++++ - .../DxeMemEncryptSevLib.inf | 1 + - .../Ia32/MemEncryptSevLib.c | 27 ++++++++ - .../PeiMemEncryptSevLib.inf | 1 + - .../SecMemEncryptSevLibInternal.c | 20 ++++++ - .../X64/AsmHelperStub.nasm | 33 ++++++++++ - .../X64/MemEncryptSevLib.c | 64 +++++++++++++++++++ - 7 files changed, 198 insertions(+) - create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm - -diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h -index ea251f1..8ed6242 100644 ---- a/OvmfPkg/Include/Library/MemEncryptSevLib.h -+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h -@@ -215,4 +215,56 @@ MemEncryptSevClearMmioPageEncMask ( - IN UINTN NumPages - ); - -+/** -+ This hypercall is used to notify hypervisor when the page's encryption -+ state changes. -+ -+ @param[in] PhysicalAddress The physical address that is the start address -+ of a memory region. -+ @param[in] Pages Number of pages in memory region. -+ @param[in] IsEncrypted Encrypted or Decrypted. -+ -+ @retval RETURN_SUCCESS Hypercall returned success. -+ @retval RETURN_UNSUPPORTED Hypercall not supported. -+ @retval RETURN_NO_MAPPING Hypercall returned error. -+**/ -+RETURN_STATUS -+EFIAPI -+SetMemoryEncDecHypercall3 ( -+ IN UINTN PhysicalAddress, -+ IN UINTN Pages, -+ IN BOOLEAN IsEncrypted -+ ); -+ -+#define KVM_HC_MAP_GPA_RANGE 12 -+#define KVM_MAP_GPA_RANGE_PAGE_SZ_4K 0 -+#define KVM_MAP_GPA_RANGE_PAGE_SZ_2M BIT0 -+#define KVM_MAP_GPA_RANGE_PAGE_SZ_1G BIT1 -+#define KVM_MAP_GPA_RANGE_ENC_STATE(n) ((n) << 4) -+#define KVM_MAP_GPA_RANGE_ENCRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(1) -+#define KVM_MAP_GPA_RANGE_DECRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(0) -+ -+/** -+ Interface exposed by the ASM implementation of the core hypercall -+ -+ @param[in] HypercallNum KVM_HC_MAP_GPA_RANGE hypercall. -+ @param[in] PhysicalAddress The physical address that is the start address -+ of a memory region. -+ @param[in] Pages Number of pages in memory region. -+ @param[in] Attributes Bits 3:0 - preferred page size encoding, -+ 0 = 4kb, 1 = 2mb, 2 = 1gb, etc... -+ Bit 4 - plaintext = 0, encrypted = 1 -+ Bits 63:5 - reserved (must be zero) -+ -+ @retval Hypercall returned status. -+**/ -+UINTN -+EFIAPI -+SetMemoryEncDecHypercall3AsmStub ( -+ IN UINTN HypercallNum, -+ IN UINTN PhysicalAddress, -+ IN UINTN Pages, -+ IN UINTN Attributes -+ ); -+ - #endif // _MEM_ENCRYPT_SEV_LIB_H_ -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -index dc32929..8ea8d3a 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -@@ -38,6 +38,7 @@ - X64/PeiDxeVirtualMemory.c - X64/VirtualMemory.c - X64/VirtualMemory.h -+ X64/AsmHelperStub.nasm - - [Sources.IA32] - Ia32/MemEncryptSevLib.c -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c -index be260e0..516d639 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c -@@ -136,3 +136,30 @@ MemEncryptSevClearMmioPageEncMask ( - // - return RETURN_UNSUPPORTED; - } -+ -+/** -+ This hyercall is used to notify hypervisor when the page's encryption -+ state changes. -+ -+ @param[in] PhysicalAddress The physical address that is the start address -+ of a memory region. -+ @param[in] Pages Number of Pages in the memory region. -+ @param[in] IsEncrypted Encrypted or Decrypted. -+ -+ @retval RETURN_SUCCESS Hypercall returned success. -+ @retval RETURN_UNSUPPORTED Hypercall not supported. -+ @retval RETURN_NO_MAPPING Hypercall returned error. -+**/ -+RETURN_STATUS -+EFIAPI -+SetMemoryEncDecHypercall3 ( -+ IN UINTN PhysicalAddress, -+ IN UINTN Pages, -+ IN BOOLEAN IsEncrypted -+ ) -+{ -+ // -+ // Memory encryption bit is not accessible in 32-bit mode -+ // -+ return RETURN_UNSUPPORTED; -+} -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf -index 03a78c3..3233ca7 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf -@@ -38,6 +38,7 @@ - X64/PeiDxeVirtualMemory.c - X64/VirtualMemory.c - X64/VirtualMemory.h -+ X64/AsmHelperStub.nasm - - [Sources.IA32] - Ia32/MemEncryptSevLib.c -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c -index d9f7bef..ebb1c39 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c -@@ -118,6 +118,26 @@ MemEncryptSevLiveMigrationIsEnabled ( - return FALSE; - } - -+/** -+ Interface exposed by the ASM implementation of the core hypercall -+ -+ @retval Hypercall returned status. -+**/ -+UINTN -+EFIAPI -+SetMemoryEncDecHypercall3AsmStub ( -+ IN UINTN HypercallNum, -+ IN UINTN PhysicalAddress, -+ IN UINTN Pages, -+ IN UINTN Attributes -+ ) -+{ -+ // -+ // Not used in SEC phase. -+ // -+ return RETURN_UNSUPPORTED; -+} -+ - /** - Returns the SEV encryption mask. - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm -new file mode 100644 -index 0000000..0ec35dd ---- /dev/null -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm -@@ -0,0 +1,33 @@ -+/** @file -+ -+ ASM helper stub to invoke hypercall -+ -+ Copyright (c) 2021, AMD Incorporated. All rights reserved.
-+ -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+ -+**/ -+ -+DEFAULT REL -+SECTION .text -+ -+; UINTN -+; EFIAPI -+; SetMemoryEncDecHypercall3AsmStub ( -+; IN UINTN HypercallNum, -+; IN UINTN Arg1, -+; IN UINTN Arg2, -+; IN UINTN Arg3 -+; ); -+global ASM_PFX(SetMemoryEncDecHypercall3AsmStub) -+ASM_PFX(SetMemoryEncDecHypercall3AsmStub): -+ ; UEFI calling conventions require RBX to -+ ; be nonvolatile/callee-saved. -+ push rbx -+ mov rax, rcx ; Copy HypercallNumber to rax -+ mov rbx, rdx ; Copy Arg1 to the register expected by KVM -+ mov rcx, r8 ; Copy Arg2 to register expected by KVM -+ mov rdx, r9 ; Copy Arg3 to register expected by KVM -+ vmmcall ; Call VMMCALL -+ pop rbx -+ ret -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c -index a57e8fd..a6246d4 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c -@@ -143,3 +143,67 @@ MemEncryptSevClearMmioPageEncMask ( - ); - - } -+ -+/** -+ This hyercall is used to notify hypervisor when the page's encryption -+ state changes. -+ -+ @param[in] PhysicalAddress The physical address that is the start address -+ of a memory region. -+ @param[in] Pages Number of Pages in the memory region. -+ @param[in] IsEncrypted Encrypted or Decrypted. -+ -+ @retval RETURN_SUCCESS Hypercall returned success. -+ @retval RETURN_UNSUPPORTED Hypercall not supported. -+ @retval RETURN_NO_MAPPING Hypercall returned error. -+**/ -+RETURN_STATUS -+EFIAPI -+SetMemoryEncDecHypercall3 ( -+ IN UINTN PhysicalAddress, -+ IN UINTN Pages, -+ IN BOOLEAN IsEncrypted -+ ) -+{ -+ RETURN_STATUS Ret; -+ UINTN Error; -+ UINTN EncryptState; -+ -+ Ret = RETURN_UNSUPPORTED; -+ -+ if (MemEncryptSevLiveMigrationIsEnabled ()) { -+ Ret = RETURN_SUCCESS; -+ // -+ // The encryption bit is set/clear on the smallest page size, hence -+ // use the 4k page size in MAP_GPA_RANGE hypercall below. -+ // -+ // Also, when the GCD map is being walked and the c-bit being cleared -+ // from MMIO and NonExistent memory spaces, the physical address -+ // range being passed may not be page-aligned and adding an assert -+ // here prevents booting. Hence, rounding it down when calling -+ // SetMemoryEncDecHypercall3AsmStub below. -+ // -+ -+ EncryptState = IsEncrypted ? KVM_MAP_GPA_RANGE_ENCRYPTED : -+ KVM_MAP_GPA_RANGE_DECRYPTED; -+ -+ Error = SetMemoryEncDecHypercall3AsmStub ( -+ KVM_HC_MAP_GPA_RANGE, -+ PhysicalAddress & ~EFI_PAGE_MASK, -+ Pages, -+ KVM_MAP_GPA_RANGE_PAGE_SZ_4K | EncryptState -+ ); -+ -+ if (Error != 0) { -+ DEBUG ((DEBUG_ERROR, -+ "SetMemoryEncDecHypercall3 failed, Phys = %x, Pages = %d, Err = %Ld\n", -+ PhysicalAddress, -+ Pages, -+ (INT64)Error)); -+ -+ Ret = RETURN_NO_MAPPING; -+ } -+ } -+ -+ return Ret; -+} --- -2.17.1 - diff --git a/0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch b/0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch deleted file mode 100644 index 1c865a3..0000000 --- a/0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch +++ /dev/null @@ -1,91 +0,0 @@ -From ee0ca422f17da55350c4da25ef9ca38127d79e3f Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Thu, 19 Aug 2021 13:04:56 +0000 -Subject: [PATCH 41/46] OvmfPkg/BaseMemEncryptLib: Invoke page encryption state - change hypercall - -Invoke the hypercall API to notify hypervisor when the page's -encryption state changes. - -Cc: Jordan Justen -Cc: Ard Biesheuvel -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -Change-Id: Ia61155777fe3bf66f1d059978c0e8b1d1c833ef7 ---- - .../X64/PeiDxeVirtualMemory.c | 20 +++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -index 6726010..0b67577 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -@@ -582,10 +582,13 @@ SetMemoryEncDec ( - PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; - PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; - PAGE_TABLE_ENTRY *PageDirectory2MEntry; -+ PHYSICAL_ADDRESS OrigPhysicalAddress; - PAGE_TABLE_4K_ENTRY *PageTableEntry; - UINT64 PgTableMask; - UINT64 AddressEncMask; - BOOLEAN IsWpEnabled; -+ BOOLEAN CBitChanged; -+ UINTN OrigLength; - RETURN_STATUS Status; - PHYSICAL_ADDRESS PageAddress; - UINTN PageNum; -@@ -642,6 +645,9 @@ SetMemoryEncDec ( - } - - Status = EFI_SUCCESS; -+ OrigLength = Length; -+ CBitChanged = FALSE; -+ OrigPhysicalAddress = PhysicalAddress; - - while (Length != 0) - { -@@ -702,6 +708,7 @@ SetMemoryEncDec ( - )); - PhysicalAddress += BIT30; - Length -= BIT30; -+ CBitChanged = TRUE; - } else { - // - // We must split the page -@@ -756,6 +763,7 @@ SetMemoryEncDec ( - SetOrClearCBit (&PageDirectory2MEntry->Uint64, Mode); - PhysicalAddress += BIT21; - Length -= BIT21; -+ CBitChanged = TRUE; - } else { - // - // We must split up this page into 4K pages -@@ -798,6 +806,7 @@ SetMemoryEncDec ( - SetOrClearCBit (&PageTableEntry->Uint64, Mode); - PhysicalAddress += EFI_PAGE_SIZE; - Length -= EFI_PAGE_SIZE; -+ CBitChanged = TRUE; - } - } - } -@@ -815,6 +824,17 @@ SetMemoryEncDec ( - // - CpuFlushTlb(); - -+ // -+ // Notify Hypervisor on C-bit status -+ // -+ if (CBitChanged) { -+ Status = SetMemoryEncDecHypercall3 ( -+ OrigPhysicalAddress, -+ EFI_SIZE_TO_PAGES (OrigLength), -+ (Mode == SetCBit) ? TRUE : FALSE -+ ); -+ } -+ - Done: - // - // Restore page table write protection, if any. --- -2.17.1 - diff --git a/0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch b/0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch deleted file mode 100644 index c37eb4a..0000000 --- a/0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch +++ /dev/null @@ -1,46 +0,0 @@ -From b9e68850125194c9c183a0ab2239a6c73b1d67c3 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Thu, 19 Aug 2021 13:06:40 +0000 -Subject: [PATCH 42/46] OvmfPkg/VmgExitLib: Encryption state change hypercall - support in VC handler - -Make the #VC handler aware of the page encryption state -change hypercall by adding support to check KVM_HC_MAP_GPA_RANGE -hypercall and add the additional register values used by -hypercall in the GHCB. - -Cc: Jordan Justen -Cc: Ard Biesheuvel -Signed-off-by: Ashish Kalra -Change-Id: Iaab77f063455837393f290ee80962e6f3d2f5593 ---- - OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c -index 41b0c8c..2d06343 100644 ---- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c -+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c -@@ -1171,6 +1171,19 @@ VmmCallExit ( - Ghcb->SaveArea.Cpl = (UINT8) (Regs->Cs & 0x3); - VmgSetOffsetValid (Ghcb, GhcbCpl); - -+ if (Regs->Rax == KVM_HC_MAP_GPA_RANGE) { -+ // -+ // KVM_HC_MAP_GPA_RANGE hypercall requires these -+ // extra registers. -+ // -+ Ghcb->SaveArea.Rbx = Regs->Rbx; -+ VmgSetOffsetValid (Ghcb, GhcbRbx); -+ Ghcb->SaveArea.Rcx = Regs->Rcx; -+ VmgSetOffsetValid (Ghcb, GhcbRcx); -+ Ghcb->SaveArea.Rdx = Regs->Rdx; -+ VmgSetOffsetValid (Ghcb, GhcbRdx); -+ } -+ - Status = VmgExit (Ghcb, SVM_EXIT_VMMCALL, 0, 0); - if (Status != 0) { - return Status; --- -2.17.1 - diff --git a/0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch b/0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch deleted file mode 100644 index dd2ca14..0000000 --- a/0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 4f2273d02335039e85d8b47b1e43715e3db86c33 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Thu, 19 Aug 2021 13:09:07 +0000 -Subject: [PATCH 43/46] OvmfPkg/PlatformPei: Mark SEC GHCB page as unencrypted - via hypercall - -Mark the SEC GHCB page (that is mapped as unencrypted in -ResetVector code) in the hypervisor's guest page encryption -state tracking. - -Cc: Jordan Justen -Cc: Ard Biesheuvel -Signed-off-by: Ashish Kalra -Change-Id: Iedcde6367e12106e44e0cb1cc07a4ed386f67c19 ---- - OvmfPkg/PlatformPei/AmdSev.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c -index a8bf610..1d38056 100644 ---- a/OvmfPkg/PlatformPei/AmdSev.c -+++ b/OvmfPkg/PlatformPei/AmdSev.c -@@ -52,6 +52,17 @@ AmdSevEsInitialize ( - PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE); - ASSERT_RETURN_ERROR (PcdStatus); - -+ // -+ // The SEC Ghcb setup during reset-vector needs to be marked as -+ // decrypted in the hypervisor's guest page encryption state -+ // tracking. -+ // -+ SetMemoryEncDecHypercall3 ( -+ FixedPcdGet32 (PcdOvmfSecGhcbBase), -+ EFI_SIZE_TO_PAGES(FixedPcdGet32 (PcdOvmfSecGhcbSize)), -+ FALSE -+ ); -+ - // - // Allocate GHCB and per-CPU variable pages. - // Since the pages must survive across the UEFI to OS transition --- -2.17.1 - diff --git a/0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch b/0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch deleted file mode 100644 index edb8b39..0000000 --- a/0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch +++ /dev/null @@ -1,185 +0,0 @@ -From f751df6533d370a14412fab4850ad05ce99b7b85 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Thu, 19 Aug 2021 13:14:31 +0000 -Subject: [PATCH 44/46] OvmfPkg/AmdSevDxe: Add support for SEV live migration. - -Check for SEV live migration feature support, if detected -setup a new UEFI enviroment variable to indicate OVMF -support for SEV live migration. - -This environment variable is created by UEFI but consumed -by the (guest) linux kernel. This is actually part of a -3-way negotiation of the live migration feature between -hypervisor, guest OVMF and guest kernel. Host indicates -support for live migration, which is detected by OVMF -and correspondingly OVMF sets this SetLiveMigrationEnabled -UEFI variable, which is read by the guest kernel and it -indicates to the guest kernel that both host and OVMF -support and have enabled the live migration feature. - -The new runtime UEFI environment variable is set via the -notification function registered for the -EFI_END_OF_DXE_EVENT_GROUP_GUID event in AmdSevDxe driver. - -AmdSevDxe module is an apriori driver so it gets loaded between PEI -and DXE phases and the SetVariable call will fail at the driver's -entry point as the Variable DXE module is still not loaded yet. -So we need to wait for an event notification which is signaled -after the Variable DXE module is loaded, hence, using the -EndOfDxe event notification to make this call. - -Signed-off-by: Ashish Kalra -Change-Id: Iff6eee8f56fd60d1aedf48a5253b7b09e9aa9c7e ---- - OvmfPkg/AmdSevDxe/AmdSevDxe.c | 64 ++++++++++++++++++++++ - OvmfPkg/AmdSevDxe/AmdSevDxe.inf | 4 ++ - OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h | 20 +++++++ - OvmfPkg/OvmfPkg.dec | 1 + - 4 files changed, 89 insertions(+) - create mode 100644 OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h - -diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c -index c66c4e9..0750949 100644 ---- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c -+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c -@@ -15,10 +15,47 @@ - #include - #include - #include -+#include - #include - #include -+#include -+#include -+#include - #include - -+STATIC -+VOID -+EFIAPI -+AmdSevDxeOnEndOfDxe ( -+ IN EFI_EVENT Event, -+ IN VOID *EventToSignal -+ ) -+{ -+ EFI_STATUS Status; -+ BOOLEAN SevLiveMigrationEnabled; -+ -+ SevLiveMigrationEnabled = MemEncryptSevLiveMigrationIsEnabled (); -+ -+ if (SevLiveMigrationEnabled) { -+ Status = gRT->SetVariable ( -+ L"SevLiveMigrationEnabled", -+ &gAmdSevMemEncryptGuid, -+ EFI_VARIABLE_NON_VOLATILE | -+ EFI_VARIABLE_BOOTSERVICE_ACCESS | -+ EFI_VARIABLE_RUNTIME_ACCESS, -+ sizeof SevLiveMigrationEnabled, -+ &SevLiveMigrationEnabled -+ ); -+ -+ DEBUG (( -+ DEBUG_INFO, -+ "%a: Setting SevLiveMigrationEnabled variable, status = %lx\n", -+ __FUNCTION__, -+ Status -+ )); -+ } -+} -+ - EFI_STATUS - EFIAPI - AmdSevDxeEntryPoint ( -@@ -30,6 +67,7 @@ AmdSevDxeEntryPoint ( - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *AllDescMap; - UINTN NumEntries; - UINTN Index; -+ EFI_EVENT Event; - - // - // Do nothing when SEV is not enabled -@@ -130,5 +168,31 @@ AmdSevDxeEntryPoint ( - } - } - -+ // -+ // AmdSevDxe module is an apriori driver so it gets loaded between PEI -+ // and DXE phases and the SetVariable call will fail at the driver's -+ // entry point as the Variable DXE module is still not loaded yet. -+ // So we need to wait for an event notification which is signaled -+ // after the Variable DXE module is loaded, hence, using the -+ // EndOfDxe event notification to make this call. -+ // -+ // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event. -+ // The notification function sets the runtime variable indicating OVMF -+ // support for SEV live migration. -+ // -+ Status = gBS->CreateEventEx ( -+ EVT_NOTIFY_SIGNAL, -+ TPL_CALLBACK, -+ AmdSevDxeOnEndOfDxe, -+ NULL, -+ &gEfiEndOfDxeEventGroupGuid, -+ &Event -+ ); -+ -+ if (EFI_ERROR (Status)) { -+ DEBUG ((DEBUG_ERROR, "%a: CreateEventEx(): %r\n", -+ __FUNCTION__, Status)); -+ } -+ - return EFI_SUCCESS; - } -diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf -index 0676fcc..2ad1fb8 100644 ---- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf -+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf -@@ -45,3 +45,7 @@ - - [Pcd] - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId -+ -+[Guids] -+ gAmdSevMemEncryptGuid -+ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event -diff --git a/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h -new file mode 100644 -index 0000000..1c948fb ---- /dev/null -+++ b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h -@@ -0,0 +1,20 @@ -+/** @file -+ -+ AMD Memory Encryption GUID, define a new GUID for defining -+ new UEFI environment variables assocaiated with SEV Memory Encryption. -+ -+ Copyright (c) 2021, AMD Inc. All rights reserved.
-+ -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+ -+**/ -+ -+#ifndef __AMD_SEV_MEMENCRYPT_LIB_H__ -+#define __AMD_SEV_MEMENCRYPT_LIB_H__ -+ -+#define AMD_SEV_MEMENCRYPT_GUID \ -+{0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}} -+ -+extern EFI_GUID gAmdSevMemEncryptGuid; -+ -+#endif -diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec -index 7e6a6a2..b6f88e0 100644 ---- a/OvmfPkg/OvmfPkg.dec -+++ b/OvmfPkg/OvmfPkg.dec -@@ -128,6 +128,7 @@ - gQemuKernelLoaderFsMediaGuid = {0x1428f772, 0xb64a, 0x441e, {0xb8, 0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}} - gGrubFileGuid = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}} - gConfidentialComputingSecretGuid = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}} -+ gAmdSevMemEncryptGuid = {0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}} - - [Ppis] - # PPI whose presence in the PPI database signals that the TPM base address --- -2.17.1 - diff --git a/0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch b/0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch deleted file mode 100644 index d152d63..0000000 --- a/0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 1f244d5fec68cbd76fd902819d906c5222577a69 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Mon, 17 Jan 2022 01:19:21 -0500 -Subject: [PATCH 45/46] anolis: OvmfPkg/BaseMemcryptSevLib: Correct the - calculation of page range that notified to hypervisor - -Correct the calculation of page range that notified to hypervisor. - -Change-Id: Ie2ac4a4e894095ea9ae3b1d44afed04681b9d491 ---- - .../Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -index 0b67577..4dbf829 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c -@@ -828,9 +828,13 @@ SetMemoryEncDec ( - // Notify Hypervisor on C-bit status - // - if (CBitChanged) { -+ UINTN StartPfn = OrigPhysicalAddress >> EFI_PAGE_SHIFT; -+ UINTN EndPfn = (OrigPhysicalAddress + OrigLength + -+ ((1 << EFI_PAGE_SHIFT) - 1)) >> EFI_PAGE_SHIFT; -+ - Status = SetMemoryEncDecHypercall3 ( - OrigPhysicalAddress, -- EFI_SIZE_TO_PAGES (OrigLength), -+ (EndPfn - StartPfn), - (Mode == SetCBit) ? TRUE : FALSE - ); - } --- -2.17.1 - diff --git a/0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch b/0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch deleted file mode 100644 index 5da0f2b..0000000 --- a/0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 901330a9161de852bf99ad7b2c629bae00af2b7a Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Sun, 19 Jun 2022 18:12:35 +0800 -Subject: [PATCH 46/46] anolis: OvmfPkg/BaseMemEncryptLib: Return SUCCESS if - not support SEV live migration - -Add this change to avoid trigger 'ASSERT_EFI_ERROR (Status = Unsupported)' -when QEMU doesn't support SEV live migration. - -Change-Id: I48066d6cf1b4357c984496bcb6450be4d35b7e16 ---- - OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c -index a6246d4..e50231c 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c -@@ -169,10 +169,12 @@ SetMemoryEncDecHypercall3 ( - UINTN Error; - UINTN EncryptState; - -- Ret = RETURN_UNSUPPORTED; -+ // -+ // Return success if not support migration. -+ // -+ Ret = RETURN_SUCCESS; - - if (MemEncryptSevLiveMigrationIsEnabled ()) { -- Ret = RETURN_SUCCESS; - // - // The encryption bit is set/clear on the smallest page size, hence - // use the 4k page size in MAP_GPA_RANGE hypercall below. --- -2.17.1 - diff --git a/dist b/dist deleted file mode 100644 index 9c0e36e..0000000 --- a/dist +++ /dev/null @@ -1 +0,0 @@ -an8 diff --git a/edk2-SecurityPkg-DxeImageVerificationLib-Check-result-of-.patch b/edk2-SecurityPkg-DxeImageVerificationLib-Check-result-of-.patch new file mode 100644 index 0000000..e2d7ed3 --- /dev/null +++ b/edk2-SecurityPkg-DxeImageVerificationLib-Check-result-of-.patch @@ -0,0 +1,109 @@ +From bb0f29580825e60a5dc5c67e260dd20258eb71b0 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Wed, 29 Mar 2023 11:52:52 -0400 +Subject: [PATCH] SecurityPkg/DxeImageVerificationLib: Check result of + GetEfiGlobalVariable2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 22: SecurityPkg/DxeImageVerificationLib: Check result of GetEfiGlobalVariable2 +RH-Bugzilla: 1861743 +RH-Acked-by: Gerd Hoffmann +RH-Commit: [1/1] 70e1ae5e2c7c148fc23160acdd360c044df5f4ff + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1861743 +Upstream: Merged +CVE: CVE-2019-14560 + +commit 494127613b36e870250649b02cd4ce5f1969d9bd +Author: Gerd Hoffmann +Date: Fri Mar 3 18:35:53 2023 +0800 + + SecurityPkg/DxeImageVerificationLib: Check result of GetEfiGlobalVariable2 + + Call gRT->GetVariable() directly to read the SecureBoot variable. It is + one byte in size so we can easily place it on the stack instead of + having GetEfiGlobalVariable2() allocate it for us, which avoids a few + possible error cases. + + Skip secure boot checks if (and only if): + + (a) the SecureBoot variable is not present (EFI_NOT_FOUND) according to + the return value, or + (b) the SecureBoot variable was read successfully and is set to + SECURE_BOOT_MODE_DISABLE. + + Previously the code skipped the secure boot checks on *any* + gRT->GetVariable() error (GetEfiGlobalVariable2 sets the variable + value to NULL in that case) and also on memory allocation failures. + + Fixes: CVE-2019-14560 + Signed-off-by: Gerd Hoffmann + Suggested-by: Marvin Häuser + Reviewed-by: Min Xu + Reviewed-by: Jiewen Yao + +Signed-off-by: Jon Maloy +--- + .../DxeImageVerificationLib.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +index c48861cd64..1252927664 100644 +--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c ++++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +@@ -1650,7 +1650,8 @@ DxeImageVerificationHandler ( + EFI_IMAGE_EXECUTION_ACTION Action; + WIN_CERTIFICATE *WinCertificate; + UINT32 Policy; +- UINT8 *SecureBoot; ++ UINT8 SecureBoot; ++ UINTN SecureBootSize; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 NumberOfRvaAndSizes; + WIN_CERTIFICATE_EFI_PKCS *PkcsCertData; +@@ -1665,6 +1666,8 @@ DxeImageVerificationHandler ( + RETURN_STATUS PeCoffStatus; + EFI_STATUS HashStatus; + EFI_STATUS DbStatus; ++ EFI_STATUS VarStatus; ++ UINT32 VarAttr; + BOOLEAN IsFound; + + SignatureList = NULL; +@@ -1720,22 +1723,25 @@ DxeImageVerificationHandler ( + CpuDeadLoop (); + } + +- GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID**)&SecureBoot, NULL); ++ SecureBootSize = sizeof (SecureBoot); ++ VarStatus = gRT->GetVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, &VarAttr, &SecureBootSize, &SecureBoot); + // + // Skip verification if SecureBoot variable doesn't exist. + // +- if (SecureBoot == NULL) { ++ if (VarStatus == EFI_NOT_FOUND) { + return EFI_SUCCESS; + } + + // + // Skip verification if SecureBoot is disabled but not AuditMode + // +- if (*SecureBoot == SECURE_BOOT_MODE_DISABLE) { +- FreePool (SecureBoot); ++ if ((VarStatus == EFI_SUCCESS) && ++ (VarAttr == (EFI_VARIABLE_BOOTSERVICE_ACCESS | ++ EFI_VARIABLE_RUNTIME_ACCESS)) && ++ (SecureBoot == SECURE_BOOT_MODE_DISABLE)) ++ { + return EFI_SUCCESS; + } +- FreePool (SecureBoot); + + // + // Read the Dos header. +-- +2.39.1 + diff --git a/edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch b/edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch new file mode 100644 index 0000000..2739061 --- /dev/null +++ b/edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch @@ -0,0 +1,49 @@ +From c32f4994552ea5835cf00ce06f2f7d88c71249e5 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 28 Feb 2023 15:47:00 +0100 +Subject: [PATCH] UefiCpuPkg/MpInitLib: fix apic mode for cpu hotplug + +RH-Author: Miroslav Rezanina +RH-MergeRequest: 29: UefiCpuPkg/MpInitLib: fix apic mode for cpu hotplug +RH-Bugzilla: 2150267 +RH-Acked-by: Oliver Steffen +RH-Acked-by: Jon Maloy +RH-Commit: [1/1] e7e332ac0e6edf207b1b9692f2e1aed4a1fe7c0c + +In case the number of CPUs can in increase beyond 255 +due to CPU hotplug choose x2apic mode. + +Signed-off-by: Gerd Hoffmann +--- + UefiCpuPkg/Library/MpInitLib/MpLib.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c +index b9a06747ed..177d15ab5b 100644 +--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c ++++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c +@@ -495,7 +495,9 @@ CollectProcessorCount ( + // + // Enable x2APIC mode if + // 1. Number of CPU is greater than 255; or +- // 2. There are any logical processors reporting an Initial APIC ID of 255 or greater. ++ // 2. The platform exposed the exact *boot* CPU count to us in advance, and ++ // more than 255 logical processors are possible later, with hotplug; or ++ // 3. There are any logical processors reporting an Initial APIC ID of 255 or greater. + // + X2Apic = FALSE; + if (CpuMpData->CpuCount > 255) { +@@ -503,6 +505,10 @@ CollectProcessorCount ( + // If there are more than 255 processor found, force to enable X2APIC + // + X2Apic = TRUE; ++ } else if ((PcdGet32 (PcdCpuBootLogicalProcessorNumber) > 0) && ++ (PcdGet32 (PcdCpuMaxLogicalProcessorNumber) > 255)) ++ { ++ X2Apic = TRUE; + } else { + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { +-- +2.37.3 + diff --git a/edk2.spec b/edk2.spec index 400ab2c..5e6bf7b 100644 --- a/edk2.spec +++ b/edk2.spec @@ -7,7 +7,7 @@ ExclusiveArch: x86_64 aarch64 Name: edk2 Version: %{GITDATE}git%{GITCOMMIT} -Release: 5%{?dist} +Release: 6%{?dist} Summary: UEFI firmware for 64-bit virtual machines Group: Applications/Emulators License: BSD-2-Clause-Patent and OpenSSL and MIT @@ -56,26 +56,11 @@ Patch27: edk2-OvmfPkg-AmdSev-SecretPei-Mark-SEV-launch-secret-area.patch # For bz#2164558 - CVE-2023-0215 edk2: openssl: use-after-free following BIO_new_NDEF [rhel-8] # For bz#2164581 - CVE-2022-4450 edk2: openssl: double free after calling PEM_read_bio_ex [rhel-8] Patch28: edk2-rh-openssl-add-crypto-bn-rsa_sup_mul.c-to-file-list.patch -# Support hygon csv3 feature -Patch29: 0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch -Patch30: 0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch -Patch31: 0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch -Patch32: 0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch -Patch33: 0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch -Patch34: 0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch -Patch35: 0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch -Patch36: 0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch -Patch37: 0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch -Patch38: 0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch -# Support SEV live migration -Patch39: 0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch -Patch40: 0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch -Patch41: 0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch -Patch42: 0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch -Patch43: 0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch -Patch44: 0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch -Patch45: 0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch -Patch46: 0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch +# For bz#1861743 - CVE-2019-14560 edk2: Function GetEfiGlobalVariable2() return value not checked in DxeImageVerificationHandler() [rhel-8] +Patch29: edk2-SecurityPkg-DxeImageVerificationLib-Check-result-of-.patch +# For bz#2150267 - ovmf must consider max cpu count not boot cpu count for apic mode [rhel-8] +Patch30: edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch + # python3-devel and libuuid-devel are required for building tools. # python3-devel is also needed for varstore template generation and @@ -519,9 +504,15 @@ true %endif %changelog -* Mon Dec 11 2023 Jiang Xin - 20220126gitbb1bba3d77-5 -- Support hygon CSV3 feature -- Support SEV live migration +* Fri Aug 04 2023 Jon Maloy - 20220126gitbb1bba3d77-6 +- edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch [bz#2150267] +- Resolves: bz#2150267 + (ovmf must consider max cpu count not boot cpu count for apic mode [rhel-8]) + +* Thu Apr 06 2023 Miroslav Rezanina - 20220126gitbb1bba3d77-5 +- edk2-SecurityPkg-DxeImageVerificationLib-Check-result-of-.patch [bz#1861743] +- Resolves: bz#1861743 + (CVE-2019-14560 edk2: Function GetEfiGlobalVariable2() return value not checked in DxeImageVerificationHandler() [rhel-8]) * Wed Feb 15 2023 Jon Maloy - 20220126gitbb1bba3d77-4 - edk2-openssl-update.patch [bz#2164531 bz#2164543 bz#2164558 bz#2164581] -- Gitee From 6f76fe2e645f77f45a716e2cc965cc6608b119b1 Mon Sep 17 00:00:00 2001 From: Xin Jiang Date: Mon, 11 Dec 2023 14:05:11 +0800 Subject: [PATCH 2/2] Support Hygon CSV3 feaure and SEV live migration Signed-off-by: Xin Jiang --- ...g-Add-StandardSignatureIsHygonGenuin.patch | 140 ++++ ...g-LocalApicLib-Exclude-second-SendIp.patch | 83 ++ ...dd-CSV-secure-call-library-on-Hygon-.patch | 672 ++++++++++++++++ ...cg-Add-CsvLib-for-TpmMmioSevDecryptP.patch | 27 + ...esetVector-Support-CSV-in-ResetVecto.patch | 222 ++++++ ...latformPei-Initialize-CSV-VM-s-memor.patch | 202 +++++ ...aseMemcryptSevLib-update-page-status.patch | 75 ++ 0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch | 616 +++++++++++++++ ...mfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch | 724 ++++++++++++++++++ ...eserve-a-CPUID-table-page-for-CSV-gu.patch | 137 ++++ ...ncryptLib-Detect-SEV-live-migration-.patch | 325 ++++++++ ...ncryptLib-Hypercall-API-for-page-enc.patch | 298 +++++++ ...ncryptLib-Invoke-page-encryption-sta.patch | 91 +++ ...ib-Encryption-state-change-hypercall.patch | 46 ++ ...Pei-Mark-SEC-GHCB-page-as-unencrypte.patch | 43 ++ ...e-Add-support-for-SEV-live-migration.patch | 185 +++++ ...aseMemcryptSevLib-Correct-the-calcul.patch | 35 + ...aseMemEncryptLib-Return-SUCCESS-if-n.patch | 36 + edk2.spec | 27 +- 19 files changed, 3983 insertions(+), 1 deletion(-) create mode 100644 0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch create mode 100644 0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch create mode 100644 0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch create mode 100644 0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch create mode 100644 0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch create mode 100644 0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch create mode 100644 0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch create mode 100644 0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch create mode 100644 0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch create mode 100644 0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch create mode 100644 0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch create mode 100644 0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch create mode 100644 0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch create mode 100644 0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch create mode 100644 0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch create mode 100644 0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch create mode 100644 0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch create mode 100644 0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch diff --git a/0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch b/0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch new file mode 100644 index 0000000..5abf6fc --- /dev/null +++ b/0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch @@ -0,0 +1,140 @@ +From c5906a1813f0a370e76d0e4910f1959edd552af4 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Thu, 21 Apr 2022 16:03:08 +0800 +Subject: [PATCH 29/46] anolis: UefiCpuPkg: Add + StandardSignatureIsHygonGenuine() in BaseUefiCpuLib + +This function allows IA32/X64 code to determine if it is running on an +Hygon brand processor. + +Signed-off-by: Xin Jiang +Change-Id: I72594196f0ce6003fce43856120e3ca4609b8bb2 +--- + UefiCpuPkg/Include/Library/UefiCpuLib.h | 13 +++++ + UefiCpuPkg/Include/Register/Hygon/Cpuid.h | 47 +++++++++++++++++++ + .../Library/BaseUefiCpuLib/BaseUefiCpuLib.c | 24 ++++++++++ + 3 files changed, 84 insertions(+) + create mode 100644 UefiCpuPkg/Include/Register/Hygon/Cpuid.h + +diff --git a/UefiCpuPkg/Include/Library/UefiCpuLib.h b/UefiCpuPkg/Include/Library/UefiCpuLib.h +index 092c1d2..c64fe26 100644 +--- a/UefiCpuPkg/Include/Library/UefiCpuLib.h ++++ b/UefiCpuPkg/Include/Library/UefiCpuLib.h +@@ -43,6 +43,19 @@ StandardSignatureIsAuthenticAMD ( + VOID + ); + ++/** ++ Determine if the standard CPU signature is "HygonGenuine". ++ ++ @retval TRUE The CPU signature matches. ++ @retval FALSE The CPU signature does not match. ++ ++**/ ++BOOLEAN ++EFIAPI ++StandardSignatureIsHygonGenuine ( ++ VOID ++ ); ++ + /** + Return the 32bit CPU family and model value. + +diff --git a/UefiCpuPkg/Include/Register/Hygon/Cpuid.h b/UefiCpuPkg/Include/Register/Hygon/Cpuid.h +new file mode 100644 +index 0000000..e8a2c76 +--- /dev/null ++++ b/UefiCpuPkg/Include/Register/Hygon/Cpuid.h +@@ -0,0 +1,47 @@ ++/** @file ++ CPUID leaf definitions. ++ ++ Provides defines for CPUID leaf indexes. Data structures are provided for ++ registers returned by a CPUID leaf that contain one or more bit fields. ++ If a register returned is a single 32-bit value, then a data structure is ++ not provided for that register. ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++**/ ++ ++#ifndef __HYGON_CPUID_H__ ++#define __HYGON_CPUID_H__ ++ ++/** ++CPUID Signature Information ++ ++@param EAX CPUID_SIGNATURE (0x00) ++ ++@retval EAX Returns the highest value the CPUID instruction recognizes for ++ returning basic processor information. The value is returned is ++ processor specific. ++@retval EBX First 4 characters of a vendor identification string. ++@retval ECX Last 4 characters of a vendor identification string. ++@retval EDX Middle 4 characters of a vendor identification string. ++ ++**/ ++ ++/// ++/// @{ CPUID signature values returned by HYGON processors ++/// ++#define CPUID_SIGNATURE_AUTHENTIC_HYGON_EBX SIGNATURE_32 ('H', 'y', 'g', 'o') ++#define CPUID_SIGNATURE_AUTHENTIC_HYGON_EDX SIGNATURE_32 ('n', 'G', 'e', 'n') ++#define CPUID_SIGNATURE_AUTHENTIC_HYGON_ECX SIGNATURE_32 ('u', 'i', 'n', 'e') ++/// ++/// @} ++/// ++ ++#endif +diff --git a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c +index 5089161..700d633 100644 +--- a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c ++++ b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c +@@ -11,6 +11,7 @@ + + #include + #include ++#include + + #include + #include +@@ -38,6 +39,29 @@ StandardSignatureIsAuthenticAMD ( + RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); + } + ++/** ++ Determine if the standard CPU signature is "HygonGenuine". ++ ++ @retval TRUE The CPU signature matches. ++ @retval FALSE The CPU signature does not match. ++ ++**/ ++BOOLEAN ++EFIAPI ++StandardSignatureIsHygonGenuine ( ++ VOID ++ ) ++{ ++ UINT32 RegEbx; ++ UINT32 RegEcx; ++ UINT32 RegEdx; ++ ++ AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); ++ return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_HYGON_EBX && ++ RegEcx == CPUID_SIGNATURE_AUTHENTIC_HYGON_ECX && ++ RegEdx == CPUID_SIGNATURE_AUTHENTIC_HYGON_EDX); ++} ++ + /** + Return the 32bit CPU family and model value. + +-- +2.17.1 + diff --git a/0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch b/0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch new file mode 100644 index 0000000..ccb5fd6 --- /dev/null +++ b/0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch @@ -0,0 +1,83 @@ +From 573b40aeb685842d7fd4e7985cd197fc79fe8cff Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Sun, 10 Apr 2022 21:50:15 -0400 +Subject: [PATCH 30/46] anolis: UefiCpuPkg/LocalApicLib: Exclude second SendIpi + sequence on HYGON hardware + +On HYGON processors the second SendIpi in the SendInitSipiSipi and +SendInitSipiSipiAllExcludingSelf routines is not required, and may cause +undesired side-effects during MP initialization. + +This patch leverages the StandardSignatureIsHygonGenuine check to exclude +the second SendIpi and its associated MicroSecondDelay (200). + +Signed-off-by: Xin Jiang +Change-Id: I59defdaf10fb36981c5dfb7e3b69e8bf5aaf46cc +--- + UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 5 +++-- + UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 5 +++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +index 52bd90d..fac41bd 100644 +--- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c ++++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + // + // Library internal functions +@@ -527,7 +528,7 @@ SendInitSipiSipi ( + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; + IcrLow.Bits.Level = 1; + SendIpi (IcrLow.Uint32, ApicId); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, ApicId); + } +@@ -563,7 +564,7 @@ SendInitSipiSipiAllExcludingSelf ( + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + SendIpi (IcrLow.Uint32, 0); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, 0); + } +diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +index cdcbca0..a8fea8b 100644 +--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c ++++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + // + // Library internal functions +@@ -622,7 +623,7 @@ SendInitSipiSipi ( + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; + IcrLow.Bits.Level = 1; + SendIpi (IcrLow.Uint32, ApicId); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, ApicId); + } +@@ -658,7 +659,7 @@ SendInitSipiSipiAllExcludingSelf ( + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + SendIpi (IcrLow.Uint32, 0); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, 0); + } +-- +2.17.1 + diff --git a/0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch b/0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch new file mode 100644 index 0000000..72ebc6f --- /dev/null +++ b/0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch @@ -0,0 +1,672 @@ +From 98354124fe8c4cd7e6aed0fb6feabbe3a4de1836 Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 14:25:11 +0800 +Subject: [PATCH 31/46] anolis: OvmfPkg: Add CSV secure call library on Hygon + CPU + +CSV is the secure virtualization feature on Hygon CPU. +A CSV virtual machine is composed of private memory and shared memory. +The private memory or shared memory can be converted to the other by +the following steps: + - guest clear/set the c-bit in the guest page table + - guest send a update command to Hygon Secure Processor + +While the update command has to be forwarded by the VMM to the Secure +Processor, to prevent the malicious VMM from attacking the update +command, a reliable command channel is required between the CSV VM +and the Hygon Secure Processor. + +The secure call library is created to build a secure command channel +between the VM and the Secure Processor by #NPF on a special private +page which the VMM is not able to access. +This special page is called secure call page. +The VM puts command in the secure call page and triggers a #NPF +to reach the Secure Processor. +The Secure Processor then puts the response in the same page and +finishes the #NPF. +The information is protected in the secure call page all the way. + +CsvLib is added to implement the functionality and new PCDs are added +accordingly. + +Signed-off-by: Xin Jiang +Change-Id: If62f0cb37faf003a79ed8a117bf582f8b90cdf89 +--- + OvmfPkg/Include/Library/CsvLib.h | 84 +++++++ + OvmfPkg/Library/CsvLib/CsvLib.c | 82 ++++++ + OvmfPkg/Library/CsvLib/CsvLib.inf | 55 ++++ + .../Library/CsvLib/Ia32/UpdateMemoryCsvLib.c | 53 ++++ + .../Library/CsvLib/X64/UpdateMemoryCsvLib.c | 238 ++++++++++++++++++ + OvmfPkg/OvmfPkg.dec | 8 + + OvmfPkg/OvmfPkgIa32.dsc | 1 + + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + + OvmfPkg/OvmfPkgX64.dsc | 1 + + OvmfPkg/OvmfPkgX64.fdf | 3 + + 10 files changed, 526 insertions(+) + create mode 100644 OvmfPkg/Include/Library/CsvLib.h + create mode 100644 OvmfPkg/Library/CsvLib/CsvLib.c + create mode 100644 OvmfPkg/Library/CsvLib/CsvLib.inf + create mode 100644 OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c + create mode 100644 OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c + +diff --git a/OvmfPkg/Include/Library/CsvLib.h b/OvmfPkg/Include/Library/CsvLib.h +new file mode 100644 +index 0000000..0cb6218 +--- /dev/null ++++ b/OvmfPkg/Include/Library/CsvLib.h +@@ -0,0 +1,84 @@ ++/** @file ++ ++ CSV base library helper function ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#ifndef _CSV_LIB_H_ ++#define _CSV_LIB_H_ ++ ++#include ++ ++typedef struct { ++ IN UINT64 BaseAddress; ++ IN UINT64 Size; ++} CSV_SECURE_CMD_SHARED_REGION; ++ ++typedef enum { ++ CsvSecureCmdEnc = 1, ++ CsvSecureCmdDec, ++ CsvSecureCmdReset, ++ CsvSecureCmdUpdateSecureCallTable, ++ CsvSecureCmdMapLowerMemory, //secure memory range below 4G ++ CsvSecureCmdMapUpperMemory //secure memory range above 4G ++} CSV_SECURE_COMMAND_TYPE; ++ ++/** ++ Returns a boolean to indicate whether CSV is enabled ++ ++ @retval TRUE CSV is enabled ++ @retval FALSE CSV is not enabled ++**/ ++BOOLEAN ++EFIAPI ++CsvIsEnabled ( ++ VOID ++ ); ++ ++#define CSV_SHARED_MEMORY_SIGNATURE SIGNATURE_32('C','S','V',' ') ++ ++typedef struct { ++ UINTN Signature; ++ LIST_ENTRY Link; ++ UINT64 Start; ++ UINT64 Length; ++} CsvSharedMemoryEntry; ++ ++VOID ++EFIAPI ++CsvUpdateMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages, ++ IN BOOLEAN Dec ++); ++ ++VOID ++EFIAPI ++CsvResetMemory ( ++ VOID ++); ++ ++VOID ++EFIAPI ++CsvUpdateMapLowerMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++); ++ ++VOID ++EFIAPI ++CsvUpdateMapUpperMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++); ++#endif // _CSV_LIB_H_ +diff --git a/OvmfPkg/Library/CsvLib/CsvLib.c b/OvmfPkg/Library/CsvLib/CsvLib.c +new file mode 100644 +index 0000000..7e7f8ef +--- /dev/null ++++ b/OvmfPkg/Library/CsvLib/CsvLib.c +@@ -0,0 +1,82 @@ ++/** @file ++ ++ CSV library helper function ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++STATIC BOOLEAN mCsvStatus = FALSE; ++STATIC BOOLEAN mCsvStatusChecked = FALSE; ++ ++/** ++ ++ Reads and sets the status of CSV features ++ **/ ++STATIC ++VOID ++EFIAPI ++InternalCsvStatus ( ++ VOID ++ ) ++{ ++ UINT32 RegEax; ++ ++ // ++ // Check if memory encryption leaf exist ++ // ++ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); ++ if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) { ++ if(StandardSignatureIsHygonGenuine ()){ ++ // ++ // Check MSR_0xC0010131 Bit 30 (Csv Enabled) ++ // ++ MSR_SEV_STATUS_REGISTER Msr; ++ Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS); ++ if (Msr.Uint32 & (1 << 30)) { ++ mCsvStatus = TRUE; ++ DEBUG ((EFI_D_INFO, "CSV is enabled\n")); ++ } ++ } ++ } ++ mCsvStatusChecked = TRUE; ++} ++ ++/** ++ Returns a boolean to indicate whether CSV is enabled ++ ++ @retval TRUE CSV is enabled ++ @retval FALSE CSV is not enabled ++**/ ++BOOLEAN ++EFIAPI ++CsvIsEnabled ( ++ VOID ++ ) ++{ ++ if (!mCsvStatusChecked) { ++ InternalCsvStatus (); ++ } ++ ++ return MemEncryptSevEsIsEnabled () && mCsvStatus; ++} +diff --git a/OvmfPkg/Library/CsvLib/CsvLib.inf b/OvmfPkg/Library/CsvLib/CsvLib.inf +new file mode 100644 +index 0000000..25859c3 +--- /dev/null ++++ b/OvmfPkg/Library/CsvLib/CsvLib.inf +@@ -0,0 +1,55 @@ ++## @file ++# Library provides the helper functions for CSV guest ++# ++# Copyright (c) 2022 HYGON. All rights reserved.
++# ++# This program and the accompanying materials ++# are licensed and made available under the terms and conditions of the BSD ++# License which accompanies this distribution. The full text of the license ++# may be found at http://opensource.org/licenses/bsd-license.php ++# ++# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED. ++# ++# ++## ++ ++[Defines] ++ INF_VERSION = 1.25 ++ BASE_NAME = CsvLib ++ FILE_GUID = 9460ef3a-b9c3-11e9-8324-7371ac35e1e3 ++ MODULE_TYPE = BASE ++ VERSION_STRING = 1.0 ++ LIBRARY_CLASS = CsvLib|PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER ++ ++# ++# The following information is for reference only and not required by the build ++# tools. ++# ++# VALID_ARCHITECTURES = Ia32 X64 ++# ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ OvmfPkg/OvmfPkg.dec ++ UefiCpuPkg/UefiCpuPkg.dec ++ ++[Sources] ++ CsvLib.c ++ ++[Sources.X64] ++ X64/UpdateMemoryCsvLib.c ++[Sources.IA32] ++ Ia32/UpdateMemoryCsvLib.c ++ ++[LibraryClasses] ++ BaseLib ++ CpuLib ++ DebugLib ++ MemEncryptSevLib ++ UefiCpuLib ++ ++[Pcd] ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize +diff --git a/OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c b/OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c +new file mode 100644 +index 0000000..15d3aa8 +--- /dev/null ++++ b/OvmfPkg/Library/CsvLib/Ia32/UpdateMemoryCsvLib.c +@@ -0,0 +1,53 @@ ++/** @file ++ ++ CSV library helper function ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#include ++ ++VOID ++EFIAPI ++CsvUpdateMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages, ++ IN BOOLEAN Dec ++) ++{ ++} ++ ++VOID ++EFIAPI ++CsvResetMemory ( ++ VOID ++) ++{ ++} ++ ++VOID ++EFIAPI ++CsvUpdateMapLowerMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++) ++{ ++} ++ ++VOID ++EFIAPI ++CsvUpdateMapUpperMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++) ++{ ++} +diff --git a/OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c b/OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c +new file mode 100644 +index 0000000..13d06d7 +--- /dev/null ++++ b/OvmfPkg/Library/CsvLib/X64/UpdateMemoryCsvLib.c +@@ -0,0 +1,238 @@ ++/** @file ++ ++ CSV library helper function ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SECURE_CALL_ENTRY_MAX (254) ++ ++ ++typedef struct { ++ union { ++ UINT8 Guid[16]; ++ UINT64 Guid64[2]; ++ }; ++ UINT32 CmdType; ++ UINT32 Nums; ++ UINT64 Unused; ++ struct { ++ UINT64 BaseAddress; ++ UINT64 Size; ++ } Entry[SECURE_CALL_ENTRY_MAX]; ++} CSV_SECURE_CALL_CMD; ++ ++STATIC UINT32 SecureCallPageIdx = 0; ++ ++STATIC UINTN MemorySizeBelow4G = (UINTN)-1; ++STATIC UINTN MemorySizeAbove4G = (UINTN)-1; ++ ++STATIC ++VOID ++EFIAPI ++CsvSecureCall( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages, ++ IN CSV_SECURE_COMMAND_TYPE CmdType ++) ++{ ++ volatile CSV_SECURE_COMMAND_TYPE CmdAck = 0; ++ ++ CSV_SECURE_CALL_CMD *SecureCallPageRead; ++ CSV_SECURE_CALL_CMD *SecureCallPageWrite; ++ UINTN SecureCallBase = 0; ++ ++ if (CsvIsEnabled () == FALSE) { ++ return ; ++ } ++ ++ SecureCallBase = FixedPcdGet32 (PcdCsvDefaultSecureCallBase); ++ ++ SecureCallPageRead = ++ (CSV_SECURE_CALL_CMD *)(UINT64) ++ (EFI_PAGE_SIZE * SecureCallPageIdx + SecureCallBase); ++ ++ SecureCallPageWrite = ++ (CSV_SECURE_CALL_CMD *) ++ (UINT64)(EFI_PAGE_SIZE * (1 - SecureCallPageIdx) + SecureCallBase); ++ ++ while(1) { ++ SecureCallPageWrite->CmdType = (UINT32)CmdType; ++ SecureCallPageWrite->Nums = 1; ++ SecureCallPageWrite->Entry[0].BaseAddress = (UINT64)BaseAddress; ++ SecureCallPageWrite->Entry[0].Size = (UINT64)NumPages << EFI_PAGE_SHIFT; ++ ++ MemoryFence (); ++ ++ CmdAck = SecureCallPageRead->CmdType; ++ if (CmdAck != CmdType) ++ break; ++ } ++ SecureCallPageIdx = 1 - SecureCallPageIdx; ++} ++ ++STATIC ++UINT8 ++CmosRead8 ( ++ IN UINTN Index ++ ) ++{ ++ IoWrite8 (0x70, (UINT8) Index); ++ return IoRead8 (0x71); ++} ++ ++ ++STATIC ++VOID ++EFIAPI ++CsvGetSystemMemory( ++ VOID ++ ) ++{ ++ UINT8 Cmos0x34; ++ UINT8 Cmos0x35; ++ UINT32 Size; ++ UINTN CmosIndex; ++ ++ // ++ // system memory below 4GB MB ++ // ++ ++ Cmos0x34 = (UINT8) CmosRead8 (0x34); ++ Cmos0x35 = (UINT8) CmosRead8 (0x35); ++ ++ MemorySizeBelow4G = ++ (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); ++ ++ // ++ // system memory above 4GB MB ++ // ++ ++ Size = 0; ++ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) { ++ Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex); ++ } ++ ++ MemorySizeAbove4G = LShiftU64 (Size, 16); ++} ++ ++STATIC ++BOOLEAN ++EFIAPI ++CsvIsDRAM( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++ ) ++{ ++ UINTN Size = EFI_PAGES_TO_SIZE (NumPages); ++ PHYSICAL_ADDRESS EndAddress; ++ ++ Size = EFI_PAGES_TO_SIZE (NumPages); ++ EndAddress = BaseAddress + Size; ++ ++ if (MemorySizeBelow4G == (UINTN)-1 || ++ MemorySizeAbove4G == (UINTN)-1) { ++ CsvGetSystemMemory (); ++ } ++ ++ if (BaseAddress < MemorySizeBelow4G) { ++ return TRUE; ++ } else if (BaseAddress >= BASE_4GB && ++ BaseAddress < (BASE_4GB + MemorySizeAbove4G)) { ++ return TRUE; ++ } else if (EndAddress > BASE_4GB && ++ EndAddress <= (BASE_4GB + MemorySizeAbove4G)) { ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++STATIC ++VOID ++EFIAPI ++CsvUpdateEncryptMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++) ++{ ++ PHYSICAL_ADDRESS PageAddress = BaseAddress & ~EFI_PAGE_MASK; ++ ++ if (CsvIsDRAM (PageAddress, NumPages)) { ++ CsvSecureCall (PageAddress, NumPages, CsvSecureCmdEnc); ++ } ++} ++ ++STATIC ++VOID ++EFIAPI ++CsvUpdateDecryptMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++) ++{ ++ PHYSICAL_ADDRESS PageAddress = BaseAddress & ~EFI_PAGE_MASK; ++ ++ if (CsvIsDRAM (PageAddress, NumPages)) { ++ CsvSecureCall (PageAddress, NumPages, CsvSecureCmdDec); ++ } ++} ++ ++VOID ++EFIAPI ++CsvUpdateMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages, ++ IN BOOLEAN Dec ++ ) ++{ ++ if (Dec) ++ CsvUpdateDecryptMemory (BaseAddress, NumPages); ++ else ++ CsvUpdateEncryptMemory (BaseAddress, NumPages); ++} ++ ++VOID ++EFIAPI ++CsvResetMemory ( ++ VOID ++) ++{ ++ CsvSecureCall (0, 0, CsvSecureCmdReset); ++} ++ ++VOID ++EFIAPI ++CsvUpdateMapLowerMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++) ++{ ++ CsvSecureCall (BaseAddress, NumPages, CsvSecureCmdMapLowerMemory); ++} ++ ++VOID ++EFIAPI ++CsvUpdateMapUpperMemory ( ++ IN PHYSICAL_ADDRESS BaseAddress, ++ IN UINTN NumPages ++) ++{ ++ CsvSecureCall (BaseAddress, NumPages, CsvSecureCmdMapUpperMemory); ++} +diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec +index 340d83f..6f4afb8 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -109,6 +109,10 @@ + # + XenPlatformLib|Include/Library/XenPlatformLib.h + ++ ## @libraryclass CSV Library ++ # ++ CsvLib|Include/Library/CsvLib.h ++ + [Guids] + gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}} + gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}} +@@ -350,6 +354,10 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset|0|UINT32|0x56 + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize|0|UINT32|0x57 + ++ ## the base address of the secure call pages used by CSV. ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|0|UINT32|0x58 ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize|0|UINT32|0x59 ++ + [PcdsDynamic, PcdsDynamicEx] + gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 +diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc +index a066693..d623ed3 100644 +--- a/OvmfPkg/OvmfPkgIa32.dsc ++++ b/OvmfPkg/OvmfPkgIa32.dsc +@@ -176,6 +176,7 @@ + VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf + LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf + MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf ++ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf + !if $(SMM_REQUIRE) == FALSE + LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf + !endif +diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc +index 5efeb42..9e4dcce 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -180,6 +180,7 @@ + VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf + LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf + MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf ++ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf + !if $(SMM_REQUIRE) == FALSE + LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf + !endif +diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc +index 10fb7d7..e62b533 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -180,6 +180,7 @@ + VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf + LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf + MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf ++ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf + !if $(SMM_REQUIRE) == FALSE + LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf + !endif +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 85b4b23..a3634dd 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -88,6 +88,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm + 0x00C000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize + ++0x00D000|0x002000 ++gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize ++ + 0x010000|0x010000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + +-- +2.17.1 + diff --git a/0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch b/0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch new file mode 100644 index 0000000..c00ebcd --- /dev/null +++ b/0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch @@ -0,0 +1,27 @@ +From 40c0763c88a6a895d4fc58158f3c0f9a17798049 Mon Sep 17 00:00:00 2001 +From: Xin Jiang +Date: Fri, 18 Aug 2023 16:48:03 +0800 +Subject: [PATCH 32/46] anolis: OvmfPkg/Tcg: Add CsvLib for + TpmMmioSevDecryptPei + +Signed-off-by: Xin Jiang +Change-Id: I4a11065abcc679538aabcb7602185f785df60496 +--- + OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf +index 51ad6d0..402e4c9 100644 +--- a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf ++++ b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf +@@ -29,6 +29,7 @@ + PcdLib + PeimEntryPoint + PeiServicesLib ++ CsvLib + + [Ppis] + gOvmfTpmMmioAccessiblePpiGuid ## PRODUCES +-- +2.17.1 + diff --git a/0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch b/0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch new file mode 100644 index 0000000..b30e7df --- /dev/null +++ b/0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch @@ -0,0 +1,222 @@ +From b08f9e4b2d4aa1f1baec02ecda6ae481ed58c64f Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 15:55:44 +0800 +Subject: [PATCH 33/46] anolis: OvmfPkg/ResetVector: Support CSV in ResetVector + phase + +- A GUID is written along with the first secure call page address, +by which the Secure Processor can locate the first secure call page +address. + +- Check whether the VM is a CSV VM when setting the first page table + +- CSV VM will update first shared GHCB page address to Secure Processor +by secure call page + +Signed-off-by: Xin Jiang +Change-Id: I422bff00dc88d6738d1dae2d9f6c5c49ec601e95 +--- + OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 15 +++ + OvmfPkg/ResetVector/Ia32/AmdSev.asm | 10 ++ + OvmfPkg/ResetVector/Ia32/CsvInit.asm | 107 +++++++++++++++++++ + OvmfPkg/ResetVector/ResetVector.inf | 2 + + OvmfPkg/ResetVector/ResetVector.nasmb | 4 + + 5 files changed, 138 insertions(+) + create mode 100644 OvmfPkg/ResetVector/Ia32/CsvInit.asm + +diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +index dee2e3f..c32b608 100644 +--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm ++++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +@@ -48,6 +48,21 @@ TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0 + guidedStructureStart: + + %ifdef ARCH_X64 ++; ++; CSV secure call table ++; ++; Provide secure call pages when boot up for CSV guest. ++; ++; GUID : 9a5d926f-2fa5-ceba-ab21-6b275d5556a5 ++; ++csvSecureCallBase: ++ DD CSV_DEFAULT_SECURE_CALL_SIZE ++ DD CSV_DEFAULT_SECURE_CALL_BASE ++ DW csvSecureCallEnd - csvSecureCallBase ++ DB 0x6F, 0x92, 0x5D, 0x9A, 0xA5, 0x2F, 0xBA, 0xCE ++ DB 0xAB, 0x21, 0x6B, 0x27, 0x5D, 0x55, 0x56, 0xA5 ++csvSecureCallEnd: ++ + ; + ; TDX Metadata offset block + ; +diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm +index 250ac8d..8ce5eb0 100644 +--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm ++++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm +@@ -177,6 +177,16 @@ pageTableEntries4kLoop: + mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12 + mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0 + ++ OneTimeCall CheckCsvFeature ++ test eax, eax ++ jz clearGhcbStart ++ ++ OneTimeCall CsvInit ++ mov eax, 1 ++ test ecx, ecx ++ jz SevEsUnexpectedRespTerminate ++ ++clearGhcbStart: + mov ecx, GHCB_SIZE / 4 + xor eax, eax + clearGhcbMemoryLoop: +diff --git a/OvmfPkg/ResetVector/Ia32/CsvInit.asm b/OvmfPkg/ResetVector/Ia32/CsvInit.asm +new file mode 100644 +index 0000000..0744a35 +--- /dev/null ++++ b/OvmfPkg/ResetVector/Ia32/CsvInit.asm +@@ -0,0 +1,107 @@ ++;------------------------------------------------------------------------------ ++; @file ++; Provide the functions to check whether CSV is enabled. ++; ++; Copyright (c) 2022, HYGON. All rights reserved.
++; SPDX-License-Identifier: BSD-2-Clause-Patent ++; ++;------------------------------------------------------------------------------ ++ ++BITS 32 ++ ++; If Secure Command returns ok then ECX will be non-zero. ++; If Secure Command returns error then ECX will be zero. ++CsvInit: ++ mov esp, SEV_ES_VC_TOP_OF_STACK ++ push esi ++ push edi ++ ++ ; copy SECURE_CALL_GUID to CSV_DEFAULT_SECURE_CALL_BASE + 4096 ++ cld ++ mov esi, ADDR_OF(SECURE_CALL_GUID) ++ mov edi, CSV_DEFAULT_SECURE_CALL_BASE ++ add edi, 4096 ++ mov ecx, 4 ++ rep movsd ++ ++ ; secure call begin ++ mov esi, CSV_DEFAULT_SECURE_CALL_BASE ++ ; write secure cmd to page B ++ ; 16 bytes of page A/B is GUID, just ignore ++ mov [esi + 4096 + 16], DWORD 2 ; dec command ++ mov [esi + 4096 + 20], DWORD 1 ; 1 entry ++ ; 8 bytes is unused ++ mov [esi + 4096 + 32], DWORD GHCB_BASE; lower address ++ mov [esi + 4096 + 36], DWORD 0 ; upper address ++ mov [esi + 4096 + 40], DWORD 4096 ; lower 32 bit of page size ++ mov [esi + 4096 + 44], DWORD 0 ; upper 32 bit of page size ++ mfence ++ ; read from page A ++ mov ecx, [esi + 16] ++ ; check if the response comes ++ cmp ecx, 2 ++ jne SecureCommandDone ++ ; no secure command response, clean ecx ++ xor ecx, ecx ++ ; secure call end ++ ++SecureCommandDone: ++ pop edi ++ pop esi ++ mov esp, 0 ++ ++ OneTimeCallRet CsvInit ++ ++; Check if CSV feature is enabled. ++; ++; Modified: EAX, EBX, ECX, EDX ++; ++; If CSV is enabled then EAX will be non-zero. ++; If CSV is disabled then EAX will be zero. ++; ++CheckCsvFeature: ++ mov esp, SEV_ES_VC_TOP_OF_STACK ++ mov eax, ADDR_OF(Idtr) ++ lidt [cs:eax] ++ ++ ; Check if vendor Hygon CPUID_SIGNATURE(0x0) ++ ; CPUID raises a #VC exception if running as an SEV-ES guest ++ mov eax, 0 ++ cpuid ++ ++ cmp ebx, 0x6f677948 ++ jne NoCsv ++ cmp ecx, 0x656e6975 ++ jne NoCsv ++ cmp edx, 0x6e65476e ++ jne NoCsv ++ ++ ; Check if CSV is enabled ++ ; MSR_0xC0010131 - Bit 30 (CSV enabled) ++ mov ecx, 0xc0010131 ++ rdmsr ++ and eax, 0x40000000 ++ jmp CsvExit ++ ++NoCsv: ++ xor eax, eax ++ ++CsvExit: ++ ; ++ ; Clear exception handlers and stack ++ ; ++ push eax ++ mov eax, ADDR_OF(IdtrClear) ++ lidt [cs:eax] ++ pop eax ++ mov esp, 0 ++ ++ OneTimeCallRet CheckCsvFeature ++ ++SECURE_CALL_GUID: ++; low 0xceba2fa59a5d926f ++; high 0xa556555d276b21ab ++ dd 0x9a5d926f ++ dd 0xceba2fa5 ++ dd 0x276b21ab ++ dd 0xa556555d +diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf +index 320e5f2..38c1720 100644 +--- a/OvmfPkg/ResetVector/ResetVector.inf ++++ b/OvmfPkg/ResetVector/ResetVector.inf +@@ -35,6 +35,8 @@ + + [Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase +diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb +index 87effed..ca00f64 100644 +--- a/OvmfPkg/ResetVector/ResetVector.nasmb ++++ b/OvmfPkg/ResetVector/ResetVector.nasmb +@@ -104,11 +104,15 @@ + %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16) + %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) + ++ %define CSV_DEFAULT_SECURE_CALL_BASE FixedPcdGet32 (PcdCsvDefaultSecureCallBase) ++ %define CSV_DEFAULT_SECURE_CALL_SIZE FixedPcdGet32 (PcdCsvDefaultSecureCallSize) ++ + %include "X64/IntelTdxMetadata.asm" + %include "Ia32/Flat32ToFlat64.asm" + %include "Ia32/AmdSev.asm" + %include "Ia32/PageTables64.asm" + %include "Ia32/IntelTdx.asm" ++%include "Ia32/CsvInit.asm" + %endif + + %include "Ia16/Real16ToFlat32.asm" +-- +2.17.1 + diff --git a/0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch b/0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch new file mode 100644 index 0000000..3a55e93 --- /dev/null +++ b/0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch @@ -0,0 +1,202 @@ +From 9c52c4e45c2fc51308628c8118edb3740bbfae47 Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 16:12:38 +0800 +Subject: [PATCH 34/46] anolis: OvmfPkg/PlatformPei: Initialize CSV VM's memory + +For CSV VM, the Secure Processor builds a temporary nested +page table to help the guest to run into the PEI phase. + +In PEI phase, CSV VM detects the start address and size of the +guest physical memory. + +The CSV VM sends the memory information to the Secure Processor +to build the permanent nested page table. + +Signed-off-by: Xin Jiang +Change-Id: I853d17ffa4146037038018d934f224fcbf79be1a +--- + OvmfPkg/PlatformPei/Csv.c | 81 +++++++++++++++++++++++++++++ + OvmfPkg/PlatformPei/MemDetect.c | 2 - + OvmfPkg/PlatformPei/Platform.c | 2 + + OvmfPkg/PlatformPei/Platform.h | 14 +++++ + OvmfPkg/PlatformPei/PlatformPei.inf | 4 ++ + 5 files changed, 101 insertions(+), 2 deletions(-) + create mode 100644 OvmfPkg/PlatformPei/Csv.c + +diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c +new file mode 100644 +index 0000000..44e81e1 +--- /dev/null ++++ b/OvmfPkg/PlatformPei/Csv.c +@@ -0,0 +1,81 @@ ++/** @file ++ ++ CSV initialization in PEI ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "Platform.h" ++ ++VOID ++CsvInitializeMemInfo ( ++ VOID ++ ) ++{ ++ UINT64 LowerMemorySize; ++ UINT64 UpperMemorySize; ++ ++ if (!CsvIsEnabled ()) { ++ return ; ++ } ++ ++ LowerMemorySize = GetSystemMemorySizeBelow4gb (); ++ UpperMemorySize = GetSystemMemorySizeAbove4gb (); ++ ++ CsvUpdateMapLowerMemory ( ++ 0, ++ LowerMemorySize >> EFI_PAGE_SHIFT ++ ); ++ ++ if (UpperMemorySize > 0) { ++ CsvUpdateMapUpperMemory ( ++ BASE_4GB, ++ UpperMemorySize >> EFI_PAGE_SHIFT ++ ); ++ } ++ ++ BuildMemoryAllocationHob ( ++ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdCsvDefaultSecureCallBase), ++ (UINT64)(UINTN) FixedPcdGet32 (PcdCsvDefaultSecureCallSize), ++ EfiReservedMemoryType ++ ); ++} ++ ++VOID ++CsvInitializeGhcb ( ++ VOID ++ ) ++{ ++ RETURN_STATUS EncryptStatus; ++ ++ if (!CsvIsEnabled ()) { ++ return ; ++ } ++ ++ // ++ // Encrypt the SecGhcb as it's not a Ghcb any more ++ // ++ EncryptStatus = MemEncryptSevSetPageEncMask( ++ 0, ++ PcdGet32 (PcdOvmfSecGhcbBase), ++ 1 ++ ); ++ ASSERT_RETURN_ERROR (EncryptStatus); ++} +diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c +index d736b85..c2c3cf7 100644 +--- a/OvmfPkg/PlatformPei/MemDetect.c ++++ b/OvmfPkg/PlatformPei/MemDetect.c +@@ -301,8 +301,6 @@ GetSystemMemorySizeBelow4gb ( + return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); + } + +- +-STATIC + UINT64 + GetSystemMemorySizeAbove4gb ( + ) +diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c +index d0e2c08..79bf4e7 100644 +--- a/OvmfPkg/PlatformPei/Platform.c ++++ b/OvmfPkg/PlatformPei/Platform.c +@@ -743,6 +743,7 @@ InitializePlatform ( + QemuUc32BaseInitialization (); + + InitializeRamRegions (); ++ CsvInitializeMemInfo (); + + if (mBootMode != BOOT_ON_S3_RESUME) { + if (!FeaturePcdGet (PcdSmmSmramRequire)) { +@@ -757,6 +758,7 @@ InitializePlatform ( + + InstallClearCacheCallback (); + AmdSevInitialize (); ++ CsvInitializeGhcb (); + MiscInitialization (); + InstallFeatureControlCallback (); + +diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h +index 8b1d270..89c3bd8 100644 +--- a/OvmfPkg/PlatformPei/Platform.h ++++ b/OvmfPkg/PlatformPei/Platform.h +@@ -102,6 +102,20 @@ AmdSevInitialize ( + VOID + ); + ++VOID ++CsvInitializeMemInfo ( ++ VOID ++); ++ ++VOID ++CsvInitializeGhcb ( ++ VOID ++); ++ ++UINT64 ++GetSystemMemorySizeAbove4gb ( ++); ++ + extern EFI_BOOT_MODE mBootMode; + + extern BOOLEAN mS3Supported; +diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf +index 69eb3ed..cb0582c 100644 +--- a/OvmfPkg/PlatformPei/PlatformPei.inf ++++ b/OvmfPkg/PlatformPei/PlatformPei.inf +@@ -33,6 +33,7 @@ + MemTypeInfo.c + Platform.c + Platform.h ++ Csv.c + + [Packages] + EmbeddedPkg/EmbeddedPkg.dec +@@ -62,6 +63,7 @@ + MtrrLib + MemEncryptSevLib + PcdLib ++ CsvLib + + [Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase +@@ -119,6 +121,8 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize + + [FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable +-- +2.17.1 + diff --git a/0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch b/0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch new file mode 100644 index 0000000..1938b99 --- /dev/null +++ b/0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch @@ -0,0 +1,75 @@ +From 16936ea22fc052576844dfdad6987531aa27a8ec Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Sat, 26 Feb 2022 14:39:06 +0800 +Subject: [PATCH 35/46] anolis: OvmfPkg/BaseMemcryptSevLib: update page status + to Secure Processor for CSV + +For CSV VM, when encrypting/decrypting a shared/private memory region, +guest needs to + - set/clear the c-bit in guest page table + - the Secure Processor should be updated accordingly + +The BaseMemcryptSevLib has done the first step. +Calling the secure call library for second step. + +Signed-off-by: Xin Jiang +Change-Id: Icab502ee201d887d6056bcb0116b2e5a1b9eb6b9 +--- + .../BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 1 + + .../BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 14 ++++++++++++++ + 2 files changed, 15 insertions(+) + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +index f2e162d..dc32929 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +@@ -49,6 +49,7 @@ + DebugLib + MemoryAllocationLib + PcdLib ++ CsvLib + + [FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +index c696745..6726010 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +@@ -18,6 +18,8 @@ + + #include "VirtualMemory.h" + ++#include ++ + STATIC BOOLEAN mAddressEncMaskChecked = FALSE; + STATIC UINT64 mAddressEncMask; + STATIC PAGE_TABLE_POOL *mPageTablePool = NULL; +@@ -585,6 +587,11 @@ SetMemoryEncDec ( + UINT64 AddressEncMask; + BOOLEAN IsWpEnabled; + RETURN_STATUS Status; ++ PHYSICAL_ADDRESS PageAddress; ++ UINTN PageNum; ++ ++ PageAddress = PhysicalAddress; ++ PageNum = EFI_SIZE_TO_PAGES (Length); + + // + // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings. +@@ -816,6 +823,13 @@ Done: + EnableReadOnlyPageWriteProtect (); + } + ++ if (CsvIsEnabled () && Status == EFI_SUCCESS) { ++ if (Mode == ClearCBit) ++ CsvUpdateMemory (PageAddress, PageNum, TRUE); ++ else ++ CsvUpdateMemory (PageAddress, PageNum, FALSE); ++ } ++ + return Status; + } + +-- +2.17.1 + diff --git a/0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch b/0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch new file mode 100644 index 0000000..0bf6d40 --- /dev/null +++ b/0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch @@ -0,0 +1,616 @@ +From 4569ddd201843a1fd1e9b0431e971cd4edefff5d Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 16:34:25 +0800 +Subject: [PATCH 36/46] anolis: OvmfPkg: Add CsvDxe driver + +CsvDxe creates and installs the CsvSharedMemory protocol. + +CSV VM needs the shared memory to exchange data with external devices. + +To improve the performance, CsvSharedMemory protocol pre-allocates +huge shared memory chunk as a pool. + +When reqeusted, it allocates small pieces of shared memory from the +pool and records the allocated memory in a list. + +When finished, the shared memory pieces are returned to the pool and +removed from the record list. + +Signed-off-by: Xin Jiang +Change-Id: I6b41c6e1af34b4f8ad58a61cce2e7fd8e8b5795b +--- + OvmfPkg/CsvDxe/CsvDxe.c | 104 +++++++++++ + OvmfPkg/CsvDxe/CsvDxe.inf | 45 +++++ + OvmfPkg/CsvDxe/CsvSharedMemory.c | 208 +++++++++++++++++++++ + OvmfPkg/CsvDxe/CsvSharedMemory.h | 29 +++ + OvmfPkg/Include/Protocol/CsvSharedMemory.h | 99 ++++++++++ + OvmfPkg/OvmfPkg.dec | 1 + + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + + OvmfPkg/OvmfPkgIa32X64.fdf | 1 + + OvmfPkg/OvmfPkgX64.dsc | 1 + + OvmfPkg/OvmfPkgX64.fdf | 1 + + 10 files changed, 490 insertions(+) + create mode 100644 OvmfPkg/CsvDxe/CsvDxe.c + create mode 100644 OvmfPkg/CsvDxe/CsvDxe.inf + create mode 100644 OvmfPkg/CsvDxe/CsvSharedMemory.c + create mode 100644 OvmfPkg/CsvDxe/CsvSharedMemory.h + create mode 100644 OvmfPkg/Include/Protocol/CsvSharedMemory.h + +diff --git a/OvmfPkg/CsvDxe/CsvDxe.c b/OvmfPkg/CsvDxe/CsvDxe.c +new file mode 100644 +index 0000000..552f3cf +--- /dev/null ++++ b/OvmfPkg/CsvDxe/CsvDxe.c +@@ -0,0 +1,104 @@ ++/** @file ++ ++ Hygon CSV DXE. ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT ++ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "CsvSharedMemory.h" ++ ++ ++#define HUGE_PAGE_SIZE 0x200000ULL ++ ++EFI_STATUS ++EFIAPI ++CsvDxeEntryPoint ( ++ IN EFI_HANDLE ImageHandle, ++ IN EFI_SYSTEM_TABLE *SystemTable ++ ) ++{ ++ EFI_STATUS Status; ++ RETURN_STATUS DecryptStatus; ++ CSV_SHARED_MEMORY_PROTOCOL *SharedMemory; ++ EFI_PHYSICAL_ADDRESS Memory; ++ EFI_PHYSICAL_ADDRESS EndMemory; ++ EFI_ALLOCATE_TYPE AllocateType; ++ UINT64 Size; ++ ++ Status = CsvInstallSharedMemoryProtocol (); ++ ++ if (EFI_ERROR (Status)) { ++ DEBUG ((EFI_D_ERROR, "fail to install CsvSharedMemory protocol\n")); ++ return Status; ++ } ++ ++ // ++ // Do nothing more when CSV is not enabled ++ // ++ if (!CsvIsEnabled ()) { ++ return EFI_SUCCESS; ++ } ++ ++ Status = gBS->LocateProtocol ( ++ &gCsvSharedMemoryProtocolGuid, ++ NULL, ++ (VOID**)&SharedMemory ++ ); ++ ++ if (Status == EFI_SUCCESS) { ++ ++ AllocateType = AllocateMaxAddress; ++ Memory = BASE_4GB - 1; ++ ++ Status = gBS->AllocatePages ( ++ AllocateType, ++ EfiBootServicesData, ++ CSV_SHARED_MEMORY_PAGE_NUMBER, ++ &Memory ++ ); ++ ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "fail to allocate CsvSharedMemory\n", SharedMemory)); ++ } else { ++ //Align to huge page ++ EndMemory = (Memory + CSV_SHARED_MEMORY_SIZE) & (~(HUGE_PAGE_SIZE - 1)); ++ Memory = ALIGN_VALUE(Memory, HUGE_PAGE_SIZE); ++ Size = (EndMemory > Memory) ? EndMemory - Memory : 0; ++ DecryptStatus = MemEncryptSevClearPageEncMask ( ++ 0, ++ Memory, ++ Size >> EFI_PAGE_SHIFT ++ ); ++ ASSERT_RETURN_ERROR (DecryptStatus); ++ ++ SharedMemory->CsvInitializeSharedMemoryList ( ++ SharedMemory, ++ (UINT64)Memory, ++ Size ++ ); ++ } ++ } else { ++ DEBUG ((DEBUG_ERROR, "fail to LocateProtocol gCsvSharedMemoryProtocolGuid\n")); ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/OvmfPkg/CsvDxe/CsvDxe.inf b/OvmfPkg/CsvDxe/CsvDxe.inf +new file mode 100644 +index 0000000..89e3703 +--- /dev/null ++++ b/OvmfPkg/CsvDxe/CsvDxe.inf +@@ -0,0 +1,45 @@ ++#/** @file ++# ++# Secure Isolated Virtualization ++# ++# Copyright (c) 2022, HYGON Inc. All rights reserved.
++# ++# This program and the accompanying materials are licensed and made available ++# under the terms and conditions of the BSD License which accompanies this ++# distribution. The full text of the license may be found at ++# http://opensource.org/licenses/bsd-license.php ++# ++# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED. ++# ++#**/ ++ ++[Defines] ++ INF_VERSION = 1.25 ++ BASE_NAME = CsvDxe ++ FILE_GUID = 829310c0-b9c4-11e9-9e16-9b10d744f884 ++ MODULE_TYPE = DXE_DRIVER ++ VERSION_STRING = 1.0 ++ ENTRY_POINT = CsvDxeEntryPoint ++ ++[Sources] ++ CsvDxe.c ++ CsvSharedMemory.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ OvmfPkg/OvmfPkg.dec ++ ++[LibraryClasses] ++ BaseLib ++ BaseMemoryLib ++ DebugLib ++ CsvLib ++ UefiDriverEntryPoint ++ ++[Depex] ++ TRUE ++ ++[Protocols] ++ gCsvSharedMemoryProtocolGuid +diff --git a/OvmfPkg/CsvDxe/CsvSharedMemory.c b/OvmfPkg/CsvDxe/CsvSharedMemory.c +new file mode 100644 +index 0000000..8674eaf +--- /dev/null ++++ b/OvmfPkg/CsvDxe/CsvSharedMemory.c +@@ -0,0 +1,208 @@ ++/** @file ++ ++ The protocol provides allocate, free the CSV shared memory. ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++STATIC LIST_ENTRY CsvSharedMemoryList = INITIALIZE_LIST_HEAD_VARIABLE (CsvSharedMemoryList); ++ ++// ++// Insert the initial shared memory address and length to list. ++// ++ ++EFI_STATUS ++EFIAPI ++CsvInitializeSharedMemoryList ( ++ IN CSV_SHARED_MEMORY_PROTOCOL *Protocol, ++ IN UINT64 Address, ++ IN UINT64 Length ++ ) ++{ ++ CsvSharedMemoryEntry *Entry; ++ ++ if (Length == 0) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ Entry = AllocatePool (sizeof (*Entry)); ++ if (Entry == NULL) { ++ DEBUG((DEBUG_ERROR, "CsvInitializeSharedMemoryList AllocatePool error\n")); ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ Entry->Start = Address; ++ Entry->Length = Length; ++ Entry->Signature = CSV_SHARED_MEMORY_SIGNATURE; ++ ++ InsertTailList (&CsvSharedMemoryList, &Entry->Link); ++ ++ return EFI_SUCCESS; ++} ++ ++EFI_STATUS ++EFIAPI ++CsvAllocateSharedMemory ( ++ IN CSV_SHARED_MEMORY_PROTOCOL *Protocol, ++ IN UINTN NumberOfPages, ++ OUT UINT64 *Memory ++ ) ++{ ++ LIST_ENTRY *Link; ++ CsvSharedMemoryEntry *Entry; ++ UINT64 MemoryLength; ++ ++ MemoryLength = (UINT64)NumberOfPages << EFI_PAGE_SHIFT; ++ ++ for (Link = CsvSharedMemoryList.ForwardLink; Link != &CsvSharedMemoryList; Link = Link->ForwardLink) { ++ Entry = CR (Link, CsvSharedMemoryEntry, Link, CSV_SHARED_MEMORY_SIGNATURE); ++ if (Entry->Length > MemoryLength) { ++ *Memory = (EFI_PHYSICAL_ADDRESS)Entry->Start; ++ Entry->Start = *Memory + MemoryLength; ++ Entry->Length -= MemoryLength; ++ break; ++ } else if (Entry->Length == MemoryLength) { ++ *Memory = (EFI_PHYSICAL_ADDRESS)Entry->Start; ++ RemoveEntryList (&Entry->Link); ++ FreePool (Entry); ++ break; ++ } ++ } ++ ++ ++ ++ if (Link == &CsvSharedMemoryList) { ++ DEBUG ((EFI_D_ERROR, "CsvAllocateSharedMemory fail to allocate %u pages\n", NumberOfPages)); ++ return EFI_NOT_FOUND; ++ } ++ else { ++ return EFI_SUCCESS; ++ } ++} ++ ++ ++ ++EFI_STATUS ++EFIAPI ++CsvFreeSharedMemory ( ++ IN CSV_SHARED_MEMORY_PROTOCOL *Protocol, ++ IN UINTN Pages, ++ IN UINT64 HostAddress ++ ) ++{ ++ LIST_ENTRY *Link; ++ CsvSharedMemoryEntry *Entry; ++ CsvSharedMemoryEntry *NewEntry; ++ UINT64 Memory; ++ UINT64 MemoryLength; ++ CsvSharedMemoryEntry *Previous = NULL; ++ BOOLEAN Inserted = FALSE; ++ ++ Memory = (UINT64)HostAddress; ++ MemoryLength = (UINT64)Pages << EFI_PAGE_SHIFT; ++ ++ for (Link = CsvSharedMemoryList.ForwardLink; ++ Link != &CsvSharedMemoryList; ++ Link = Link->ForwardLink) { ++ Entry = CR (Link, CsvSharedMemoryEntry, Link, CSV_SHARED_MEMORY_SIGNATURE); ++ if (Inserted) ++ goto Merge; ++ if (Entry->Start + Entry->Length == Memory) { ++ Entry->Length += MemoryLength; ++ Inserted = TRUE; ++ goto Merge; ++ } else if (Memory + MemoryLength < Entry->Start) { ++ NewEntry = AllocatePool (sizeof *NewEntry); ++ if (NewEntry == NULL) { ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ NewEntry->Start = Memory; ++ NewEntry->Length = MemoryLength; ++ NewEntry->Signature = CSV_SHARED_MEMORY_SIGNATURE; ++ ++ InsertTailList (&Entry->Link, &NewEntry->Link); ++ break; ++ } else if (Memory + MemoryLength == Entry->Start) { ++ Entry->Start = Memory; ++ Entry->Length += MemoryLength; ++ break; ++ } else if (Link->ForwardLink == &CsvSharedMemoryList) { ++ // ++ // Insert to tail ++ // ++ NewEntry = AllocatePool (sizeof *NewEntry); ++ if (NewEntry == NULL) { ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ NewEntry->Start = Memory; ++ NewEntry->Length = MemoryLength; ++ NewEntry->Signature = CSV_SHARED_MEMORY_SIGNATURE; ++ InsertHeadList (Link, &NewEntry->Link); ++ break; ++ } ++ ++Merge: ++ if (Previous) { ++ if (Previous->Start + Previous->Length == Entry->Start) { ++ Entry->Start = Previous->Start; ++ Entry->Length += Previous->Length; ++ RemoveEntryList (&Previous->Link); ++ FreePool (Previous); ++ } ++ break; ++ } else { ++ Previous = Entry; ++ } ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++CSV_SHARED_MEMORY_PROTOCOL mCsvSharedMemory = { ++ CsvInitializeSharedMemoryList, ++ CsvAllocateSharedMemory, ++ CsvFreeSharedMemory ++}; ++ ++/** ++ Initialize CsvSharedMemory Protocol. ++ ++**/ ++EFI_STATUS ++EFIAPI ++CsvInstallSharedMemoryProtocol ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_HANDLE Handle; ++ ++ Handle = NULL; ++ Status = gBS->InstallMultipleProtocolInterfaces ( ++ &Handle, ++ &gCsvSharedMemoryProtocolGuid, ++ &mCsvSharedMemory, ++ NULL ++ ); ++ return Status; ++} +diff --git a/OvmfPkg/CsvDxe/CsvSharedMemory.h b/OvmfPkg/CsvDxe/CsvSharedMemory.h +new file mode 100644 +index 0000000..8828515 +--- /dev/null ++++ b/OvmfPkg/CsvDxe/CsvSharedMemory.h +@@ -0,0 +1,29 @@ ++/** @file ++ CSV shared memory management protocol ++ ++ Copyright (C) 2022 HYGON. ++ ++ This program and the accompanying materials ++ are licensed and made available under the terms and conditions of the BSD License ++ which accompanies this distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#ifndef _CSV_SHARED_MEMORY_H_ ++#define _CSV_SHARED_MEMORY_H_ ++ ++// ++// Install SHARED_MEMORY protocol . ++// ++ ++EFI_STATUS ++EFIAPI ++CsvInstallSharedMemoryProtocol ( ++ VOID ++ ); ++ ++#endif +diff --git a/OvmfPkg/Include/Protocol/CsvSharedMemory.h b/OvmfPkg/Include/Protocol/CsvSharedMemory.h +new file mode 100644 +index 0000000..0c3f23d +--- /dev/null ++++ b/OvmfPkg/Include/Protocol/CsvSharedMemory.h +@@ -0,0 +1,99 @@ ++/** @file ++ CSV shared memory management protocol ++ ++ Copyright (C) 2022 HYGON. ++ ++ This program and the accompanying materials ++ are licensed and made available under the terms and conditions of the BSD License ++ which accompanies this distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#ifndef __PROTOCOL_CSV_SHARED_MEMORY_H__ ++#define __PROTOCOL_CSV_SHARED_MEMORY_H__ ++ ++#define CSV_SHARED_MEMORY_PAGE_NUMBER (16384ULL) ++#define CSV_SHARED_MEMORY_SIZE ((CSV_SHARED_MEMORY_PAGE_NUMBER)*(SIZE_4KB)) ++ ++/// ++/// Forward declaration ++/// ++typedef struct _CSV_SHARED_MEMORY_PROTOCOL CSV_SHARED_MEMORY_PROTOCOL; ++ ++ ++/// ++/// Function prototypes ++/// ++ ++/** ++ Initialize the list to manage the CSV shared memory. ++ Insert the start address and length. ++ ++ @param This A pointer to CSV_SHARED_MEMORY_PROTOCOL instance. ++ @param Address The start address of the shared memory. ++ @param Length The length of the shared memory. ++ ++**/ ++typedef ++EFI_STATUS ++(EFIAPI *CSV_INITIALIZE_SHARED_MEMORY_LIST)( ++ IN CSV_SHARED_MEMORY_PROTOCOL *This, ++ IN UINT64 Address, ++ IN UINT64 Length ++ ); ++ ++/** ++ Allocate buffer from the shared memory. ++ ++ @param This A pointer to CSV_SHARED_MEMORY_PROTOCOL instance. ++ @param NumberOfPages The length of page number. ++ @param Memory When success, allocated memory will be stored in. ++ ++ @return On success, EFI_SUCCESS. Otherwise an errno value ++ indicating the type of failure. ++**/ ++typedef ++EFI_STATUS ++(EFIAPI *CSV_ALLOCATE_SHARED_MEMORY)( ++ IN CSV_SHARED_MEMORY_PROTOCOL *This, ++ IN UINTN NumberOfPages, ++ OUT UINT64 *Memory ++ ); ++ ++/** ++ Free buffer to the shared memory. ++ ++ @param This A pointer to CSV_SHARED_MEMORY_PROTOCOL instance. ++ @param NumberOfPages The page number. ++ @param Memory The allocated memory to be freed. ++ ++ @return On success, EFI_SUCCESS. Otherwise an errno value ++ indicating the type of failure. ++**/ ++typedef ++EFI_STATUS ++(EFIAPI *CSV_FREE_SHARED_MEMORY)( ++ IN CSV_SHARED_MEMORY_PROTOCOL *This, ++ IN UINTN NumberOfPages, ++ IN UINT64 Memory ++ ); ++ ++/// ++/// Protocol structure ++/// ++struct _CSV_SHARED_MEMORY_PROTOCOL { ++ // ++ // Protocol data fields ++ // ++ CSV_INITIALIZE_SHARED_MEMORY_LIST CsvInitializeSharedMemoryList; ++ CSV_ALLOCATE_SHARED_MEMORY CsvAllocateSharedMemory; ++ CSV_FREE_SHARED_MEMORY CsvFreeSharedMemory; ++}; ++ ++extern EFI_GUID gCsvSharedMemoryProtocolGuid; ++ ++#endif +diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec +index 6f4afb8..d8f9be3 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -152,6 +152,7 @@ + gEfiLegacyInterruptProtocolGuid = {0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}} + gEfiVgaMiniPortProtocolGuid = {0xc7735a2f, 0x88f5, 0x4882, {0xae, 0x63, 0xfa, 0xac, 0x8c, 0x8b, 0x86, 0xb3}} + gOvmfLoadedX86LinuxKernelProtocolGuid = {0xa3edc05d, 0xb618, 0x4ff6, {0x95, 0x52, 0x76, 0xd7, 0x88, 0x63, 0x43, 0xc8}} ++ gCsvSharedMemoryProtocolGuid = {0x0c795ed0, 0xbf0a, 0x11e9, {0x99, 0xbe, 0x50, 0x9a, 0x4c, 0x01, 0x1e, 0xd1}} + + [PcdsFixedAtBuild] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|0x0|UINT32|0 +diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc +index 9e4dcce..edc0f0e 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -982,6 +982,7 @@ + OvmfPkg/PlatformDxe/Platform.inf + OvmfPkg/AmdSevDxe/AmdSevDxe.inf + OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++ OvmfPkg/CsvDxe/CsvDxe.inf + + !if $(SMM_REQUIRE) == TRUE + OvmfPkg/SmmAccess/SmmAccess2Dxe.inf +diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf +index e33a40c..f05405b 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.fdf ++++ b/OvmfPkg/OvmfPkgIa32X64.fdf +@@ -339,6 +339,7 @@ INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf + INF OvmfPkg/PlatformDxe/Platform.inf + INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf + INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++INF OvmfPkg/CsvDxe/CsvDxe.inf + + !if $(SMM_REQUIRE) == TRUE + INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf +diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc +index e62b533..763214d 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -980,6 +980,7 @@ + OvmfPkg/PlatformDxe/Platform.inf + OvmfPkg/AmdSevDxe/AmdSevDxe.inf + OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++ OvmfPkg/CsvDxe/CsvDxe.inf + + !if $(SMM_REQUIRE) == TRUE + OvmfPkg/SmmAccess/SmmAccess2Dxe.inf +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index a3634dd..0f04acb 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -358,6 +358,7 @@ INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf + INF OvmfPkg/PlatformDxe/Platform.inf + INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf + INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++INF OvmfPkg/CsvDxe/CsvDxe.inf + + !if $(SMM_REQUIRE) == TRUE + INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf +-- +2.17.1 + diff --git a/0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch b/0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch new file mode 100644 index 0000000..9b4b800 --- /dev/null +++ b/0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch @@ -0,0 +1,724 @@ +From 8f82f4b8d86ca1b10b9353b484c403c628b3b560 Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 16:54:44 +0800 +Subject: [PATCH 37/46] anolis: OvmfPkg/IoMmuDxe: Add CsvIoMmu protocol + +Create the dedicated IoMmu protocol for CSV virtual machine. +And Install it during CSV VM boots up. + +It calls the CsvSharedMemoryProtocol to allocate shared memory +for DMA operations. + +- AllocateBuffer() allocates the shared memory. + +- FreeBuffer() frees the shared memory. + +- Map() does nothing when BusMasterCommonBuffer[64] is requested + Otherwise, Map() allocates shared memory. + +- Unmap() does nothing when cleaning up a BusMasterCommonBuffer[64] + operation. Otherwise, Unmap() frees the shared memory. + +Signed-off-by: Xin Jiang +Change-Id: If49857f45c639341a96605722b06babfa1553874 +--- + OvmfPkg/IoMmuDxe/CsvIoMmu.c | 592 ++++++++++++++++++++++++++++++++++ + OvmfPkg/IoMmuDxe/CsvIoMmu.h | 29 ++ + OvmfPkg/IoMmuDxe/IoMmuDxe.c | 10 + + OvmfPkg/IoMmuDxe/IoMmuDxe.inf | 6 +- + 4 files changed, 636 insertions(+), 1 deletion(-) + create mode 100644 OvmfPkg/IoMmuDxe/CsvIoMmu.c + create mode 100644 OvmfPkg/IoMmuDxe/CsvIoMmu.h + +diff --git a/OvmfPkg/IoMmuDxe/CsvIoMmu.c b/OvmfPkg/IoMmuDxe/CsvIoMmu.c +new file mode 100644 +index 0000000..c5df6b9 +--- /dev/null ++++ b/OvmfPkg/IoMmuDxe/CsvIoMmu.c +@@ -0,0 +1,592 @@ ++/** @file ++ ++ The protocol provides support to allocate, free, map and umap a DMA buffer ++ for bus master (e.g PciHostBridge). When CSV is enabled, the DMA operations ++ must be performed on non-secure memory so we have to allocate the DMA buffer ++ from non-secure memory. ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "CsvIoMmu.h" ++ ++#define MAP_INFO_SIG SIGNATURE_64 ('M', 'A', 'P', '_', 'I', 'N', 'F', 'O') ++ ++typedef struct { ++ UINT64 Signature; ++ LIST_ENTRY Link; ++ EDKII_IOMMU_OPERATION Operation; ++ UINTN NumberOfBytes; ++ UINTN NumberOfPages; ++ EFI_PHYSICAL_ADDRESS SecureAddress; ++ EFI_PHYSICAL_ADDRESS UnSecureAddress; ++} MAP_INFO; ++ ++// ++// List of the MAP_INFO structures that have been set up by IoMmuMap() and not ++// yet torn down by IoMmuUnmap(). The list represents the full set of mappings ++// currently in effect. ++// ++STATIC LIST_ENTRY mMapInfos = INITIALIZE_LIST_HEAD_VARIABLE (mMapInfos); ++ ++// ++// ASCII names for EDKII_IOMMU_OPERATION constants, for debug logging. ++// ++STATIC CONST CHAR8 * CONST ++mBusMasterOperationName[EdkiiIoMmuOperationMaximum] = { ++ "Read", ++ "Write", ++ "CommonBuffer", ++ "Read64", ++ "Write64", ++ "CommonBuffer64" ++}; ++ ++STATIC CSV_SHARED_MEMORY_PROTOCOL *SharedMemory; ++STATIC ++EFI_STATUS ++EFIAPI ++CsvAllocSharedPage( ++ IN UINTN Pages, ++ OUT EFI_PHYSICAL_ADDRESS *Address ++ ) ++{ ++ EFI_STATUS Status; ++ ++ Status = SharedMemory->CsvAllocateSharedMemory ( ++ SharedMemory, ++ Pages, ++ (UINT64*)Address ++ ); ++ ++ return Status; ++} ++ ++STATIC ++EFI_STATUS ++EFIAPI ++CsvFreeSharedPage( ++ IN UINTN Pages, ++ IN VOID *HostAddress ++ ) ++{ ++ EFI_STATUS Status; ++ ++ Status = SharedMemory->CsvFreeSharedMemory ( ++ SharedMemory, ++ Pages, ++ (UINTN)HostAddress ++ ); ++ ++ return Status; ++} ++ ++/** ++ Provides the controller-specific addresses required to access system memory ++ from a DMA bus master. ++ On CSV guest, the DMA openerations must be done on non-secure memory which ++ is the shared memory between the guest and QEMU. ++ ++ @param This The protocol instance pointer. ++ @param Operation Indicates if the bus master is going to read or ++ write to system memory. ++ @param HostAddress The system memory address to map to the PCI ++ controller. ++ @param NumberOfBytes On input the number of bytes to map. On output ++ the number of bytes that were mapped. ++ @param DeviceAddress The resulting map address for the bus master ++ PCI controller to use to access the hosts ++ HostAddress. ++ @param Mapping A resulting value to pass to Unmap(). ++ ++ @retval EFI_SUCCESS The range was mapped for the returned ++ NumberOfBytes. ++ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common ++ buffer. ++ @retval EFI_INVALID_PARAMETER One or more parameters are invalid. ++ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a ++ lack of resources. ++ @retval EFI_DEVICE_ERROR The system hardware could not map the requested ++ address. ++ ++**/ ++EFI_STATUS ++EFIAPI ++CsvIoMmuMap ( ++ IN EDKII_IOMMU_PROTOCOL *This, ++ IN EDKII_IOMMU_OPERATION Operation, ++ IN VOID *HostAddress, ++ IN OUT UINTN *NumberOfBytes, ++ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, ++ OUT VOID **Mapping ++ ) ++{ ++ EFI_STATUS Status; ++ MAP_INFO *MapInfo; ++ ++ DEBUG (( ++ DEBUG_VERBOSE, ++ "%a: Operation=%a Operation=%u Host=0x%p Bytes=0x%Lx\n", ++ __FUNCTION__, ++ ((Operation >= 0 && ++ Operation < ARRAY_SIZE (mBusMasterOperationName)) ? ++ mBusMasterOperationName[Operation] : ++ "Invalid"), ++ Operation, ++ HostAddress, ++ (UINT64)((NumberOfBytes == NULL) ? 0 : *NumberOfBytes) ++ )); ++ ++ if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || ++ Mapping == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Allocate a MAP_INFO structure to remember the mapping when Unmap() is ++ // called later. ++ // ++ MapInfo = AllocatePool (sizeof (MAP_INFO)); ++ if (MapInfo == NULL) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto Failed; ++ } ++ ++ ZeroMem (&MapInfo->Link, sizeof MapInfo->Link); ++ MapInfo->Operation = Operation; ++ MapInfo->NumberOfBytes = *NumberOfBytes; ++ MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes); ++ MapInfo->Signature = MAP_INFO_SIG; ++ ++ switch (Operation) { ++ // ++ // For BusMasterRead[64] and BusMasterWrite[64] operations, a bounce buffer ++ // is necessary regardless of whether the original (crypted) buffer crosses ++ // the 4GB limit or not -- we have to allocate a separate plaintext buffer. ++ // The only variable is whether the plaintext buffer should be under 4GB. ++ // ++ case EdkiiIoMmuOperationBusMasterRead: ++ case EdkiiIoMmuOperationBusMasterWrite: ++ // ++ // fall through ++ // ++ case EdkiiIoMmuOperationBusMasterRead64: ++ case EdkiiIoMmuOperationBusMasterWrite64: ++ // ++ // Allocate the implicit plaintext bounce buffer. ++ // ++ Status = CsvAllocSharedPage ( ++ MapInfo->NumberOfPages, ++ &MapInfo->UnSecureAddress ++ ); ++ if (EFI_ERROR (Status)) { ++ goto FreeMapInfo; ++ } ++ MapInfo->SecureAddress = (UINTN)HostAddress; ++ if (Operation == EdkiiIoMmuOperationBusMasterRead || ++ Operation == EdkiiIoMmuOperationBusMasterRead64) { ++ CopyMem ( ++ (VOID *) (UINTN) MapInfo->UnSecureAddress, ++ (VOID *) (UINTN) MapInfo->SecureAddress, ++ MapInfo->NumberOfBytes ++ ); ++ } ++ break; ++ ++ // ++ // For BusMasterCommonBuffer[64] operations, ++ // AllocateBuffer already returns the plain-text, ++ // No need to decrypt the data. ++ // ++ case EdkiiIoMmuOperationBusMasterCommonBuffer: ++ case EdkiiIoMmuOperationBusMasterCommonBuffer64: ++ MapInfo->UnSecureAddress = (UINTN)HostAddress; ++ MapInfo->SecureAddress = (UINTN)HostAddress; ++ break; ++ ++ default: ++ // ++ // Operation is invalid ++ // ++ Status = EFI_INVALID_PARAMETER; ++ goto FreeMapInfo; ++ } ++ ++ // ++ // Track all MAP_INFO structures. ++ // ++ InsertHeadList (&mMapInfos, &MapInfo->Link); ++ // ++ // Populate output parameters. ++ // ++ *DeviceAddress = MapInfo->UnSecureAddress; ++ *Mapping = MapInfo; ++ ++ DEBUG (( ++ DEBUG_VERBOSE, ++ "%a: Mapping=0x%p Device=0x%Lx Host=0x%Lx Pages=0x%Lx\n", ++ __FUNCTION__, ++ MapInfo, ++ MapInfo->UnSecureAddress, ++ MapInfo->SecureAddress, ++ (UINT64)MapInfo->NumberOfPages ++ )); ++ ++ return EFI_SUCCESS; ++ ++FreeMapInfo: ++ FreePool (MapInfo); ++ ++Failed: ++ *NumberOfBytes = 0; ++ return Status; ++} ++ ++/** ++ Completes the Map() operation and releases any corresponding resources. ++ ++ This is an internal worker function that only extends the Map() API with ++ the MemoryMapLocked parameter. ++ ++ @param This The protocol instance pointer. ++ @param Mapping The mapping value returned from Map(). ++ @param MemoryMapLocked The function is executing on the stack of ++ gBS->ExitBootServices(); changes to the UEFI ++ memory map are forbidden. ++ ++ @retval EFI_SUCCESS The range was unmapped. ++ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by ++ Map(). ++ @retval EFI_DEVICE_ERROR The data was not committed to the target system ++ memory. ++**/ ++STATIC ++EFI_STATUS ++EFIAPI ++CsvIoMmuUnmapWorker ( ++ IN EDKII_IOMMU_PROTOCOL *This, ++ IN VOID *Mapping, ++ IN BOOLEAN MemoryMapLocked ++ ) ++{ ++ MAP_INFO *MapInfo; ++ EDKII_IOMMU_OPERATION Operation; ++ ++ if (Mapping == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ MapInfo = (MAP_INFO *)Mapping; ++ Operation = MapInfo->Operation; ++ ++ DEBUG (( ++ DEBUG_VERBOSE, ++ "%a: Mapping=0x%p MemoryMapLocked=%d Operation %a Operation %d\n", ++ __FUNCTION__, ++ Mapping, ++ MemoryMapLocked, ++ ((Operation >= 0 && ++ Operation < ARRAY_SIZE (mBusMasterOperationName)) ? ++ mBusMasterOperationName[Operation] : ++ "Invalid"), ++ Operation ++ )); ++ ++ switch (MapInfo->Operation) { ++ case EdkiiIoMmuOperationBusMasterWrite: ++ case EdkiiIoMmuOperationBusMasterWrite64: ++ CopyMem ( ++ (VOID *) (UINTN) MapInfo->SecureAddress, ++ (VOID *) (UINTN) MapInfo->UnSecureAddress, ++ MapInfo->NumberOfBytes ++ ); ++ case EdkiiIoMmuOperationBusMasterRead: ++ case EdkiiIoMmuOperationBusMasterRead64: ++ ZeroMem ( ++ (VOID *)(UINTN)MapInfo->UnSecureAddress, ++ EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages) ++ ); ++ CsvFreeSharedPage( ++ MapInfo->NumberOfPages, ++ (VOID*)(UINTN)MapInfo->UnSecureAddress ++ ); ++ ++ default: ++ break; ++ } ++ ++ // ++ // Forget the MAP_INFO structure, then free it (unless the UEFI memory map is ++ // locked). ++ // ++ RemoveEntryList (&MapInfo->Link); ++ if (!MemoryMapLocked) { ++ FreePool (MapInfo); ++ } ++ ++ return EFI_SUCCESS; ++ ++} ++ ++/** ++ Completes the Map() operation and releases any corresponding resources. ++ ++ @param This The protocol instance pointer. ++ @param Mapping The mapping value returned from Map(). ++ ++ @retval EFI_SUCCESS The range was unmapped. ++ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by ++ Map(). ++ @retval EFI_DEVICE_ERROR The data was not committed to the target system ++ memory. ++**/ ++EFI_STATUS ++EFIAPI ++CsvIoMmuUnmap ( ++ IN EDKII_IOMMU_PROTOCOL *This, ++ IN VOID *Mapping ++ ) ++{ ++ return CsvIoMmuUnmapWorker ( ++ This, ++ Mapping, ++ FALSE // MemoryMapLocked ++ ); ++} ++ ++/** ++ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or ++ OperationBusMasterCommonBuffer64 mapping. ++ ++ @param This The protocol instance pointer. ++ @param Type This parameter is not used and must be ignored. ++ @param MemoryType The type of memory to allocate, ++ EfiBootServicesData or EfiRuntimeServicesData. ++ @param Pages The number of pages to allocate. ++ @param HostAddress A pointer to store the base system memory ++ address of the allocated range. ++ @param Attributes The requested bit mask of attributes for the ++ allocated range. ++ ++ @retval EFI_SUCCESS The requested memory pages were allocated. ++ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal ++ attribute bits are MEMORY_WRITE_COMBINE and ++ MEMORY_CACHED. ++ @retval EFI_INVALID_PARAMETER One or more parameters are invalid. ++ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. ++ ++**/ ++EFI_STATUS ++EFIAPI ++CsvIoMmuAllocateBuffer ( ++ IN EDKII_IOMMU_PROTOCOL *This, ++ IN EFI_ALLOCATE_TYPE Type, ++ IN EFI_MEMORY_TYPE MemoryType, ++ IN UINTN Pages, ++ IN OUT VOID **HostAddress, ++ IN UINT64 Attributes ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_PHYSICAL_ADDRESS PhysicalAddress; ++ ++ DEBUG (( ++ DEBUG_VERBOSE, ++ "%a: MemoryType=%u Pages=0x%Lx Attributes=0x%Lx\n", ++ __FUNCTION__, ++ (UINT32)MemoryType, ++ (UINT64)Pages, ++ Attributes ++ )); ++ ++ // ++ // Validate Attributes ++ // ++ if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) { ++ return EFI_UNSUPPORTED; ++ } ++ ++ // ++ // Check for invalid inputs ++ // ++ if (HostAddress == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // The only valid memory types are EfiBootServicesData and ++ // EfiRuntimeServicesData ++ // ++ if (MemoryType != EfiBootServicesData && ++ MemoryType != EfiRuntimeServicesData) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // We'll need a header page for the COMMON_BUFFER_HEADER structure. ++ // ++ if (Pages > MAX_UINTN - 1) { ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ Status = CsvAllocSharedPage (Pages,&PhysicalAddress); ++ if (Status != EFI_SUCCESS){ ++ goto error; ++ } ++ ++ ++ *HostAddress = (VOID *)(UINTN)PhysicalAddress; ++ ++ return EFI_SUCCESS; ++ ++error: ++ return Status; ++} ++ ++/** ++ Frees memory that was allocated with AllocateBuffer(). ++ ++ @param This The protocol instance pointer. ++ @param Pages The number of pages to free. ++ @param HostAddress The base system memory address of the allocated ++ range. ++ ++ @retval EFI_SUCCESS The requested memory pages were freed. ++ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and ++ Pages was not allocated with AllocateBuffer(). ++ ++**/ ++EFI_STATUS ++EFIAPI ++CsvIoMmuFreeBuffer ( ++ IN EDKII_IOMMU_PROTOCOL *This, ++ IN UINTN Pages, ++ IN VOID *HostAddress ++ ) ++{ ++ ++ EFI_STATUS Status; ++ ++ if (HostAddress == NULL || Pages == 0) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ DEBUG (( ++ DEBUG_VERBOSE, ++ "%a: Host=0x%p Pages=0x%Lx\n", ++ __FUNCTION__, ++ HostAddress, ++ (UINT64)Pages ++ )); ++ ++ Status = CsvFreeSharedPage (Pages, HostAddress); ++ ++ return Status; ++} ++ ++ ++/** ++ Set IOMMU attribute for a system memory. ++ ++ @param[in] This The protocol instance pointer. ++ @param[in] DeviceHandle The device who initiates the DMA access ++ request. ++ @param[in] Mapping The mapping value returned from Map(). ++ @param[in] IoMmuAccess The IOMMU access. ++ ++ @retval EFI_SUCCESS The IoMmuAccess is set for the memory range ++ specified by DeviceAddress and Length. ++ @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle. ++ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by ++ Map(). ++ @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination ++ of access. ++ @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU. ++ @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported ++ by the IOMMU. ++ @retval EFI_UNSUPPORTED The IOMMU does not support the memory range ++ specified by Mapping. ++ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to ++ modify the IOMMU access. ++ @retval EFI_DEVICE_ERROR The IOMMU device reported an error while ++ attempting the operation. ++ ++**/ ++EFI_STATUS ++EFIAPI ++CsvIoMmuSetAttribute ( ++ IN EDKII_IOMMU_PROTOCOL *This, ++ IN EFI_HANDLE DeviceHandle, ++ IN VOID *Mapping, ++ IN UINT64 IoMmuAccess ++ ) ++{ ++ return EFI_UNSUPPORTED; ++} ++ ++EDKII_IOMMU_PROTOCOL mCsv = { ++ EDKII_IOMMU_PROTOCOL_REVISION, ++ CsvIoMmuSetAttribute, ++ CsvIoMmuMap, ++ CsvIoMmuUnmap, ++ CsvIoMmuAllocateBuffer, ++ CsvIoMmuFreeBuffer, ++}; ++ ++/** ++ Initialize Iommu Protocol. ++ ++**/ ++EFI_STATUS ++EFIAPI ++CsvInstallIoMmuProtocol ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_HANDLE Handle; ++ ++ Status = gBS->LocateProtocol ( ++ &gCsvSharedMemoryProtocolGuid, ++ NULL, ++ (VOID**)&SharedMemory ++ ); ++ ++ if (EFI_ERROR (Status)) { ++ goto error; ++ } ++ ++ Handle = NULL; ++ Status = gBS->InstallMultipleProtocolInterfaces ( ++ &Handle, ++ &gEdkiiIoMmuProtocolGuid, ++ &mCsv, ++ NULL ++ ); ++ if (EFI_ERROR (Status)) { ++ goto error; ++ } ++ ++ return EFI_SUCCESS; ++ ++error: ++ return Status; ++} +diff --git a/OvmfPkg/IoMmuDxe/CsvIoMmu.h b/OvmfPkg/IoMmuDxe/CsvIoMmu.h +new file mode 100644 +index 0000000..d48a02c +--- /dev/null ++++ b/OvmfPkg/IoMmuDxe/CsvIoMmu.h +@@ -0,0 +1,29 @@ ++/** @file ++ ++ The protocol provides support to allocate, free, map and umap a DMA buffer ++ for bus master (e.g PciHostBridge). When CSV is enabled, the DMA operations ++ must be performed on unencrypted buffer hence protocol clear the encryption ++ bit from the DMA buffer. ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++ ++**/ ++ ++#ifndef _CSV_IOMMU_H_ ++#define _CSV_IOMMU_H_ ++ ++EFI_STATUS ++EFIAPI ++CsvInstallIoMmuProtocol ( ++ VOID ++ ); ++ ++#endif +diff --git a/OvmfPkg/IoMmuDxe/IoMmuDxe.c b/OvmfPkg/IoMmuDxe/IoMmuDxe.c +index 13df8ba..35e5df9 100644 +--- a/OvmfPkg/IoMmuDxe/IoMmuDxe.c ++++ b/OvmfPkg/IoMmuDxe/IoMmuDxe.c +@@ -9,7 +9,9 @@ + + **/ + ++#include + #include "AmdSevIoMmu.h" ++#include "CsvIoMmu.h" + + EFI_STATUS + EFIAPI +@@ -21,6 +23,14 @@ IoMmuDxeEntryPoint ( + EFI_STATUS Status; + EFI_HANDLE Handle; + ++ if (CsvIsEnabled ()) { ++ Status = CsvInstallIoMmuProtocol (); ++ if (Status != EFI_SUCCESS) { ++ DEBUG((EFI_D_ERROR, "fail to install CSV IOMMU\n")); ++ } ++ return Status; ++ } ++ + // + // When SEV is enabled, install IoMmu protocol otherwise install the + // placeholder protocol so that other dependent module can run. +diff --git a/OvmfPkg/IoMmuDxe/IoMmuDxe.inf b/OvmfPkg/IoMmuDxe/IoMmuDxe.inf +index 2ebd74e..6b89c6a 100644 +--- a/OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++++ b/OvmfPkg/IoMmuDxe/IoMmuDxe.inf +@@ -21,6 +21,8 @@ + AmdSevIoMmu.c + AmdSevIoMmu.h + IoMmuDxe.c ++ CsvIoMmu.c ++ CsvIoMmu.h + + [Packages] + MdePkg/MdePkg.dec +@@ -35,10 +37,12 @@ + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint ++ CsvLib + + [Protocols] + gEdkiiIoMmuProtocolGuid ## SOMETIME_PRODUCES + gIoMmuAbsentProtocolGuid ## SOMETIME_PRODUCES ++ gCsvSharedMemoryProtocolGuid + + [Depex] +- TRUE ++ gCsvSharedMemoryProtocolGuid +-- +2.17.1 + diff --git a/0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch b/0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch new file mode 100644 index 0000000..6aeeadf --- /dev/null +++ b/0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch @@ -0,0 +1,137 @@ +From 8a7ac3e25c1e8a62852a64d0a303e948b0e1499a Mon Sep 17 00:00:00 2001 +From: Xin Jiang +Date: Tue, 15 Aug 2023 17:15:53 +0800 +Subject: [PATCH 38/46] anolis: OvmfPkg: Reserve a CPUID table page for CSV + guest + +Reserve a page for CPUID table which will be initialized by firmware. +In future, A CSV guest should get CPUID value from a CPUID table +which has been validated by firmware rather than requesting them from +hypervisor via a VMGEXIT. + +Signed-off-by: Xin Jiang +Change-Id: Ic09af8667c65ac83eef5a2a4a1e69d0506cd89d7 +--- + OvmfPkg/OvmfPkg.dec | 4 ++++ + OvmfPkg/OvmfPkgX64.fdf | 3 +++ + OvmfPkg/PlatformPei/Csv.c | 6 ++++++ + OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++ + OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 15 +++++++++++++++ + OvmfPkg/ResetVector/ResetVector.inf | 2 ++ + OvmfPkg/ResetVector/ResetVector.nasmb | 2 ++ + 7 files changed, 34 insertions(+) + +diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec +index d8f9be3..7e6a6a2 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -359,6 +359,10 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|0|UINT32|0x58 + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize|0|UINT32|0x59 + ++ ## the base address of the cpuid table page used by CSV. ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|0|UINT32|0x60 ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize|0|UINT32|0x61 ++ + [PcdsDynamic, PcdsDynamicEx] + gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 0f04acb..04efa62 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -91,6 +91,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.P + 0x00D000|0x002000 + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize + ++0x00F000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize ++ + 0x010000|0x010000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + +diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c +index 44e81e1..f7c87ac 100644 +--- a/OvmfPkg/PlatformPei/Csv.c ++++ b/OvmfPkg/PlatformPei/Csv.c +@@ -56,6 +56,12 @@ CsvInitializeMemInfo ( + (UINT64)(UINTN) FixedPcdGet32 (PcdCsvDefaultSecureCallSize), + EfiReservedMemoryType + ); ++ ++ BuildMemoryAllocationHob ( ++ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdOvmfCsvCpuidBase), ++ (UINT64)(UINTN) FixedPcdGet32 (PcdOvmfCsvCpuidSize), ++ EfiReservedMemoryType ++ ); + } + + VOID +diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf +index cb0582c..bed4dcf 100644 +--- a/OvmfPkg/PlatformPei/PlatformPei.inf ++++ b/OvmfPkg/PlatformPei/PlatformPei.inf +@@ -123,6 +123,8 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize + + [FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable +diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +index c32b608..f282692 100644 +--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm ++++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +@@ -63,6 +63,21 @@ csvSecureCallBase: + DB 0xAB, 0x21, 0x6B, 0x27, 0x5D, 0x55, 0x56, 0xA5 + csvSecureCallEnd: + ++; ++; CSV cpuid table ++; ++; Provide cpuid table page when boot up for CSV guest ++; ++; GUID : 1b4c70e6-07e6-4e4e-8f28-0eaf871a0752 ++; ++csvCpuidTableBase: ++ DD CSV_CPUID_TABLE_SIZE ++ DD CSV_CPUID_TABLE_BASE ++ DW csvCpuidTableEnd - csvCpuidTableBase ++ DB 0xE6, 0x70, 0x4C, 0x1B, 0xE6, 0x07, 0x4E, 0x4E ++ DB 0x8F, 0x28, 0x0E, 0xAF, 0x87, 0x1A, 0x07, 0x52 ++csvCpuidTableEnd: ++ + ; + ; TDX Metadata offset block + ; +diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf +index 38c1720..e35c17b 100644 +--- a/OvmfPkg/ResetVector/ResetVector.inf ++++ b/OvmfPkg/ResetVector/ResetVector.inf +@@ -37,6 +37,8 @@ + gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase +diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb +index ca00f64..4e7c7ad 100644 +--- a/OvmfPkg/ResetVector/ResetVector.nasmb ++++ b/OvmfPkg/ResetVector/ResetVector.nasmb +@@ -106,6 +106,8 @@ + + %define CSV_DEFAULT_SECURE_CALL_BASE FixedPcdGet32 (PcdCsvDefaultSecureCallBase) + %define CSV_DEFAULT_SECURE_CALL_SIZE FixedPcdGet32 (PcdCsvDefaultSecureCallSize) ++ %define CSV_CPUID_TABLE_BASE FixedPcdGet32 (PcdOvmfCsvCpuidBase) ++ %define CSV_CPUID_TABLE_SIZE FixedPcdGet32 (PcdOvmfCsvCpuidSize) + + %include "X64/IntelTdxMetadata.asm" + %include "Ia32/Flat32ToFlat64.asm" +-- +2.17.1 + diff --git a/0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch b/0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch new file mode 100644 index 0000000..a8c2c34 --- /dev/null +++ b/0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch @@ -0,0 +1,325 @@ +From 118d8bd819dfd2300798481d8c89a9c37e54a32c Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Thu, 19 Aug 2021 12:35:50 +0000 +Subject: [PATCH 39/46] OvmfPkg/BaseMemEncryptLib: Detect SEV live migration + feature. + +Add support to check if we are running inside KVM HVM and +KVM HVM supports SEV Live Migration feature. + +Cc: Jordan Justen +Cc: Ard Biesheuvel +Signed-off-by: Ashish Kalra +Change-Id: I29fa5047198c9c3c6965c36b5e221b48c277dfc9 +--- + OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 ++++ + .../DxeMemEncryptSevLibInternal.c | 41 +++++++++++++ + .../PeiDxeMemEncryptSevLibInternal.c | 57 +++++++++++++++++++ + .../PeiDxeMemEncryptSevLibInternal.h | 31 ++++++++++ + .../PeiMemEncryptSevLibInternal.c | 41 +++++++++++++ + .../SecMemEncryptSevLibInternal.c | 18 ++++++ + 6 files changed, 200 insertions(+) + create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h + +diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h +index adc490e..ea251f1 100644 +--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h ++++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h +@@ -71,6 +71,18 @@ MemEncryptSevIsEnabled ( + VOID + ); + ++/** ++ Returns a boolean to indicate whether SEV live migration is enabled. ++ ++ @retval TRUE SEV live migration is enabled ++ @retval FALSE SEV live migration is not enabled ++**/ ++BOOLEAN ++EFIAPI ++MemEncryptSevLiveMigrationIsEnabled ( ++ VOID ++ ); ++ + /** + This function clears memory encryption bit for the memory region specified by + BaseAddress and NumPages from the current page table context. +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c +index 2816f85..df73a83 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c +@@ -17,9 +17,13 @@ + #include + #include + ++#include "PeiDxeMemEncryptSevLibInternal.h" ++ + STATIC BOOLEAN mSevStatus = FALSE; + STATIC BOOLEAN mSevEsStatus = FALSE; + STATIC BOOLEAN mSevStatusChecked = FALSE; ++STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; ++STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; + + STATIC UINT64 mSevEncryptionMask = 0; + STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; +@@ -106,6 +110,24 @@ MemEncryptSevEsIsEnabled ( + return mSevEsStatus; + } + ++/** ++ Figures out if we are running inside KVM HVM and ++ KVM HVM supports SEV Live Migration feature. ++**/ ++STATIC ++VOID ++EFIAPI ++InternalDetectSevLiveMigrationFeature ( ++ VOID ++ ) ++{ ++ if (KvmDetectSevLiveMigrationFeature ()) { ++ mSevLiveMigrationStatus = TRUE; ++ } ++ ++ mSevLiveMigrationStatusChecked = TRUE; ++} ++ + /** + Returns a boolean to indicate whether SEV is enabled. + +@@ -125,6 +147,25 @@ MemEncryptSevIsEnabled ( + return mSevStatus; + } + ++/** ++ Returns a boolean to indicate whether SEV live migration is enabled. ++ ++ @retval TRUE SEV live migration is enabled ++ @retval FALSE SEV live migration is not enabled ++**/ ++BOOLEAN ++EFIAPI ++MemEncryptSevLiveMigrationIsEnabled ( ++ VOID ++ ) ++{ ++ if (!mSevLiveMigrationStatusChecked) { ++ InternalDetectSevLiveMigrationFeature (); ++ } ++ ++ return mSevLiveMigrationStatus; ++} ++ + /** + Returns the SEV encryption mask. + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c +index b4a9f46..30f2d90 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c +@@ -16,6 +16,8 @@ + #include + #include + ++#include "PeiDxeMemEncryptSevLibInternal.h" ++ + /** + Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM + Save State Map. +@@ -61,3 +63,58 @@ MemEncryptSevLocateInitialSmramSaveStateMapPages ( + + return RETURN_SUCCESS; + } ++ ++/** ++ Figures out if we are running inside KVM HVM and ++ KVM HVM supports SEV Live Migration feature. ++ ++ @retval TRUE SEV live migration is supported. ++ @retval FALSE SEV live migration is not supported. ++**/ ++BOOLEAN ++EFIAPI ++KvmDetectSevLiveMigrationFeature ( ++ VOID ++ ) ++{ ++ CHAR8 Signature[13]; ++ UINT32 mKvmLeaf; ++ UINT32 RegEax; ++ UINT32 RegEbx; ++ UINT32 RegEcx; ++ UINT32 RegEdx; ++ ++ Signature[12] = '\0'; ++ for (mKvmLeaf = 0x40000000; mKvmLeaf < 0x40010000; mKvmLeaf += 0x100) { ++ AsmCpuid ( ++ mKvmLeaf, ++ NULL, ++ (UINT32 *) &Signature[0], ++ (UINT32 *) &Signature[4], ++ (UINT32 *) &Signature[8]); ++ ++ if (AsciiStrCmp (Signature, "KVMKVMKVM") == 0) { ++ DEBUG (( ++ DEBUG_INFO, ++ "%a: KVM Detected, signature = %a\n", ++ __FUNCTION__, ++ Signature ++ )); ++ ++ RegEax = mKvmLeaf + 1; ++ RegEcx = 0; ++ AsmCpuid (mKvmLeaf + 1, &RegEax, &RegEbx, &RegEcx, &RegEdx); ++ if ((RegEax & KVM_FEATURE_MIGRATION_CONTROL) != 0) { ++ DEBUG (( ++ DEBUG_INFO, ++ "%a: SEV Live Migration feature supported\n", ++ __FUNCTION__ ++ )); ++ ++ return TRUE; ++ } ++ } ++ } ++ ++ return FALSE; ++} +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h +new file mode 100644 +index 0000000..30cf5de +--- /dev/null ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h +@@ -0,0 +1,31 @@ ++/** @file ++ ++ Secure Encrypted Virtualization (SEV) library helper function ++ ++ Copyright (c) 2021, AMD Incorporated. All rights reserved.
++ ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_ ++#define PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_ ++ ++#include ++ ++#define KVM_FEATURE_MIGRATION_CONTROL BIT17 ++ ++/** ++ Figures out if we are running inside KVM HVM and ++ KVM HVM supports SEV Live Migration feature. ++ ++ @retval TRUE SEV live migration is supported. ++ @retval FALSE SEV live migration is not supported. ++**/ ++BOOLEAN ++EFIAPI ++KvmDetectSevLiveMigrationFeature( ++ VOID ++ ); ++ ++#endif // PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_ +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c +index e2fd109..9293b56 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c +@@ -17,9 +17,13 @@ + #include + #include + ++#include "PeiDxeMemEncryptSevLibInternal.h" ++ + STATIC BOOLEAN mSevStatus = FALSE; + STATIC BOOLEAN mSevEsStatus = FALSE; + STATIC BOOLEAN mSevStatusChecked = FALSE; ++STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; ++STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; + + STATIC UINT64 mSevEncryptionMask = 0; + STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; +@@ -87,6 +91,24 @@ InternalMemEncryptSevStatus ( + mSevStatusChecked = TRUE; + } + ++/** ++ Figures out if we are running inside KVM HVM and ++ KVM HVM supports SEV Live Migration feature. ++**/ ++STATIC ++VOID ++EFIAPI ++InternalDetectSevLiveMigrationFeature ( ++ VOID ++ ) ++{ ++ if (KvmDetectSevLiveMigrationFeature ()) { ++ mSevLiveMigrationStatus = TRUE; ++ } ++ ++ mSevLiveMigrationStatusChecked = TRUE; ++} ++ + /** + Returns a boolean to indicate whether SEV-ES is enabled. + +@@ -125,6 +147,25 @@ MemEncryptSevIsEnabled ( + return mSevStatus; + } + ++/** ++ Returns a boolean to indicate whether SEV live migration is enabled. ++ ++ @retval TRUE SEV live migration is enabled ++ @retval FALSE SEV live migration is not enabled ++**/ ++BOOLEAN ++EFIAPI ++MemEncryptSevLiveMigrationIsEnabled ( ++ VOID ++ ) ++{ ++ if (!mSevLiveMigrationStatusChecked) { ++ InternalDetectSevLiveMigrationFeature (); ++ } ++ ++ return mSevLiveMigrationStatus; ++} ++ + /** + Returns the SEV encryption mask. + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +index 56d8f3f..d9f7bef 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +@@ -100,6 +100,24 @@ MemEncryptSevIsEnabled ( + return Msr.Bits.SevBit ? TRUE : FALSE; + } + ++/** ++ Returns a boolean to indicate whether SEV live migration is enabled. ++ ++ @retval TRUE SEV live migration is enabled ++ @retval FALSE SEV live migration is not enabled ++**/ ++BOOLEAN ++EFIAPI ++MemEncryptSevLiveMigrationIsEnabled ( ++ VOID ++ ) ++{ ++ // ++ // Not used in SEC phase. ++ // ++ return FALSE; ++} ++ + /** + Returns the SEV encryption mask. + +-- +2.17.1 + diff --git a/0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch b/0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch new file mode 100644 index 0000000..205c5b1 --- /dev/null +++ b/0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch @@ -0,0 +1,298 @@ +From f622069729e0abc9b676af25a90b9e142419cf1a Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Thu, 19 Aug 2021 13:03:00 +0000 +Subject: [PATCH 40/46] OvmfPkg/BaseMemEncryptLib: Hypercall API for page + encryption state change + +Add API to issue hypercall on page encryption state change. + +By default all the SEV guest memory regions are considered encrypted, +if a guest changes the encryption attribute of the page (e.g mark a +page as decrypted) then notify hypervisor. Hypervisor will need to +track the unencrypted pages. The information will be used during +guest live migration, guest page migration and guest debugging. + +This hypercall is used to notify hypervisor when the page's +encryption state changes. + +Cc: Jordan Justen +Cc: Ard Biesheuvel +Signed-off-by: Brijesh Singh +Signed-off-by: Ashish Kalra +Change-Id: Ic0dcf854947f35f633137d2bb052dc79d111971f +--- + OvmfPkg/Include/Library/MemEncryptSevLib.h | 52 +++++++++++++++ + .../DxeMemEncryptSevLib.inf | 1 + + .../Ia32/MemEncryptSevLib.c | 27 ++++++++ + .../PeiMemEncryptSevLib.inf | 1 + + .../SecMemEncryptSevLibInternal.c | 20 ++++++ + .../X64/AsmHelperStub.nasm | 33 ++++++++++ + .../X64/MemEncryptSevLib.c | 64 +++++++++++++++++++ + 7 files changed, 198 insertions(+) + create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm + +diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h +index ea251f1..8ed6242 100644 +--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h ++++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h +@@ -215,4 +215,56 @@ MemEncryptSevClearMmioPageEncMask ( + IN UINTN NumPages + ); + ++/** ++ This hypercall is used to notify hypervisor when the page's encryption ++ state changes. ++ ++ @param[in] PhysicalAddress The physical address that is the start address ++ of a memory region. ++ @param[in] Pages Number of pages in memory region. ++ @param[in] IsEncrypted Encrypted or Decrypted. ++ ++ @retval RETURN_SUCCESS Hypercall returned success. ++ @retval RETURN_UNSUPPORTED Hypercall not supported. ++ @retval RETURN_NO_MAPPING Hypercall returned error. ++**/ ++RETURN_STATUS ++EFIAPI ++SetMemoryEncDecHypercall3 ( ++ IN UINTN PhysicalAddress, ++ IN UINTN Pages, ++ IN BOOLEAN IsEncrypted ++ ); ++ ++#define KVM_HC_MAP_GPA_RANGE 12 ++#define KVM_MAP_GPA_RANGE_PAGE_SZ_4K 0 ++#define KVM_MAP_GPA_RANGE_PAGE_SZ_2M BIT0 ++#define KVM_MAP_GPA_RANGE_PAGE_SZ_1G BIT1 ++#define KVM_MAP_GPA_RANGE_ENC_STATE(n) ((n) << 4) ++#define KVM_MAP_GPA_RANGE_ENCRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(1) ++#define KVM_MAP_GPA_RANGE_DECRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(0) ++ ++/** ++ Interface exposed by the ASM implementation of the core hypercall ++ ++ @param[in] HypercallNum KVM_HC_MAP_GPA_RANGE hypercall. ++ @param[in] PhysicalAddress The physical address that is the start address ++ of a memory region. ++ @param[in] Pages Number of pages in memory region. ++ @param[in] Attributes Bits 3:0 - preferred page size encoding, ++ 0 = 4kb, 1 = 2mb, 2 = 1gb, etc... ++ Bit 4 - plaintext = 0, encrypted = 1 ++ Bits 63:5 - reserved (must be zero) ++ ++ @retval Hypercall returned status. ++**/ ++UINTN ++EFIAPI ++SetMemoryEncDecHypercall3AsmStub ( ++ IN UINTN HypercallNum, ++ IN UINTN PhysicalAddress, ++ IN UINTN Pages, ++ IN UINTN Attributes ++ ); ++ + #endif // _MEM_ENCRYPT_SEV_LIB_H_ +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +index dc32929..8ea8d3a 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +@@ -38,6 +38,7 @@ + X64/PeiDxeVirtualMemory.c + X64/VirtualMemory.c + X64/VirtualMemory.h ++ X64/AsmHelperStub.nasm + + [Sources.IA32] + Ia32/MemEncryptSevLib.c +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c +index be260e0..516d639 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c +@@ -136,3 +136,30 @@ MemEncryptSevClearMmioPageEncMask ( + // + return RETURN_UNSUPPORTED; + } ++ ++/** ++ This hyercall is used to notify hypervisor when the page's encryption ++ state changes. ++ ++ @param[in] PhysicalAddress The physical address that is the start address ++ of a memory region. ++ @param[in] Pages Number of Pages in the memory region. ++ @param[in] IsEncrypted Encrypted or Decrypted. ++ ++ @retval RETURN_SUCCESS Hypercall returned success. ++ @retval RETURN_UNSUPPORTED Hypercall not supported. ++ @retval RETURN_NO_MAPPING Hypercall returned error. ++**/ ++RETURN_STATUS ++EFIAPI ++SetMemoryEncDecHypercall3 ( ++ IN UINTN PhysicalAddress, ++ IN UINTN Pages, ++ IN BOOLEAN IsEncrypted ++ ) ++{ ++ // ++ // Memory encryption bit is not accessible in 32-bit mode ++ // ++ return RETURN_UNSUPPORTED; ++} +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf +index 03a78c3..3233ca7 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf +@@ -38,6 +38,7 @@ + X64/PeiDxeVirtualMemory.c + X64/VirtualMemory.c + X64/VirtualMemory.h ++ X64/AsmHelperStub.nasm + + [Sources.IA32] + Ia32/MemEncryptSevLib.c +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +index d9f7bef..ebb1c39 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +@@ -118,6 +118,26 @@ MemEncryptSevLiveMigrationIsEnabled ( + return FALSE; + } + ++/** ++ Interface exposed by the ASM implementation of the core hypercall ++ ++ @retval Hypercall returned status. ++**/ ++UINTN ++EFIAPI ++SetMemoryEncDecHypercall3AsmStub ( ++ IN UINTN HypercallNum, ++ IN UINTN PhysicalAddress, ++ IN UINTN Pages, ++ IN UINTN Attributes ++ ) ++{ ++ // ++ // Not used in SEC phase. ++ // ++ return RETURN_UNSUPPORTED; ++} ++ + /** + Returns the SEV encryption mask. + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm +new file mode 100644 +index 0000000..0ec35dd +--- /dev/null ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm +@@ -0,0 +1,33 @@ ++/** @file ++ ++ ASM helper stub to invoke hypercall ++ ++ Copyright (c) 2021, AMD Incorporated. All rights reserved.
++ ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++DEFAULT REL ++SECTION .text ++ ++; UINTN ++; EFIAPI ++; SetMemoryEncDecHypercall3AsmStub ( ++; IN UINTN HypercallNum, ++; IN UINTN Arg1, ++; IN UINTN Arg2, ++; IN UINTN Arg3 ++; ); ++global ASM_PFX(SetMemoryEncDecHypercall3AsmStub) ++ASM_PFX(SetMemoryEncDecHypercall3AsmStub): ++ ; UEFI calling conventions require RBX to ++ ; be nonvolatile/callee-saved. ++ push rbx ++ mov rax, rcx ; Copy HypercallNumber to rax ++ mov rbx, rdx ; Copy Arg1 to the register expected by KVM ++ mov rcx, r8 ; Copy Arg2 to register expected by KVM ++ mov rdx, r9 ; Copy Arg3 to register expected by KVM ++ vmmcall ; Call VMMCALL ++ pop rbx ++ ret +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c +index a57e8fd..a6246d4 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c +@@ -143,3 +143,67 @@ MemEncryptSevClearMmioPageEncMask ( + ); + + } ++ ++/** ++ This hyercall is used to notify hypervisor when the page's encryption ++ state changes. ++ ++ @param[in] PhysicalAddress The physical address that is the start address ++ of a memory region. ++ @param[in] Pages Number of Pages in the memory region. ++ @param[in] IsEncrypted Encrypted or Decrypted. ++ ++ @retval RETURN_SUCCESS Hypercall returned success. ++ @retval RETURN_UNSUPPORTED Hypercall not supported. ++ @retval RETURN_NO_MAPPING Hypercall returned error. ++**/ ++RETURN_STATUS ++EFIAPI ++SetMemoryEncDecHypercall3 ( ++ IN UINTN PhysicalAddress, ++ IN UINTN Pages, ++ IN BOOLEAN IsEncrypted ++ ) ++{ ++ RETURN_STATUS Ret; ++ UINTN Error; ++ UINTN EncryptState; ++ ++ Ret = RETURN_UNSUPPORTED; ++ ++ if (MemEncryptSevLiveMigrationIsEnabled ()) { ++ Ret = RETURN_SUCCESS; ++ // ++ // The encryption bit is set/clear on the smallest page size, hence ++ // use the 4k page size in MAP_GPA_RANGE hypercall below. ++ // ++ // Also, when the GCD map is being walked and the c-bit being cleared ++ // from MMIO and NonExistent memory spaces, the physical address ++ // range being passed may not be page-aligned and adding an assert ++ // here prevents booting. Hence, rounding it down when calling ++ // SetMemoryEncDecHypercall3AsmStub below. ++ // ++ ++ EncryptState = IsEncrypted ? KVM_MAP_GPA_RANGE_ENCRYPTED : ++ KVM_MAP_GPA_RANGE_DECRYPTED; ++ ++ Error = SetMemoryEncDecHypercall3AsmStub ( ++ KVM_HC_MAP_GPA_RANGE, ++ PhysicalAddress & ~EFI_PAGE_MASK, ++ Pages, ++ KVM_MAP_GPA_RANGE_PAGE_SZ_4K | EncryptState ++ ); ++ ++ if (Error != 0) { ++ DEBUG ((DEBUG_ERROR, ++ "SetMemoryEncDecHypercall3 failed, Phys = %x, Pages = %d, Err = %Ld\n", ++ PhysicalAddress, ++ Pages, ++ (INT64)Error)); ++ ++ Ret = RETURN_NO_MAPPING; ++ } ++ } ++ ++ return Ret; ++} +-- +2.17.1 + diff --git a/0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch b/0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch new file mode 100644 index 0000000..1c865a3 --- /dev/null +++ b/0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch @@ -0,0 +1,91 @@ +From ee0ca422f17da55350c4da25ef9ca38127d79e3f Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Thu, 19 Aug 2021 13:04:56 +0000 +Subject: [PATCH 41/46] OvmfPkg/BaseMemEncryptLib: Invoke page encryption state + change hypercall + +Invoke the hypercall API to notify hypervisor when the page's +encryption state changes. + +Cc: Jordan Justen +Cc: Ard Biesheuvel +Signed-off-by: Brijesh Singh +Signed-off-by: Ashish Kalra +Change-Id: Ia61155777fe3bf66f1d059978c0e8b1d1c833ef7 +--- + .../X64/PeiDxeVirtualMemory.c | 20 +++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +index 6726010..0b67577 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +@@ -582,10 +582,13 @@ SetMemoryEncDec ( + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; + PAGE_TABLE_ENTRY *PageDirectory2MEntry; ++ PHYSICAL_ADDRESS OrigPhysicalAddress; + PAGE_TABLE_4K_ENTRY *PageTableEntry; + UINT64 PgTableMask; + UINT64 AddressEncMask; + BOOLEAN IsWpEnabled; ++ BOOLEAN CBitChanged; ++ UINTN OrigLength; + RETURN_STATUS Status; + PHYSICAL_ADDRESS PageAddress; + UINTN PageNum; +@@ -642,6 +645,9 @@ SetMemoryEncDec ( + } + + Status = EFI_SUCCESS; ++ OrigLength = Length; ++ CBitChanged = FALSE; ++ OrigPhysicalAddress = PhysicalAddress; + + while (Length != 0) + { +@@ -702,6 +708,7 @@ SetMemoryEncDec ( + )); + PhysicalAddress += BIT30; + Length -= BIT30; ++ CBitChanged = TRUE; + } else { + // + // We must split the page +@@ -756,6 +763,7 @@ SetMemoryEncDec ( + SetOrClearCBit (&PageDirectory2MEntry->Uint64, Mode); + PhysicalAddress += BIT21; + Length -= BIT21; ++ CBitChanged = TRUE; + } else { + // + // We must split up this page into 4K pages +@@ -798,6 +806,7 @@ SetMemoryEncDec ( + SetOrClearCBit (&PageTableEntry->Uint64, Mode); + PhysicalAddress += EFI_PAGE_SIZE; + Length -= EFI_PAGE_SIZE; ++ CBitChanged = TRUE; + } + } + } +@@ -815,6 +824,17 @@ SetMemoryEncDec ( + // + CpuFlushTlb(); + ++ // ++ // Notify Hypervisor on C-bit status ++ // ++ if (CBitChanged) { ++ Status = SetMemoryEncDecHypercall3 ( ++ OrigPhysicalAddress, ++ EFI_SIZE_TO_PAGES (OrigLength), ++ (Mode == SetCBit) ? TRUE : FALSE ++ ); ++ } ++ + Done: + // + // Restore page table write protection, if any. +-- +2.17.1 + diff --git a/0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch b/0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch new file mode 100644 index 0000000..c37eb4a --- /dev/null +++ b/0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch @@ -0,0 +1,46 @@ +From b9e68850125194c9c183a0ab2239a6c73b1d67c3 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Thu, 19 Aug 2021 13:06:40 +0000 +Subject: [PATCH 42/46] OvmfPkg/VmgExitLib: Encryption state change hypercall + support in VC handler + +Make the #VC handler aware of the page encryption state +change hypercall by adding support to check KVM_HC_MAP_GPA_RANGE +hypercall and add the additional register values used by +hypercall in the GHCB. + +Cc: Jordan Justen +Cc: Ard Biesheuvel +Signed-off-by: Ashish Kalra +Change-Id: Iaab77f063455837393f290ee80962e6f3d2f5593 +--- + OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c +index 41b0c8c..2d06343 100644 +--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c ++++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c +@@ -1171,6 +1171,19 @@ VmmCallExit ( + Ghcb->SaveArea.Cpl = (UINT8) (Regs->Cs & 0x3); + VmgSetOffsetValid (Ghcb, GhcbCpl); + ++ if (Regs->Rax == KVM_HC_MAP_GPA_RANGE) { ++ // ++ // KVM_HC_MAP_GPA_RANGE hypercall requires these ++ // extra registers. ++ // ++ Ghcb->SaveArea.Rbx = Regs->Rbx; ++ VmgSetOffsetValid (Ghcb, GhcbRbx); ++ Ghcb->SaveArea.Rcx = Regs->Rcx; ++ VmgSetOffsetValid (Ghcb, GhcbRcx); ++ Ghcb->SaveArea.Rdx = Regs->Rdx; ++ VmgSetOffsetValid (Ghcb, GhcbRdx); ++ } ++ + Status = VmgExit (Ghcb, SVM_EXIT_VMMCALL, 0, 0); + if (Status != 0) { + return Status; +-- +2.17.1 + diff --git a/0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch b/0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch new file mode 100644 index 0000000..dd2ca14 --- /dev/null +++ b/0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch @@ -0,0 +1,43 @@ +From 4f2273d02335039e85d8b47b1e43715e3db86c33 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Thu, 19 Aug 2021 13:09:07 +0000 +Subject: [PATCH 43/46] OvmfPkg/PlatformPei: Mark SEC GHCB page as unencrypted + via hypercall + +Mark the SEC GHCB page (that is mapped as unencrypted in +ResetVector code) in the hypervisor's guest page encryption +state tracking. + +Cc: Jordan Justen +Cc: Ard Biesheuvel +Signed-off-by: Ashish Kalra +Change-Id: Iedcde6367e12106e44e0cb1cc07a4ed386f67c19 +--- + OvmfPkg/PlatformPei/AmdSev.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c +index a8bf610..1d38056 100644 +--- a/OvmfPkg/PlatformPei/AmdSev.c ++++ b/OvmfPkg/PlatformPei/AmdSev.c +@@ -52,6 +52,17 @@ AmdSevEsInitialize ( + PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE); + ASSERT_RETURN_ERROR (PcdStatus); + ++ // ++ // The SEC Ghcb setup during reset-vector needs to be marked as ++ // decrypted in the hypervisor's guest page encryption state ++ // tracking. ++ // ++ SetMemoryEncDecHypercall3 ( ++ FixedPcdGet32 (PcdOvmfSecGhcbBase), ++ EFI_SIZE_TO_PAGES(FixedPcdGet32 (PcdOvmfSecGhcbSize)), ++ FALSE ++ ); ++ + // + // Allocate GHCB and per-CPU variable pages. + // Since the pages must survive across the UEFI to OS transition +-- +2.17.1 + diff --git a/0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch b/0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch new file mode 100644 index 0000000..edb8b39 --- /dev/null +++ b/0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch @@ -0,0 +1,185 @@ +From f751df6533d370a14412fab4850ad05ce99b7b85 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Thu, 19 Aug 2021 13:14:31 +0000 +Subject: [PATCH 44/46] OvmfPkg/AmdSevDxe: Add support for SEV live migration. + +Check for SEV live migration feature support, if detected +setup a new UEFI enviroment variable to indicate OVMF +support for SEV live migration. + +This environment variable is created by UEFI but consumed +by the (guest) linux kernel. This is actually part of a +3-way negotiation of the live migration feature between +hypervisor, guest OVMF and guest kernel. Host indicates +support for live migration, which is detected by OVMF +and correspondingly OVMF sets this SetLiveMigrationEnabled +UEFI variable, which is read by the guest kernel and it +indicates to the guest kernel that both host and OVMF +support and have enabled the live migration feature. + +The new runtime UEFI environment variable is set via the +notification function registered for the +EFI_END_OF_DXE_EVENT_GROUP_GUID event in AmdSevDxe driver. + +AmdSevDxe module is an apriori driver so it gets loaded between PEI +and DXE phases and the SetVariable call will fail at the driver's +entry point as the Variable DXE module is still not loaded yet. +So we need to wait for an event notification which is signaled +after the Variable DXE module is loaded, hence, using the +EndOfDxe event notification to make this call. + +Signed-off-by: Ashish Kalra +Change-Id: Iff6eee8f56fd60d1aedf48a5253b7b09e9aa9c7e +--- + OvmfPkg/AmdSevDxe/AmdSevDxe.c | 64 ++++++++++++++++++++++ + OvmfPkg/AmdSevDxe/AmdSevDxe.inf | 4 ++ + OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h | 20 +++++++ + OvmfPkg/OvmfPkg.dec | 1 + + 4 files changed, 89 insertions(+) + create mode 100644 OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h + +diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c +index c66c4e9..0750949 100644 +--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c ++++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c +@@ -15,10 +15,47 @@ + #include + #include + #include ++#include + #include + #include ++#include ++#include ++#include + #include + ++STATIC ++VOID ++EFIAPI ++AmdSevDxeOnEndOfDxe ( ++ IN EFI_EVENT Event, ++ IN VOID *EventToSignal ++ ) ++{ ++ EFI_STATUS Status; ++ BOOLEAN SevLiveMigrationEnabled; ++ ++ SevLiveMigrationEnabled = MemEncryptSevLiveMigrationIsEnabled (); ++ ++ if (SevLiveMigrationEnabled) { ++ Status = gRT->SetVariable ( ++ L"SevLiveMigrationEnabled", ++ &gAmdSevMemEncryptGuid, ++ EFI_VARIABLE_NON_VOLATILE | ++ EFI_VARIABLE_BOOTSERVICE_ACCESS | ++ EFI_VARIABLE_RUNTIME_ACCESS, ++ sizeof SevLiveMigrationEnabled, ++ &SevLiveMigrationEnabled ++ ); ++ ++ DEBUG (( ++ DEBUG_INFO, ++ "%a: Setting SevLiveMigrationEnabled variable, status = %lx\n", ++ __FUNCTION__, ++ Status ++ )); ++ } ++} ++ + EFI_STATUS + EFIAPI + AmdSevDxeEntryPoint ( +@@ -30,6 +67,7 @@ AmdSevDxeEntryPoint ( + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *AllDescMap; + UINTN NumEntries; + UINTN Index; ++ EFI_EVENT Event; + + // + // Do nothing when SEV is not enabled +@@ -130,5 +168,31 @@ AmdSevDxeEntryPoint ( + } + } + ++ // ++ // AmdSevDxe module is an apriori driver so it gets loaded between PEI ++ // and DXE phases and the SetVariable call will fail at the driver's ++ // entry point as the Variable DXE module is still not loaded yet. ++ // So we need to wait for an event notification which is signaled ++ // after the Variable DXE module is loaded, hence, using the ++ // EndOfDxe event notification to make this call. ++ // ++ // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event. ++ // The notification function sets the runtime variable indicating OVMF ++ // support for SEV live migration. ++ // ++ Status = gBS->CreateEventEx ( ++ EVT_NOTIFY_SIGNAL, ++ TPL_CALLBACK, ++ AmdSevDxeOnEndOfDxe, ++ NULL, ++ &gEfiEndOfDxeEventGroupGuid, ++ &Event ++ ); ++ ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a: CreateEventEx(): %r\n", ++ __FUNCTION__, Status)); ++ } ++ + return EFI_SUCCESS; + } +diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf +index 0676fcc..2ad1fb8 100644 +--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf ++++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf +@@ -45,3 +45,7 @@ + + [Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId ++ ++[Guids] ++ gAmdSevMemEncryptGuid ++ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event +diff --git a/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h +new file mode 100644 +index 0000000..1c948fb +--- /dev/null ++++ b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h +@@ -0,0 +1,20 @@ ++/** @file ++ ++ AMD Memory Encryption GUID, define a new GUID for defining ++ new UEFI environment variables assocaiated with SEV Memory Encryption. ++ ++ Copyright (c) 2021, AMD Inc. All rights reserved.
++ ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef __AMD_SEV_MEMENCRYPT_LIB_H__ ++#define __AMD_SEV_MEMENCRYPT_LIB_H__ ++ ++#define AMD_SEV_MEMENCRYPT_GUID \ ++{0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}} ++ ++extern EFI_GUID gAmdSevMemEncryptGuid; ++ ++#endif +diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec +index 7e6a6a2..b6f88e0 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -128,6 +128,7 @@ + gQemuKernelLoaderFsMediaGuid = {0x1428f772, 0xb64a, 0x441e, {0xb8, 0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}} + gGrubFileGuid = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}} + gConfidentialComputingSecretGuid = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}} ++ gAmdSevMemEncryptGuid = {0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}} + + [Ppis] + # PPI whose presence in the PPI database signals that the TPM base address +-- +2.17.1 + diff --git a/0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch b/0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch new file mode 100644 index 0000000..d152d63 --- /dev/null +++ b/0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch @@ -0,0 +1,35 @@ +From 1f244d5fec68cbd76fd902819d906c5222577a69 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Mon, 17 Jan 2022 01:19:21 -0500 +Subject: [PATCH 45/46] anolis: OvmfPkg/BaseMemcryptSevLib: Correct the + calculation of page range that notified to hypervisor + +Correct the calculation of page range that notified to hypervisor. + +Change-Id: Ie2ac4a4e894095ea9ae3b1d44afed04681b9d491 +--- + .../Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +index 0b67577..4dbf829 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +@@ -828,9 +828,13 @@ SetMemoryEncDec ( + // Notify Hypervisor on C-bit status + // + if (CBitChanged) { ++ UINTN StartPfn = OrigPhysicalAddress >> EFI_PAGE_SHIFT; ++ UINTN EndPfn = (OrigPhysicalAddress + OrigLength + ++ ((1 << EFI_PAGE_SHIFT) - 1)) >> EFI_PAGE_SHIFT; ++ + Status = SetMemoryEncDecHypercall3 ( + OrigPhysicalAddress, +- EFI_SIZE_TO_PAGES (OrigLength), ++ (EndPfn - StartPfn), + (Mode == SetCBit) ? TRUE : FALSE + ); + } +-- +2.17.1 + diff --git a/0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch b/0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch new file mode 100644 index 0000000..5da0f2b --- /dev/null +++ b/0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch @@ -0,0 +1,36 @@ +From 901330a9161de852bf99ad7b2c629bae00af2b7a Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sun, 19 Jun 2022 18:12:35 +0800 +Subject: [PATCH 46/46] anolis: OvmfPkg/BaseMemEncryptLib: Return SUCCESS if + not support SEV live migration + +Add this change to avoid trigger 'ASSERT_EFI_ERROR (Status = Unsupported)' +when QEMU doesn't support SEV live migration. + +Change-Id: I48066d6cf1b4357c984496bcb6450be4d35b7e16 +--- + OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c +index a6246d4..e50231c 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c +@@ -169,10 +169,12 @@ SetMemoryEncDecHypercall3 ( + UINTN Error; + UINTN EncryptState; + +- Ret = RETURN_UNSUPPORTED; ++ // ++ // Return success if not support migration. ++ // ++ Ret = RETURN_SUCCESS; + + if (MemEncryptSevLiveMigrationIsEnabled ()) { +- Ret = RETURN_SUCCESS; + // + // The encryption bit is set/clear on the smallest page size, hence + // use the 4k page size in MAP_GPA_RANGE hypercall below. +-- +2.17.1 + diff --git a/edk2.spec b/edk2.spec index 5e6bf7b..b6aa590 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 ExclusiveArch: x86_64 aarch64 %define GITDATE 20220126 @@ -7,7 +8,7 @@ ExclusiveArch: x86_64 aarch64 Name: edk2 Version: %{GITDATE}git%{GITCOMMIT} -Release: 6%{?dist} +Release: 6%{anolis_release}%{?dist} Summary: UEFI firmware for 64-bit virtual machines Group: Applications/Emulators License: BSD-2-Clause-Patent and OpenSSL and MIT @@ -61,6 +62,26 @@ Patch29: edk2-SecurityPkg-DxeImageVerificationLib-Check-result-of-.patch # For bz#2150267 - ovmf must consider max cpu count not boot cpu count for apic mode [rhel-8] Patch30: edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch +# Support hygon csv3 feature +Patch1000: 0029-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch +Patch1001: 0030-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch +Patch1002: 0031-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch +Patch1003: 0032-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch +Patch1004: 0033-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch +Patch1005: 0034-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch +Patch1006: 0035-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch +Patch1007: 0036-anolis-OvmfPkg-Add-CsvDxe-driver.patch +Patch1008: 0037-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch +Patch1009: 0038-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch +# Support SEV live migration +Patch1010: 0039-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch +Patch1011: 0040-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch +Patch1012: 0041-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch +Patch1013: 0042-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch +Patch1014: 0043-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch +Patch1015: 0044-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch +Patch1016: 0045-anolis-OvmfPkg-BaseMemcryptSevLib-Correct-the-calcul.patch +Patch1017: 0046-anolis-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-n.patch # python3-devel and libuuid-devel are required for building tools. # python3-devel is also needed for varstore template generation and @@ -504,6 +525,10 @@ true %endif %changelog +* Thu Dec 14 2023 Jiang Xin - 20220126gitbb1bba3d77-6.0.1 +- Support hygon CSV3 feature +- Support SEV live migration + * Fri Aug 04 2023 Jon Maloy - 20220126gitbb1bba3d77-6 - edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch [bz#2150267] - Resolves: bz#2150267 -- Gitee