diff --git a/0001-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch b/0001-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch new file mode 100644 index 0000000000000000000000000000000000000000..518575f96eae0acf8d2418013df888f579f6722e --- /dev/null +++ b/0001-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch @@ -0,0 +1,140 @@ +From b53f6c7d8acf15af98fd27fa2806e94d536311e2 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Thu, 21 Apr 2022 16:03:08 +0800 +Subject: [PATCH 01/11] 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: I7a41002da25b9cae618fc389c6a7d13da4f1e40d +--- + 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 0ff4a35..49c1455 100644 +--- a/UefiCpuPkg/Include/Library/UefiCpuLib.h ++++ b/UefiCpuPkg/Include/Library/UefiCpuLib.h +@@ -41,6 +41,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 5d925bc..abc4101 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/0002-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch b/0002-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch new file mode 100644 index 0000000000000000000000000000000000000000..6db5fc0847f9effbeb79b88a630343d53ee7a72b --- /dev/null +++ b/0002-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch @@ -0,0 +1,83 @@ +From 914c9071076ae237654faf1a35f30ac318a03993 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Sun, 10 Apr 2022 21:50:15 -0400 +Subject: [PATCH 02/11] 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: I30233a5c887e524699d18874e7bc35d1739a87ad +--- + 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 a944c3d..cc9ea8a 100644 +--- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c ++++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + // + // Library internal functions +@@ -529,7 +530,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); + } +@@ -565,7 +566,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 1e45ffc..6e6ed23 100644 +--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c ++++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + // + // Library internal functions +@@ -768,7 +769,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); + } +@@ -804,7 +805,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/0003-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch b/0003-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch new file mode 100644 index 0000000000000000000000000000000000000000..25e07d7e9c599d44970b81b739b97389a223db7b --- /dev/null +++ b/0003-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch @@ -0,0 +1,763 @@ +From 0a8a52066da1f9d6fe3f6550cb7e19370a32fcb2 Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 14:25:11 +0800 +Subject: [PATCH 03/11] 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: I3cc2289fe370d836a2b75e5e1c84c690554a5630 +--- + OvmfPkg/AmdSev/AmdSevX64.dsc | 2 + + OvmfPkg/AmdSev/AmdSevX64.fdf | 5 +- + OvmfPkg/Include/Library/CsvLib.h | 84 +++++++ + OvmfPkg/IntelTdx/IntelTdxX64.dsc | 2 + + OvmfPkg/IntelTdx/IntelTdxX64.fdf | 9 +- + 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 | 2 + + OvmfPkg/OvmfPkgIa32X64.dsc | 2 + + OvmfPkg/OvmfPkgX64.dsc | 1 + + OvmfPkg/OvmfPkgX64.fdf | 5 +- + 14 files changed, 545 insertions(+), 3 deletions(-) + 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/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc +index 1cebd6b..5bbe83b 100644 +--- a/OvmfPkg/AmdSev/AmdSevX64.dsc ++++ b/OvmfPkg/AmdSev/AmdSevX64.dsc +@@ -170,6 +170,7 @@ + MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf + PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf + DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf ++ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf + + !if $(SOURCE_DEBUG_ENABLE) == TRUE + PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf +@@ -753,6 +754,7 @@ + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + } + OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++ OvmfPkg/CsvDxe/CsvDxe.inf + + # + # Variable driver stack (non-SMM) +diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf +index 5fb3b5d..4893d6b 100644 +--- a/OvmfPkg/AmdSev/AmdSevX64.fdf ++++ b/OvmfPkg/AmdSev/AmdSevX64.fdf +@@ -74,7 +74,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase|gUefiOvmfPkgTokenSpaceGuid.PcdO + 0x00F000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize + +-0x010000|0x010000 ++0x010000|0x002000 ++gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize ++ ++0x012000|0x00E000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +diff --git a/OvmfPkg/Include/Library/CsvLib.h b/OvmfPkg/Include/Library/CsvLib.h +new file mode 100644 +index 0000000..ceeab7d +--- /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/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc +index 95b9594..3cdcea6 100644 +--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc ++++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc +@@ -180,6 +180,7 @@ + MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf + PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf + DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf ++ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf + + LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf +@@ -764,6 +765,7 @@ + OvmfPkg/IoMmuDxe/IoMmuDxe.inf + + OvmfPkg/TdxDxe/TdxDxe.inf ++ OvmfPkg/CsvDxe/CsvDxe.inf + + # + # Variable driver stack (non-SMM) +diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.fdf b/OvmfPkg/IntelTdx/IntelTdxX64.fdf +index 73dffc1..8900524 100644 +--- a/OvmfPkg/IntelTdx/IntelTdxX64.fdf ++++ b/OvmfPkg/IntelTdx/IntelTdxX64.fdf +@@ -94,7 +94,13 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase|gUefiOvmfPkgTokenSpaceGuid.PcdO + 0x00E000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize + +-0x010000|0x010000 ++0x00F000|0x002000 ++gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize ++ ++0x011000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize ++ ++0x012000|0x00E000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x100000|0x700000 +@@ -243,6 +249,7 @@ INF FatPkg/EnhancedFatDxe/Fat.inf + INF OvmfPkg/TdxDxe/TdxDxe.inf + + INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++INF OvmfPkg/CsvDxe/CsvDxe.inf + + # + # Variable driver stack (non-SMM) +diff --git a/OvmfPkg/Library/CsvLib/CsvLib.c b/OvmfPkg/Library/CsvLib/CsvLib.c +new file mode 100644 +index 0000000..2a1f903 +--- /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..0575d67 +--- /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 749fbd3..a0f786f 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -141,6 +141,10 @@ + # + HardwareInfoLib|Include/Library/HardwareInfoLib.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}} +@@ -422,6 +426,10 @@ + # check to decide whether to abort dispatch of the driver it is linked into. + gUefiOvmfPkgTokenSpaceGuid.PcdEntryPointOverrideFwCfgVarName|""|VOID*|0x68 + ++ ## the base address of the secure call pages used by CSV. ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|0|UINT32|0x70 ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize|0|UINT32|0x71 ++ + [PcdsDynamic, PcdsDynamicEx] + gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 +diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc +index 22dc293..b37b706 100644 +--- a/OvmfPkg/OvmfPkgIa32.dsc ++++ b/OvmfPkg/OvmfPkgIa32.dsc +@@ -194,6 +194,8 @@ + MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf + PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf + DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.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 6b53981..0574460 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -198,6 +198,8 @@ + MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf + PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf + DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.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 e3c6445..aa810a5 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -211,6 +211,7 @@ + MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf + PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf + DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf ++ CsvLib|OvmfPkg/Library/CsvLib/CsvLib.inf + + !if $(SMM_REQUIRE) == FALSE + LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 16666ba..4a2f8b5 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -94,7 +94,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase|gUefiOvmfPkgTokenSpaceGuid.PcdO + 0x00E000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize + +-0x010000|0x010000 ++0x00F000|0x002000 ++gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize ++ ++0x011000|0x00F000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +-- +2.17.1 + diff --git a/0004-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch b/0004-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch new file mode 100644 index 0000000000000000000000000000000000000000..bb1a656de492acddfd5dac9765cf2964ee7a1918 --- /dev/null +++ b/0004-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch @@ -0,0 +1,27 @@ +From 7217f6ab43690a0bbd779a2cb8e14f31891c1d87 Mon Sep 17 00:00:00 2001 +From: Xin Jiang +Date: Fri, 18 Aug 2023 17:17:28 +0800 +Subject: [PATCH 04/11] anolis: OvmfPkg/Tcg: Add CsvLib for + TpmMmioSevDecryptPei + +Signed-off-by: Xin Jiang +Change-Id: Ia5b694d8cf01e8eac9446c919ffc6e2c7cd6820a +--- + 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/0005-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch b/0005-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch new file mode 100644 index 0000000000000000000000000000000000000000..f339c75c2a5ba3e2237b0cd6ddd5dbc90f9b52b5 --- /dev/null +++ b/0005-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch @@ -0,0 +1,221 @@ +From 30211c6c7023e61d3afae28bedadca00f5ff8aad Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 15:55:44 +0800 +Subject: [PATCH 05/11] 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: Ib932af85578628a0a4a78c8316b541a4c10423cc +--- + OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 15 +++ + OvmfPkg/ResetVector/Ia32/AmdSev.asm | 9 ++ + OvmfPkg/ResetVector/Ia32/CsvInit.asm | 107 +++++++++++++++++++ + OvmfPkg/ResetVector/ResetVector.inf | 2 + + OvmfPkg/ResetVector/ResetVector.nasmb | 4 + + 5 files changed, 137 insertions(+) + create mode 100644 OvmfPkg/ResetVector/Ia32/CsvInit.asm + +diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +index 12f2ced..c86b049 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 3abc830..8f6de37 100644 +--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm ++++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm +@@ -192,6 +192,15 @@ pageTableEntries4kLoop: + mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12 + mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0 + ++ OneTimeCall CheckCsvFeature ++ test eax, eax ++ jz SevClearPageEncMaskForGhcbPageExit ++ ++ OneTimeCall CsvInit ++ mov eax, 1 ++ test ecx, ecx ++ jz SevEsUnexpectedRespTerminate ++ + SevClearPageEncMaskForGhcbPageExit: + OneTimeCallRet SevClearPageEncMaskForGhcbPage + +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 a4154ca..e4adedb 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 94fbb0a..d156a51 100644 +--- a/OvmfPkg/ResetVector/ResetVector.nasmb ++++ b/OvmfPkg/ResetVector/ResetVector.nasmb +@@ -123,11 +123,15 @@ + %define TDX_WORK_AREA_PGTBL_READY (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 4) + %define TDX_WORK_AREA_GPAW (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 8) + ++ %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/PageTables64.asm" + %include "Ia32/IntelTdx.asm" + %include "X64/OvmfSevMetadata.asm" ++ %include "Ia32/CsvInit.asm" + %endif + + %include "Ia32/AmdSev.asm" +-- +2.17.1 + diff --git a/0006-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch b/0006-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch new file mode 100644 index 0000000000000000000000000000000000000000..f8d7c28c6485de01ff155515943f708b47dc349a --- /dev/null +++ b/0006-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch @@ -0,0 +1,215 @@ +From b80ee2a6e792803eab715c508979f8ea1f15eb8b Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 16:12:38 +0800 +Subject: [PATCH 06/11] 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: I0828702f5c8053542fb502fd2463435d6aa1d96b +--- + OvmfPkg/Include/Library/PlatformInitLib.h | 5 ++ + OvmfPkg/Library/PlatformInitLib/MemDetect.c | 2 +- + OvmfPkg/PlatformPei/Csv.c | 82 +++++++++++++++++++++ + OvmfPkg/PlatformPei/Platform.c | 2 + + OvmfPkg/PlatformPei/Platform.h | 10 +++ + OvmfPkg/PlatformPei/PlatformPei.inf | 4 + + 6 files changed, 104 insertions(+), 1 deletion(-) + create mode 100644 OvmfPkg/PlatformPei/Csv.c + +diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h +index 57b18b9..6c28c7f 100644 +--- a/OvmfPkg/Include/Library/PlatformInitLib.h ++++ b/OvmfPkg/Include/Library/PlatformInitLib.h +@@ -151,6 +151,11 @@ PlatformGetSystemMemorySizeBelow4gb ( + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob + ); + ++UINT64 ++EFIAPI ++PlatformGetSystemMemorySizeAbove4gb ( ++ ); ++ + /** + Initialize the PhysMemAddressWidth field in PlatformInfoHob based on guest RAM size. + **/ +diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c +index 38cece9..7ff9746 100644 +--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c ++++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c +@@ -415,8 +415,8 @@ PlatformGetSystemMemorySizeBelow4gb ( + PlatformInfoHob->LowMemory = (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); + } + +-STATIC + UINT64 ++EFIAPI + PlatformGetSystemMemorySizeAbove4gb ( + ) + { +diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c +new file mode 100644 +index 0000000..5ab8331 +--- /dev/null ++++ b/OvmfPkg/PlatformPei/Csv.c +@@ -0,0 +1,82 @@ ++/** @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 ++ ++#include "Platform.h" ++ ++VOID ++CsvInitializeMemInfo ( ++ IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob ++ ) ++{ ++ UINT64 LowerMemorySize; ++ UINT64 UpperMemorySize; ++ ++ if (!CsvIsEnabled ()) { ++ return ; ++ } ++ ++ LowerMemorySize = PlatformInfoHob->LowMemory; ++ UpperMemorySize = PlatformGetSystemMemorySizeAbove4gb (); ++ ++ 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/Platform.c b/OvmfPkg/PlatformPei/Platform.c +index 1482403..486d2cf 100644 +--- a/OvmfPkg/PlatformPei/Platform.c ++++ b/OvmfPkg/PlatformPei/Platform.c +@@ -375,6 +375,7 @@ InitializePlatform ( + PlatformQemuUc32BaseInitialization (PlatformInfoHob); + + InitializeRamRegions (PlatformInfoHob); ++ CsvInitializeMemInfo (PlatformInfoHob); + + if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) { + if (!PlatformInfoHob->SmmSmramRequire) { +@@ -394,6 +395,7 @@ InitializePlatform ( + } else { + MiscInitialization (PlatformInfoHob); + } ++ CsvInitializeGhcb(); + + IntelTdxInitialize (); + InstallFeatureControlCallback (PlatformInfoHob); +diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h +index 1cf4484..1893f3f 100644 +--- a/OvmfPkg/PlatformPei/Platform.h ++++ b/OvmfPkg/PlatformPei/Platform.h +@@ -106,4 +106,14 @@ SevInitializeRam ( + VOID + ); + ++VOID ++CsvInitializeMemInfo ( ++ IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob ++ ); ++ ++VOID ++CsvInitializeGhcb ( ++ VOID ++ ); ++ + #endif // _PLATFORM_PEI_H_INCLUDED_ +diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf +index 1fadade..1de5c24 100644 +--- a/OvmfPkg/PlatformPei/PlatformPei.inf ++++ b/OvmfPkg/PlatformPei/PlatformPei.inf +@@ -32,6 +32,7 @@ + Platform.c + Platform.h + IntelTdx.c ++ Csv.c + + [Packages] + EmbeddedPkg/EmbeddedPkg.dec +@@ -65,6 +66,7 @@ + PcdLib + CcExitLib + PlatformInitLib ++ CsvLib + + [Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase +@@ -130,6 +132,8 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize + + [FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable +-- +2.17.1 + diff --git a/0007-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch b/0007-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a4d4428406236b1015f5236fe5457d42502308f --- /dev/null +++ b/0007-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch @@ -0,0 +1,75 @@ +From 3c679052f1ba84a97934640ff36bd6d257204b14 Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Sat, 26 Feb 2022 14:39:06 +0800 +Subject: [PATCH 07/11] 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: Ia80155fe2d17255e5bfddf8e64c053c6a3925fcd +--- + .../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 cc24961..3a1d308 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +@@ -52,6 +52,7 @@ + MemoryAllocationLib + PcdLib + CcExitLib ++ CsvLib + + [FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire +diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +index b9c0a5b..4f6258a 100644 +--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c ++++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +@@ -19,6 +19,8 @@ + #include "VirtualMemory.h" + #include "SnpPageStateChange.h" + ++#include ++ + STATIC BOOLEAN mAddressEncMaskChecked = FALSE; + STATIC UINT64 mAddressEncMask; + STATIC PAGE_TABLE_POOL *mPageTablePool = NULL; +@@ -703,6 +705,11 @@ SetMemoryEncDec ( + BOOLEAN IsWpEnabled; + UINTN OrigLength; + RETURN_STATUS Status; ++ PHYSICAL_ADDRESS PageAddress; ++ UINTN PageNum; ++ ++ PageAddress = PhysicalAddress; ++ PageNum = EFI_SIZE_TO_PAGES (Length); + + // + // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings. +@@ -967,6 +974,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/0008-anolis-OvmfPkg-Add-CsvDxe-driver.patch b/0008-anolis-OvmfPkg-Add-CsvDxe-driver.patch new file mode 100644 index 0000000000000000000000000000000000000000..21803902b563135a488377c64971058920f4b5e3 --- /dev/null +++ b/0008-anolis-OvmfPkg-Add-CsvDxe-driver.patch @@ -0,0 +1,616 @@ +From e525ca6b348c5d39feff577bd70b1ae2eae65bae Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 16:34:25 +0800 +Subject: [PATCH 08/11] 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: I24540228e5c74eac8141c9e97edf9b0bff215e20 +--- + 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..d7edf3b +--- /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..0dc8860 +--- /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..fbebc61 +--- /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..1634818 +--- /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..ba62f3a +--- /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 a0f786f..0fac65f 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -197,6 +197,7 @@ + gQemuAcpiTableNotifyProtocolGuid = {0x928939b2, 0x4235, 0x462f, {0x95, 0x80, 0xf6, 0xa2, 0xb2, 0xc2, 0x1a, 0x4f}} + gEfiMpInitLibMpDepProtocolGuid = {0xbb00a5ca, 0x8ce, 0x462f, {0xa5, 0x37, 0x43, 0xc7, 0x4a, 0x82, 0x5c, 0xa4}} + gEfiMpInitLibUpDepProtocolGuid = {0xa9e7cef1, 0x5682, 0x42cc, {0xb1, 0x23, 0x99, 0x30, 0x97, 0x3f, 0x4a, 0x9f}} ++ 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 0574460..1f24275 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -972,6 +972,7 @@ + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.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 4c5bd0d..5510ee3 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.fdf ++++ b/OvmfPkg/OvmfPkgIa32X64.fdf +@@ -344,6 +344,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 aa810a5..de55e6d 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -1044,6 +1044,7 @@ + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + } + OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++ OvmfPkg/CsvDxe/CsvDxe.inf + + OvmfPkg/TdxDxe/TdxDxe.inf + +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 4a2f8b5..9e94a17 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -374,6 +374,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/0009-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch b/0009-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch new file mode 100644 index 0000000000000000000000000000000000000000..2949f3825d28532c8f7a849cdec940e759f86b41 --- /dev/null +++ b/0009-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch @@ -0,0 +1,726 @@ +From cda18dd877288b5311fac2822bbca1d59e3d1a53 Mon Sep 17 00:00:00 2001 +From: Liu Zixing +Date: Fri, 25 Feb 2022 16:54:44 +0800 +Subject: [PATCH 09/11] 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: Idcff642ab63bf86a14711b786834445258c197d5 +--- + 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..2a46e98 +--- /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..431d284 +--- /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 aab6d8b..cd03ca9 100644 +--- a/OvmfPkg/IoMmuDxe/IoMmuDxe.c ++++ b/OvmfPkg/IoMmuDxe/IoMmuDxe.c +@@ -10,6 +10,8 @@ + **/ + + #include "CcIoMmu.h" ++#include ++#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 or TDX 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 17fca52..37d0d81 100644 +--- a/OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++++ b/OvmfPkg/IoMmuDxe/IoMmuDxe.inf +@@ -22,6 +22,8 @@ + CcIoMmu.h + IoMmuDxe.c + IoMmuBuffer.c ++ CsvIoMmu.c ++ CsvIoMmu.h + + [Packages] + MdePkg/MdePkg.dec +@@ -37,6 +39,7 @@ + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint ++ CsvLib + + [Pcd] + gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr +@@ -44,6 +47,7 @@ + [Protocols] + gEdkiiIoMmuProtocolGuid ## SOMETIME_PRODUCES + gIoMmuAbsentProtocolGuid ## SOMETIME_PRODUCES ++ gCsvSharedMemoryProtocolGuid + + [Depex] +- TRUE ++ gCsvSharedMemoryProtocolGuid +-- +2.17.1 + diff --git a/0010-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch b/0010-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch new file mode 100644 index 0000000000000000000000000000000000000000..be694b419d45dfdeef201d7a12fb5db2c71aab33 --- /dev/null +++ b/0010-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch @@ -0,0 +1,156 @@ +From bce616fb1b4f8a9b12318190e493e50531e88086 Mon Sep 17 00:00:00 2001 +From: Xin Jiang +Date: Wed, 16 Aug 2023 19:53:27 +0800 +Subject: [PATCH 10/11] 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: I1a0eea3fc5ce89007fb9b2433fe721e40ff66a34 +--- + OvmfPkg/AmdSev/AmdSevX64.fdf | 5 ++++- + OvmfPkg/OvmfPkg.dec | 4 ++++ + OvmfPkg/OvmfPkgX64.fdf | 5 ++++- + 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 ++ + 8 files changed, 39 insertions(+), 2 deletions(-) + +diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf +index 4893d6b..dd8e511 100644 +--- a/OvmfPkg/AmdSev/AmdSevX64.fdf ++++ b/OvmfPkg/AmdSev/AmdSevX64.fdf +@@ -77,7 +77,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCp + 0x010000|0x002000 + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize + +-0x012000|0x00E000 ++0x012000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize ++ ++0x013000|0x00D000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec +index 0fac65f..7fc0ac2 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -431,6 +431,10 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|0|UINT32|0x70 + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize|0|UINT32|0x71 + ++ ## the base address of the cpuid table page used by CSV. ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|0|UINT32|0x72 ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize|0|UINT32|0x73 ++ + [PcdsDynamic, PcdsDynamicEx] + gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 9e94a17..98f4e5c 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -97,7 +97,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCp + 0x00F000|0x002000 + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize + +-0x011000|0x00F000 ++0x011000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize ++ ++0x012000|0x00E000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c +index 5ab8331..a52112d 100644 +--- a/OvmfPkg/PlatformPei/Csv.c ++++ b/OvmfPkg/PlatformPei/Csv.c +@@ -57,6 +57,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 1de5c24..0cadd0a 100644 +--- a/OvmfPkg/PlatformPei/PlatformPei.inf ++++ b/OvmfPkg/PlatformPei/PlatformPei.inf +@@ -134,6 +134,8 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize + 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 c86b049..dc7348e 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 e4adedb..5dfba88 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 d156a51..da4068b 100644 +--- a/OvmfPkg/ResetVector/ResetVector.nasmb ++++ b/OvmfPkg/ResetVector/ResetVector.nasmb +@@ -125,6 +125,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/0011-anolis-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch b/0011-anolis-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch new file mode 100644 index 0000000000000000000000000000000000000000..67e335ebea5d25614001e170abc516a3a28f4d4f --- /dev/null +++ b/0011-anolis-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch @@ -0,0 +1,68 @@ +From 3627ee28120de78b2521319cec540e2c68fe818d Mon Sep 17 00:00:00 2001 +From: lilu +Date: Thu, 7 Sep 2023 14:44:59 +0800 +Subject: [PATCH 11/11] anolis: OvmfPkg: Use classic mmio window for CSV guest + +For CSV guest, firmware restricts gpa range. Dynamic mmio window +sets Mmio64Base exceeding firmware restriction. Use classic mmio +window for CSV guest. Classic mmio window is less than firmware +restriction under real circumstances. + +Change-Id: I006cb2f834c4d18bf31f6b179952fa0993ba6542 +Signed-off-by: Xin Jiang +--- + OvmfPkg/Library/CsvLib/CsvLib.inf | 2 +- + OvmfPkg/Library/PlatformInitLib/MemDetect.c | 4 +++- + OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf | 1 + + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/OvmfPkg/Library/CsvLib/CsvLib.inf b/OvmfPkg/Library/CsvLib/CsvLib.inf +index 0575d67..a53d1a7 100644 +--- a/OvmfPkg/Library/CsvLib/CsvLib.inf ++++ b/OvmfPkg/Library/CsvLib/CsvLib.inf +@@ -21,7 +21,7 @@ + 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 ++ LIBRARY_CLASS = CsvLib|SEC 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 +diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c +index 7ff9746..dbc0d7a 100644 +--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c ++++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c +@@ -40,6 +40,7 @@ Module Name: + #include + #include + #include ++#include + + #include + +@@ -690,7 +691,8 @@ PlatformDynamicMmioWindow ( + AddrSpace = LShiftU64 (1, PlatformInfoHob->PhysMemAddressWidth); + MmioSpace = LShiftU64 (1, PlatformInfoHob->PhysMemAddressWidth - 3); + +- if ((PlatformInfoHob->PcdPciMmio64Size < MmioSpace) && ++ if (!CsvIsEnabled() && ++ (PlatformInfoHob->PcdPciMmio64Size < MmioSpace) && + (PlatformInfoHob->PcdPciMmio64Base + MmioSpace < AddrSpace)) + { + DEBUG ((DEBUG_INFO, "%a: using dynamic mmio window\n", __func__)); +diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf +index 86a82ad..914e4ca 100644 +--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf ++++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf +@@ -52,6 +52,7 @@ + PcdLib + PciLib + PeiHardwareInfoLib ++ CsvLib + + [LibraryClasses.X64] + TdxLib +-- +2.17.1 + diff --git a/edk2.spec b/edk2.spec index d93fc4651ab9ab8da46fb6e887f8c1ccca90d7ee..15b9b608e5c22317d868a0fcfdb8dbeec8adf1f2 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,4 +1,4 @@ -%define anolis_release 2 +%define anolis_release 3 %undefine _auto_set_build_flags ExclusiveArch: x86_64 aarch64 @@ -53,6 +53,18 @@ Source44: 60-edk2-ovmf-x64-inteltdx.json Source80: https://gitlab.com/kraxel/edk2-build-config/-/blob/master/bin/edk2-build.py Source81: edk2-build +Patch0001: 0001-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch +Patch0002: 0002-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch +Patch0003: 0003-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch +Patch0004: 0004-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch +Patch0005: 0005-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch +Patch0006: 0006-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch +Patch0007: 0007-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch +Patch0008: 0008-anolis-OvmfPkg-Add-CsvDxe-driver.patch +Patch0009: 0009-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch +Patch0010: 0010-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch +Patch0011: 0011-anolis-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch + BuildRequires: python3-devel BuildRequires: libuuid-devel BuildRequires: /usr/bin/iasl @@ -128,6 +140,41 @@ environment for the UEFI and PI specifications. This package contains sample %prep %setup -q -n %{name}-%{name}-stable%{version} +%{lua: + tmp = os.tmpname(); + f = io.open(tmp, "w+"); + count = 0; + for i, p in ipairs(patches) do + f:write(p.."\n"); + count = count + 1; + end; + f:close(); + print("PATCHCOUNT="..count.."\n") + print("PATCHLIST="..tmp.."\n") +} + +git init -q +git config user.name rpm-build +git config user.email rpm-build +git config core.whitespace cr-at-eol +git config am.keepcr true +git add -A . +git commit -q -a --author 'rpm-build ' \ + -m '%{name}-%{GITCOMMIT} base' + +COUNT=$(grep '\.patch$' $PATCHLIST | wc -l) +if [ $COUNT -ne $PATCHCOUNT ]; then + echo "Found $COUNT patches in $PATCHLIST, expected $PATCHCOUNT" + exit 1 +fi +if [ $COUNT -gt 0 ]; then + for pf in `cat $PATCHLIST`; do + git am $pf + done +fi +echo "Applied $COUNT patches" +rm -f $PATCHLIST + cp -a -- %{SOURCE1} . tar -C CryptoPkg/Library/OpensslLib -a -f %{SOURCE2} -x rm -rf CryptoPkg/Library/OpensslLib/openssl @@ -358,6 +405,20 @@ install -m 0644 \ %changelog +* Tue Aug 15 2023 Xin Jiang - 202302-3 +- 0001-anolis-UefiCpuPkg-Add-StandardSignatureIsHygonGenuin.patch +- 0002-anolis-UefiCpuPkg-LocalApicLib-Exclude-second-SendIp.patch +- 0003-anolis-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-.patch +- 0004-anolis-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptP.patch +- 0005-anolis-OvmfPkg-ResetVector-Support-CSV-in-ResetVecto.patch +- 0006-anolis-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memor.patch +- 0007-anolis-OvmfPkg-BaseMemcryptSevLib-update-page-status.patch +- 0008-anolis-OvmfPkg-Add-CsvDxe-driver.patch +- 0009-anolis-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch +- 0010-anolis-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-gu.patch +- 0011-anolis-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch +- Support Hygon CSV3 feature + * Sun Apr 23 2023 Chunmei Xu - 202302-2 - add nx config to fix vm failed on aarch64