From dacd6d877f1947cc8e5f0ee5244c8307bfea6d96 Mon Sep 17 00:00:00 2001 From: Renbo Date: Mon, 22 Jan 2024 15:29:30 +0800 Subject: [PATCH 1/3] update to edk2-20220126gitbb1bba3d77-6.1 Signed-off-by: Renbo --- ...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 - ...aseMemEncryptLib-Save-memory-encrypt.patch | 144 ---- dist | 1 + edk2-ovmf-cc.json | 1 + edk2.spec | 36 +- 22 files changed, 7 insertions(+), 4132 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 0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch create mode 100644 dist 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/0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch b/0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch deleted file mode 100644 index 00380bc..0000000 --- a/0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 644748015685d9a13e43d7e689f1e7379adcc959 Mon Sep 17 00:00:00 2001 -From: Xin Jiang -Date: Fri, 12 Jan 2024 10:39:28 +0800 -Subject: [PATCH] anolis: OvmfPkg/BaseMemEncryptLib: Save memory encrypt status - in reserved memory - -The MMIO routine of VC handler will get memory encrypt status to -validate MMIO address. MemEncryptSevGetEncryptionMask() will enable -interrupt while interrupt must be disabled during VC. - -During DXE stage, VC routine as below: -CcExitHandleVc->MemEncryptSevGetAddressRangeState-> -MemEncryptSevGetEncryptionMask->PcdGet64(PcdPteMemoryEncryptionAddressOrMask) - -Unfortunately, PcdGet64() will enable interrupt in VC context. - -Change-Id: I89aedeac4a90ec79f9acb35daf638b7fb507f24c -Signed-off-by: Xin Jiang ---- - .../BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 4 ++++ - .../BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c | 10 ++-------- - OvmfPkg/OvmfPkg.dec | 4 ++++ - OvmfPkg/OvmfPkgX64.fdf | 5 ++++- - OvmfPkg/PlatformPei/AmdSev.c | 2 ++ - OvmfPkg/PlatformPei/Csv.c | 6 ++++++ - OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++ - 7 files changed, 24 insertions(+), 9 deletions(-) - -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -index 8ea8d3a..55e75ef 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf -@@ -57,3 +57,7 @@ - - [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask -+ -+[FixedPcd] -+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize -diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c -index df73a83..44d9ad1 100644 ---- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c -+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c -@@ -25,9 +25,6 @@ STATIC BOOLEAN mSevStatusChecked = FALSE; - STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; - STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; - --STATIC UINT64 mSevEncryptionMask = 0; --STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; -- - /** - Reads and sets the status of SEV features. - -@@ -177,10 +174,7 @@ MemEncryptSevGetEncryptionMask ( - VOID - ) - { -- if (!mSevEncryptionMaskSaved) { -- mSevEncryptionMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask); -- mSevEncryptionMaskSaved = TRUE; -- } -+ UINT64 *MemEncryptStatus = (UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase); - -- return mSevEncryptionMask; -+ return *MemEncryptStatus; - } -diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec -index b6f88e0..2c09ad4 100644 ---- a/OvmfPkg/OvmfPkg.dec -+++ b/OvmfPkg/OvmfPkg.dec -@@ -364,6 +364,10 @@ - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|0|UINT32|0x60 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize|0|UINT32|0x61 - -+ ## the base address of memory encryption status.^M -+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|0|UINT32|0x62 -+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize|0|UINT32|0x63 -+ - [PcdsDynamic, PcdsDynamicEx] - gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 -diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf -index 04efa62..0cc12b8 100644 ---- a/OvmfPkg/OvmfPkgX64.fdf -+++ b/OvmfPkg/OvmfPkgX64.fdf -@@ -94,7 +94,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGui - 0x00F000|0x001000 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize - --0x010000|0x010000 -+0x010000|0x001000 -+gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize -+ -+0x011000|0x00F000 - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize - - 0x020000|0x0E0000 -diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c -index 1d38056..33fc83a 100644 ---- a/OvmfPkg/PlatformPei/AmdSev.c -+++ b/OvmfPkg/PlatformPei/AmdSev.c -@@ -167,6 +167,8 @@ AmdSevInitialize ( - PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask); - ASSERT_RETURN_ERROR (PcdStatus); - -+ *(UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase) = EncryptionMask; -+ - DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask)); - - // -diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c -index f7c87ac..f8293ab 100644 ---- a/OvmfPkg/PlatformPei/Csv.c -+++ b/OvmfPkg/PlatformPei/Csv.c -@@ -32,6 +32,12 @@ CsvInitializeMemInfo ( - UINT64 LowerMemorySize; - UINT64 UpperMemorySize; - -+ BuildMemoryAllocationHob ( -+ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusBase), -+ (UINT64)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusSize), -+ EfiReservedMemoryType -+ ); -+ - if (!CsvIsEnabled ()) { - return ; - } -diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf -index bed4dcf..7bf667c 100644 ---- a/OvmfPkg/PlatformPei/PlatformPei.inf -+++ b/OvmfPkg/PlatformPei/PlatformPei.inf -@@ -125,6 +125,8 @@ - gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize -+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase -+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize - - [FeaturePcd] - gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable --- -2.17.1 - diff --git a/dist b/dist new file mode 100644 index 0000000..37a6f9c --- /dev/null +++ b/dist @@ -0,0 +1 @@ +an8_9 diff --git a/edk2-ovmf-cc.json b/edk2-ovmf-cc.json index 2e52745..64c38d0 100644 --- a/edk2-ovmf-cc.json +++ b/edk2-ovmf-cc.json @@ -18,6 +18,7 @@ { "architecture": "x86_64", "machines": [ + "pc-q35-rhel8.6.0", "pc-q35-rhel8.5.0" ] } diff --git a/edk2.spec b/edk2.spec index 65d7309..66a10a1 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,4 +1,3 @@ -%define anolis_release .0.2 ExclusiveArch: x86_64 aarch64 %define GITDATE 20220126 @@ -8,7 +7,7 @@ ExclusiveArch: x86_64 aarch64 Name: edk2 Version: %{GITDATE}git%{GITCOMMIT} -Release: 6%{anolis_release}%{?dist} +Release: 6%{?dist}.1 Summary: UEFI firmware for 64-bit virtual machines Group: Applications/Emulators License: BSD-2-Clause-Patent and OpenSSL and MIT @@ -62,28 +61,6 @@ 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 -# Fix the isue that interrupt is enabled in MMIO VC handler -Patch1018: 0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch # python3-devel and libuuid-devel are required for building tools. # python3-devel is also needed for varstore template generation and @@ -527,13 +504,10 @@ true %endif %changelog -* Thu Jan 11 2024 Xin Jiang - 20220126gitbb1bba3d77-6.0.2 -- 0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch -- Fix the isue that interrupt is enabled in MMIO VC handler - -* Thu Dec 14 2023 Jiang Xin - 20220126gitbb1bba3d77-6.0.1 -- Support hygon CSV3 feature -- Support SEV live migration +* Wed Nov 22 2023 Miroslav Rezanina - 20220126gitbb1bba3d77-6.el8_9.1 +- edk2-add-8.6-machine-type-to-edk2-ovmf-cc.json.patch [RHEL-15931] +- Resolves: RHEL-15931 + (Missing firmware descriptor with secureboot disabled in RHEL 8) * Fri Aug 04 2023 Jon Maloy - 20220126gitbb1bba3d77-6 - edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch [bz#2150267] -- Gitee From 0061b4e9eda5bdd7ef9e5ff5903acac08a2ee7ff Mon Sep 17 00:00:00 2001 From: Xin Jiang Date: Mon, 11 Dec 2023 14:05:11 +0800 Subject: [PATCH 2/3] 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 66a10a1..81ef579 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}.1 +Release: 6%{anolis_release}%{?dist}.1 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 +* Mon Jan 22 2024 Jiang Xin - 20220126gitbb1bba3d77-6.0.1.1 +- Support hygon CSV3 feature +- Support SEV live migration + * Wed Nov 22 2023 Miroslav Rezanina - 20220126gitbb1bba3d77-6.el8_9.1 - edk2-add-8.6-machine-type-to-edk2-ovmf-cc.json.patch [RHEL-15931] - Resolves: RHEL-15931 -- Gitee From 7c2ad1ae1450dc229b9fd3438fe1bb1835a1f1ab Mon Sep 17 00:00:00 2001 From: Xin Jiang Date: Fri, 12 Jan 2024 10:57:05 +0800 Subject: [PATCH 3/3] anolis: OvmfPkg/BaseMemEncryptLib: Save memory encrypt status in reserved memory The MMIO routine of VC handler will get memory encrypt status to validate MMIO address. MemEncryptSevGetEncryptionMask() will enable interrupt while interrupt must be disabled during VC. During DXE stage, VC routine as below: CcExitHandleVc->MemEncryptSevGetAddressRangeState-> MemEncryptSevGetEncryptionMask->PcdGet64(PcdPteMemoryEncryptionAddressOrMask) Unfortunately, PcdGet64() will enable interrupt in VC context. Signed-off-by: Xin Jiang --- ...aseMemEncryptLib-Save-memory-encrypt.patch | 144 ++++++++++++++++++ edk2.spec | 6 +- 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch diff --git a/0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch b/0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch new file mode 100644 index 0000000..00380bc --- /dev/null +++ b/0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch @@ -0,0 +1,144 @@ +From 644748015685d9a13e43d7e689f1e7379adcc959 Mon Sep 17 00:00:00 2001 +From: Xin Jiang +Date: Fri, 12 Jan 2024 10:39:28 +0800 +Subject: [PATCH] anolis: OvmfPkg/BaseMemEncryptLib: Save memory encrypt status + in reserved memory + +The MMIO routine of VC handler will get memory encrypt status to +validate MMIO address. MemEncryptSevGetEncryptionMask() will enable +interrupt while interrupt must be disabled during VC. + +During DXE stage, VC routine as below: +CcExitHandleVc->MemEncryptSevGetAddressRangeState-> +MemEncryptSevGetEncryptionMask->PcdGet64(PcdPteMemoryEncryptionAddressOrMask) + +Unfortunately, PcdGet64() will enable interrupt in VC context. + +Change-Id: I89aedeac4a90ec79f9acb35daf638b7fb507f24c +Signed-off-by: Xin Jiang +--- + .../BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 4 ++++ + .../BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c | 10 ++-------- + OvmfPkg/OvmfPkg.dec | 4 ++++ + OvmfPkg/OvmfPkgX64.fdf | 5 ++++- + OvmfPkg/PlatformPei/AmdSev.c | 2 ++ + OvmfPkg/PlatformPei/Csv.c | 6 ++++++ + OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++ + 7 files changed, 24 insertions(+), 9 deletions(-) + +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +index 8ea8d3a..55e75ef 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +@@ -57,3 +57,7 @@ + + [Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ++ ++[FixedPcd] ++ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c +index df73a83..44d9ad1 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c +@@ -25,9 +25,6 @@ STATIC BOOLEAN mSevStatusChecked = FALSE; + STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; + STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; + +-STATIC UINT64 mSevEncryptionMask = 0; +-STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; +- + /** + Reads and sets the status of SEV features. + +@@ -177,10 +174,7 @@ MemEncryptSevGetEncryptionMask ( + VOID + ) + { +- if (!mSevEncryptionMaskSaved) { +- mSevEncryptionMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask); +- mSevEncryptionMaskSaved = TRUE; +- } ++ UINT64 *MemEncryptStatus = (UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase); + +- return mSevEncryptionMask; ++ return *MemEncryptStatus; + } +diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec +index b6f88e0..2c09ad4 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -364,6 +364,10 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|0|UINT32|0x60 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize|0|UINT32|0x61 + ++ ## the base address of memory encryption status.^M ++ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|0|UINT32|0x62 ++ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize|0|UINT32|0x63 ++ + [PcdsDynamic, PcdsDynamicEx] + gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 04efa62..0cc12b8 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -94,7 +94,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGui + 0x00F000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize + +-0x010000|0x010000 ++0x010000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize ++ ++0x011000|0x00F000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c +index 1d38056..33fc83a 100644 +--- a/OvmfPkg/PlatformPei/AmdSev.c ++++ b/OvmfPkg/PlatformPei/AmdSev.c +@@ -167,6 +167,8 @@ AmdSevInitialize ( + PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask); + ASSERT_RETURN_ERROR (PcdStatus); + ++ *(UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase) = EncryptionMask; ++ + DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask)); + + // +diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c +index f7c87ac..f8293ab 100644 +--- a/OvmfPkg/PlatformPei/Csv.c ++++ b/OvmfPkg/PlatformPei/Csv.c +@@ -32,6 +32,12 @@ CsvInitializeMemInfo ( + UINT64 LowerMemorySize; + UINT64 UpperMemorySize; + ++ BuildMemoryAllocationHob ( ++ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusBase), ++ (UINT64)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusSize), ++ EfiReservedMemoryType ++ ); ++ + if (!CsvIsEnabled ()) { + return ; + } +diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf +index bed4dcf..7bf667c 100644 +--- a/OvmfPkg/PlatformPei/PlatformPei.inf ++++ b/OvmfPkg/PlatformPei/PlatformPei.inf +@@ -125,6 +125,8 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize ++ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize + + [FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable +-- +2.17.1 + diff --git a/edk2.spec b/edk2.spec index 81ef579..edd2afa 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.1 +%define anolis_release .0.2 ExclusiveArch: x86_64 aarch64 %define GITDATE 20220126 @@ -82,6 +82,8 @@ 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 +# Fix the isue that interrupt is enabled in MMIO VC handler +Patch1018: 0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch # python3-devel and libuuid-devel are required for building tools. # python3-devel is also needed for varstore template generation and @@ -528,6 +530,8 @@ true * Mon Jan 22 2024 Jiang Xin - 20220126gitbb1bba3d77-6.0.1.1 - Support hygon CSV3 feature - Support SEV live migration +- 0047-anolis-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt.patch +- Fix the isue that interrupt is enabled in MMIO VC handler * Wed Nov 22 2023 Miroslav Rezanina - 20220126gitbb1bba3d77-6.el8_9.1 - edk2-add-8.6-machine-type-to-edk2-ovmf-cc.json.patch [RHEL-15931] -- Gitee