Add support for Hygon CSV3 guest

Signed-off-by: hanliyang <hanliyang@hygon.cn>
This commit is contained in:
hanliyang 2024-09-10 17:54:14 +08:00
parent da77f9b87e
commit 42da937f6e
12 changed files with 3077 additions and 1 deletions

View File

@ -0,0 +1,137 @@
From f03eb634da29eea5900760ea4b453468054a76b4 Mon Sep 17 00:00:00 2001
From: Xin Jiang <jiangxin@hygon.cn>
Date: Thu, 11 Apr 2024 12:02:21 +0800
Subject: [PATCH 01/11] MdePkg: Add StandardSignatureIsHygonGenuine() in
BaseCpuLib
This function allows IA32/X64 code to determine if it is running on an
Hygon brand processor.
Signed-off-by: Xin Jiang <jiangxin@hygon.cn>
---
MdePkg/Include/Library/CpuLib.h | 11 ++++++
MdePkg/Include/Register/Hygon/Cpuid.h | 47 +++++++++++++++++++++++
MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c | 24 ++++++++++++
3 files changed, 82 insertions(+)
create mode 100644 MdePkg/Include/Register/Hygon/Cpuid.h
diff --git a/MdePkg/Include/Library/CpuLib.h b/MdePkg/Include/Library/CpuLib.h
index 3f29937..220e4e8 100644
--- a/MdePkg/Include/Library/CpuLib.h
+++ b/MdePkg/Include/Library/CpuLib.h
@@ -67,6 +67,17 @@ 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.
@return CPUID[01h].EAX with Processor Type and Stepping ID cleared.
diff --git a/MdePkg/Include/Register/Hygon/Cpuid.h b/MdePkg/Include/Register/Hygon/Cpuid.h
new file mode 100644
index 0000000..e8a2c76
--- /dev/null
+++ b/MdePkg/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.<BR>
+
+ 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/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c b/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c
index 1cad32a..6d7ceb1 100644
--- a/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c
+++ b/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c
@@ -11,6 +11,7 @@
#include <Register/Intel/Cpuid.h>
#include <Register/Amd/Cpuid.h>
+#include <Register/Hygon/Cpuid.h>
#include <Library/BaseLib.h>
#include <Library/CpuLib.h>
@@ -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.25.1

View File

@ -0,0 +1,82 @@
From 0e02ccfc4ed8424c41cd571783b3a80ee947567f Mon Sep 17 00:00:00 2001
From: jiangxin <jiangxin@hygon.cn>
Date: Sun, 10 Apr 2022 21:50:15 -0400
Subject: [PATCH 02/11] 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 <jiangxin@hygon.cn>
---
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 d56c627..6c035ee 100644
--- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
@@ -22,6 +22,7 @@
#include <Library/TimerLib.h>
#include <Library/PcdLib.h>
#include <Library/CpuLib.h>
+#include <Register/Hygon/Cpuid.h>
//
// Library internal functions
@@ -555,7 +556,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);
}
@@ -581,7 +582,7 @@ SendInitSipiSipiAllExcludingSelf (
SendInitIpiAllExcludingSelf ();
MicroSecondDelay (PcdGet32 (PcdCpuInitIpiDelayInMicroSeconds));
SendStartupIpiAllExcludingSelf (StartupRoutine);
- if (!StandardSignatureIsAuthenticAMD ()) {
+ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) {
MicroSecondDelay (200);
SendStartupIpiAllExcludingSelf (StartupRoutine);
}
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
index aa4eb11..2fa614c 100644
--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
@@ -24,6 +24,7 @@
#include <Library/PcdLib.h>
#include <Library/CpuLib.h>
#include <IndustryStandard/Tdx.h>
+#include <Register/Hygon/Cpuid.h>
//
// Library internal functions
@@ -794,7 +795,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);
}
@@ -820,7 +821,7 @@ SendInitSipiSipiAllExcludingSelf (
SendInitIpiAllExcludingSelf ();
MicroSecondDelay (PcdGet32 (PcdCpuInitIpiDelayInMicroSeconds));
SendStartupIpiAllExcludingSelf (StartupRoutine);
- if (!StandardSignatureIsAuthenticAMD ()) {
+ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) {
MicroSecondDelay (200);
SendStartupIpiAllExcludingSelf (StartupRoutine);
}
--
2.25.1

View File

@ -0,0 +1,706 @@
From 44a0f485b882bcce4a7795fc9e60c2bdb6f26a73 Mon Sep 17 00:00:00 2001
From: Liu Zixing <liuzixing@hygon.cn>
Date: Fri, 25 Feb 2022 14:25:11 +0800
Subject: [PATCH 03/11] 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 <jiangxin@hygon.cn>
---
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/AmdSev/AmdSevX64.fdf | 5 +-
OvmfPkg/Include/Library/CsvLib.h | 84 +++++++
OvmfPkg/Library/CsvLib/CsvLib.c | 85 +++++++
OvmfPkg/Library/CsvLib/CsvLib.inf | 54 ++++
.../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 +-
12 files changed, 536 insertions(+), 2 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 2c6ed7c..c70edd3 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -171,6 +171,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
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 463bd3e..7afa73a 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.<BR>
+
+ 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 <Base.h>
+
+typedef struct {
+ IN UINT64 BaseAddress;
+ IN UINT64 Size;
+} CSV_SECURE_CMD_SHARED_REGION;
+
+typedef enum {
+ CsvSecureCmdEnc = 1,
+ CsvSecureCmdDec,
+ CsvSecureCmdReset,
+ CsvSecureCmdUpdateSecureCallTable,
+ CsvSecureCmdMapLowerMemory, //secure memory range below 4G
+ CsvSecureCmdMapUpperMemory //secure memory range above 4G
+} CSV_SECURE_COMMAND_TYPE;
+
+/**
+ Returns a boolean to indicate whether CSV is enabled
+
+ @retval TRUE CSV is enabled
+ @retval FALSE CSV is not enabled
+**/
+BOOLEAN
+EFIAPI
+CsvIsEnabled (
+ VOID
+ );
+
+#define CSV_SHARED_MEMORY_SIGNATURE SIGNATURE_32('C','S','V',' ')
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ UINT64 Start;
+ UINT64 Length;
+} CsvSharedMemoryEntry;
+
+VOID
+EFIAPI
+CsvUpdateMemory (
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINTN NumPages,
+ IN BOOLEAN Dec
+);
+
+VOID
+EFIAPI
+CsvResetMemory (
+ VOID
+);
+
+VOID
+EFIAPI
+CsvUpdateMapLowerMemory (
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINTN NumPages
+);
+
+VOID
+EFIAPI
+CsvUpdateMapUpperMemory (
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINTN NumPages
+);
+#endif // _CSV_LIB_H_
diff --git a/OvmfPkg/Library/CsvLib/CsvLib.c b/OvmfPkg/Library/CsvLib/CsvLib.c
new file mode 100644
index 0000000..332e8ee
--- /dev/null
+++ b/OvmfPkg/Library/CsvLib/CsvLib.c
@@ -0,0 +1,85 @@
+/** @file
+
+ CSV library helper function
+
+ Copyright (c) 2022, HYGON. All rights reserved.<BR>
+
+ 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 <Library/BaseLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/CsvLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Register/Cpuid.h>
+#include <Register/Amd/Cpuid.h>
+#include <Register/Hygon/Cpuid.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/CpuLib.h>
+#include <Register/Amd/Fam17Msr.h>
+
+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 (!MemEncryptSevEsIsEnabled ())
+ return FALSE;
+
+ if (!mCsvStatusChecked) {
+ InternalCsvStatus ();
+ }
+
+ return mCsvStatus;
+}
diff --git a/OvmfPkg/Library/CsvLib/CsvLib.inf b/OvmfPkg/Library/CsvLib/CsvLib.inf
new file mode 100644
index 0000000..57efbe7
--- /dev/null
+++ b/OvmfPkg/Library/CsvLib/CsvLib.inf
@@ -0,0 +1,54 @@
+## @file
+# Library provides the helper functions for CSV guest
+#
+# Copyright (c) 2022 HYGON. All rights reserved.<BR>
+#
+# 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
+
+[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.<BR>
+
+ 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 <Library/CsvLib.h>
+
+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.<BR>
+
+ 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 <Library/BaseLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/CsvLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+
+#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 e3861e5..f19a356 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -145,6 +145,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}}
@@ -429,6 +433,10 @@
## Restrict boot to EFI applications in firmware volumes.
gUefiOvmfPkgTokenSpaceGuid.PcdBootRestrictToFirmware|FALSE|BOOLEAN|0x6c
+ ## 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 80d8e37..6e56169 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -187,6 +187,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 d975714..8084970 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -192,6 +192,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 b12d874..7b27691 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -204,6 +204,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 41912fc..41fdb8b 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.25.1

View File

@ -0,0 +1,219 @@
From 68f30b0567f8a9dc54c492287db3ee1093111894 Mon Sep 17 00:00:00 2001
From: Liu Zixing <liuzixing@hygon.cn>
Date: Fri, 25 Feb 2022 15:55:44 +0800
Subject: [PATCH 04/11] 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 <jiangxin@hygon.cn>
---
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.<BR>
+; 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.25.1

View File

@ -0,0 +1,214 @@
From 922d2aa15213ea16782d36d84cc39c9d99e295e5 Mon Sep 17 00:00:00 2001
From: Liu Zixing <liuzixing@hygon.cn>
Date: Fri, 25 Feb 2022 16:12:38 +0800
Subject: [PATCH 05/11] 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 <jiangxin@hygon.cn>
---
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 662e7e8..3c9f01c 100644
--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c
+++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
@@ -402,8 +402,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.<BR>
+
+ 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 <Library/BaseLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/CsvLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/PlatformInitLib.h>
+
+#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 f5dc41c..34d764e 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -345,6 +345,7 @@ InitializePlatform (
PlatformQemuUc32BaseInitialization (PlatformInfoHob);
InitializeRamRegions (PlatformInfoHob);
+ CsvInitializeMemInfo (PlatformInfoHob);
if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
if (!PlatformInfoHob->SmmSmramRequire) {
@@ -364,6 +365,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 3934aee..45d1688 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
@@ -131,6 +133,8 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable
--
2.25.1

View File

@ -0,0 +1,74 @@
From 315d4ce50c72d618240fbbe6673bb9446e7fe083 Mon Sep 17 00:00:00 2001
From: Liu Zixing <liuzixing@hygon.cn>
Date: Sat, 26 Feb 2022 14:39:06 +0800
Subject: [PATCH 06/11] 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 <jiangxin@hygon.cn>
---
.../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 dee3fb8..a49cf12 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 <Library/CsvLib.h>
+
STATIC BOOLEAN mAddressEncMaskChecked = FALSE;
STATIC UINT64 mAddressEncMask;
STATIC PAGE_TABLE_POOL *mPageTablePool = NULL;
@@ -727,6 +729,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.
@@ -991,6 +998,13 @@ Done:
EnableReadOnlyPageWriteProtect ();
}
+ if (CsvIsEnabled () && Status == EFI_SUCCESS) {
+ if (Mode == ClearCBit)
+ CsvUpdateMemory (PageAddress, PageNum, TRUE);
+ else
+ CsvUpdateMemory (PageAddress, PageNum, FALSE);
+ }
+
return Status;
}
--
2.25.1

View File

@ -0,0 +1,41 @@
From 05c13c04b8ac2eec0d1e4d2db90f887620ee4fce Mon Sep 17 00:00:00 2001
From: Xin Jiang <jiangxin@hygon.cn>
Date: Fri, 18 Aug 2023 17:17:28 +0800
Subject: [PATCH 07/11] OvmfPkg/Tcg: Add CsvLib for TpmMmioSevDecryptPei
Also add CsvLib to OvmfPkg/IntelTdx/IntelTdxX64.dsc to resolve
interface dependencies.
Signed-off-by: Xin Jiang <jiangxin@hygon.cn>
---
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 +
OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf | 1 +
2 files changed, 2 insertions(+)
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 193657f..e9cdd70 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -171,6 +171,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
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.25.1

View File

@ -0,0 +1,641 @@
From b0967ea5b377ba6de08749213db9073dcba3b498 Mon Sep 17 00:00:00 2001
From: Liu Zixing <liuzixing@hygon.cn>
Date: Fri, 25 Feb 2022 16:34:25 +0800
Subject: [PATCH 08/11] 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 <jiangxin@hygon.cn>
---
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/AmdSev/AmdSevX64.fdf | 1 +
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 +
12 files changed, 492 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/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index c70edd3..31bff34 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -757,6 +757,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 7afa73a..5d5612a 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -306,6 +306,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
#
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.<BR>
+
+ 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 <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CsvLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/CsvSharedMemory.h>
+#include <Library/MemEncryptSevLib.h>
+#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.<BR>
+#
+# 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.<BR>
+
+ 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 <Library/BaseLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/CsvLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/CsvSharedMemory.h>
+
+
+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 f19a356..593a536 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -201,6 +201,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 8084970..577583d 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -976,6 +976,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 7f599f1..429c0eb 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -345,6 +345,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 7b27691..9e01848 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -1043,6 +1043,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 41fdb8b..597c9de 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -375,6 +375,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.25.1

View File

@ -0,0 +1,725 @@
From 5a751b7c76c8f9a0a328c4d33fa440e1f02c02e6 Mon Sep 17 00:00:00 2001
From: Liu Zixing <liuzixing@hygon.cn>
Date: Fri, 25 Feb 2022 16:54:44 +0800
Subject: [PATCH 09/11] 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 <jiangxin@hygon.cn>
---
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.<BR>
+
+ 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 <Protocol/IoMmu.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CsvLib.h>
+#include <Protocol/CsvSharedMemory.h>
+#include <Library/UefiBootServicesTableLib.h>
+#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.<BR>
+
+ 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 <Library/CsvLib.h>
+#include "CsvIoMmu.h"
EFI_STATUS
EFIAPI
@@ -21,6 +23,14 @@ IoMmuDxeEntryPoint (
EFI_STATUS Status;
EFI_HANDLE Handle;
+ if (CsvIsEnabled ()) {
+ Status = CsvInstallIoMmuProtocol ();
+ if (Status != EFI_SUCCESS) {
+ DEBUG((EFI_D_ERROR, "fail to install CSV IOMMU\n"));
+ }
+ return Status;
+ }
+
//
// When SEV 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.25.1

View File

@ -0,0 +1,154 @@
From 6f9b1267e19f43e7a51351e9c612492942db5017 Mon Sep 17 00:00:00 2001
From: Xin Jiang <jiangxin@hygon.cn>
Date: Wed, 16 Aug 2023 19:53:27 +0800
Subject: [PATCH 10/11] 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 <jiangxin@hygon.cn>
---
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 5d5612a..714ab00 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 593a536..34bca30 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -438,6 +438,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 597c9de..b1cf0d9 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 45d1688..07de179 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -135,6 +135,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.25.1

View File

@ -0,0 +1,67 @@
From 1bb1257a63d8651d71223c766c9d09b8feebdd08 Mon Sep 17 00:00:00 2001
From: lilu <lilu@hygon.cn>
Date: Thu, 7 Sep 2023 14:44:59 +0800
Subject: [PATCH 11/11] 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.
Signed-off-by: Xin Jiang <jiangxin@hygon.cn>
---
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 57efbe7..bcb6546 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 3c9f01c..7eef68a 100644
--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c
+++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
@@ -40,6 +40,7 @@ Module Name:
#include <Library/QemuFwCfgLib.h>
#include <Library/QemuFwCfgSimpleParserLib.h>
#include <Library/TdxLib.h>
+#include <Library/CsvLib.h>
#include <Library/PlatformInitLib.h>
@@ -687,7 +688,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 5a79d95..8fc80f4 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.25.1

View File

@ -7,7 +7,7 @@
Name: edk2
Version: %{stable_date}
Release: 12
Release: 13
Summary: EFI Development Kit II
License: BSD-2-Clause-Patent and OpenSSL and MIT
URL: https://github.com/tianocore/edk2
@ -93,6 +93,19 @@ patch53: 0053-relax_edk2_gcc14.patch
# Fix CVE-2024-38796
patch54: 0054-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch
# Support Hygon CSV3
patch55: 0055-MdePkg-Add-StandardSignatureIsHygonGenuine-in-BaseCp.patch
patch56: 0056-UefiCpuPkg-LocalApicLib-Exclude-second-SendIpi-seque.patch
patch57: 0057-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-CPU.patch
patch58: 0058-OvmfPkg-ResetVector-Support-CSV-in-ResetVector-phase.patch
patch59: 0059-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memory.patch
patch60: 0060-OvmfPkg-BaseMemcryptSevLib-update-page-status-to-Sec.patch
patch61: 0061-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptPei.patch
patch62: 0062-OvmfPkg-Add-CsvDxe-driver.patch
patch63: 0063-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch
patch64: 0064-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-guest.patch
patch65: 0065-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl
%description
@ -362,6 +375,9 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
%endif
%changelog
* Mon Sep 23 2024 hanliyang<hanliyang@hygon.cn> - 202308-13
- Add support for running in Hygon CSV3 guest
* Wed Oct 09 2024 zhangxianting <zhangxianting@uniontech.com> - 202308-12
- fix CVE-2024-38796