Compare commits
11 Commits
fa04b020c9
...
db413a8c0c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db413a8c0c | ||
|
|
5273094c17 | ||
|
|
19e2f998a8 | ||
|
|
da93b0b1f2 | ||
|
|
dbb569a545 | ||
|
|
ef32b54b56 | ||
|
|
3ab396d92e | ||
|
|
9d8e1bd5d8 | ||
|
|
c74770f08b | ||
|
|
defff199a5 | ||
|
|
c19c4c36f9 |
32
0054-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch
Normal file
32
0054-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From c95233b8525ca6828921affd1496146cff262e65 Mon Sep 17 00:00:00 2001
|
||||
From: Doug Flick <dougflick@microsoft.com>
|
||||
Date: Fri, 27 Sep 2024 12:08:55 -0700
|
||||
Subject: [PATCH] MdePkg: Fix overflow issue in BasePeCoffLib
|
||||
|
||||
The RelocDir->Size is a UINT32 value, and RelocDir->VirtualAddress is
|
||||
also a UINT32 value. The current code does not check for overflow when
|
||||
adding RelocDir->Size to RelocDir->VirtualAddress. This patch adds a
|
||||
check to ensure that the addition does not overflow.
|
||||
|
||||
Signed-off-by: Doug Flick <dougflick@microsoft.com>
|
||||
Authored-by: sriraamx gobichettipalayam <sri..@intel.com>
|
||||
---
|
||||
MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
|
||||
index 86ff2e769b..128090d98e 100644
|
||||
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
|
||||
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
|
||||
@@ -1054,7 +1054,7 @@ PeCoffLoaderRelocateImage (
|
||||
RelocDir = &Hdr.Te->DataDirectory[0];
|
||||
}
|
||||
|
||||
- if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
|
||||
+ if ((RelocDir != NULL) && (RelocDir->Size > 0) && (RelocDir->Size - 1 < MAX_UINT32 - RelocDir->VirtualAddress)) {
|
||||
RelocBase = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);
|
||||
RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (
|
||||
ImageContext,
|
||||
--
|
||||
2.20.1
|
||||
|
||||
1304
0055-NetworkPkg-SECURITY-PATCH-CVE-2023-45237.patch
Normal file
1304
0055-NetworkPkg-SECURITY-PATCH-CVE-2023-45237.patch
Normal file
File diff suppressed because it is too large
Load Diff
823
0056-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236.patch
Normal file
823
0056-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236.patch
Normal file
@ -0,0 +1,823 @@
|
||||
From bb6d7763998a29ac05144d382966fe9fd5b7ef78 Mon Sep 17 00:00:00 2001
|
||||
From: Doug Flick <dougflick@microsoft.com>
|
||||
Date: Wed, 8 May 2024 22:56:29 -0700
|
||||
Subject: [PATCH 2/2] NetworkPkg TcpDxe: SECURITY PATCH CVE-2023-45236
|
||||
|
||||
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4541
|
||||
REF: https://www.rfc-editor.org/rfc/rfc1948.txt
|
||||
REF: https://www.rfc-editor.org/rfc/rfc6528.txt
|
||||
REF: https://www.rfc-editor.org/rfc/rfc9293.txt
|
||||
|
||||
Bug Overview:
|
||||
PixieFail Bug #8
|
||||
CVE-2023-45236
|
||||
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
|
||||
CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
|
||||
|
||||
Updates TCP ISN generation to use a cryptographic hash of the
|
||||
connection's identifying parameters and a secret key.
|
||||
This prevents an attacker from guessing the ISN used for some other
|
||||
connection.
|
||||
|
||||
This is follows the guidance in RFC 1948, RFC 6528, and RFC 9293.
|
||||
|
||||
RFC: 9293 Section 3.4.1. Initial Sequence Number Selection
|
||||
|
||||
A TCP implementation MUST use the above type of "clock" for clock-
|
||||
driven selection of initial sequence numbers (MUST-8), and SHOULD
|
||||
generate its initial sequence numbers with the expression:
|
||||
|
||||
ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
|
||||
|
||||
where M is the 4 microsecond timer, and F() is a pseudorandom
|
||||
function (PRF) of the connection's identifying parameters ("localip,
|
||||
localport, remoteip, remoteport") and a secret key ("secretkey")
|
||||
(SHLD-1). F() MUST NOT be computable from the outside (MUST-9), or
|
||||
an attacker could still guess at sequence numbers from the ISN used
|
||||
for some other connection. The PRF could be implemented as a
|
||||
cryptographic hash of the concatenation of the TCP connection
|
||||
parameters and some secret data. For discussion of the selection of
|
||||
a specific hash algorithm and management of the secret key data,
|
||||
please see Section 3 of [42].
|
||||
|
||||
For each connection there is a send sequence number and a receive
|
||||
sequence number. The initial send sequence number (ISS) is chosen by
|
||||
the data sending TCP peer, and the initial receive sequence number
|
||||
(IRS) is learned during the connection-establishing procedure.
|
||||
|
||||
For a connection to be established or initialized, the two TCP peers
|
||||
must synchronize on each other's initial sequence numbers. This is
|
||||
done in an exchange of connection-establishing segments carrying a
|
||||
control bit called "SYN" (for synchronize) and the initial sequence
|
||||
numbers. As a shorthand, segments carrying the SYN bit are also
|
||||
called "SYNs". Hence, the solution requires a suitable mechanism for
|
||||
picking an initial sequence number and a slightly involved handshake
|
||||
to exchange the ISNs.
|
||||
|
||||
Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
|
||||
Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
|
||||
|
||||
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||
Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
|
||||
---
|
||||
NetworkPkg/SecurityFixes.yaml | 22 +++
|
||||
NetworkPkg/TcpDxe/TcpDriver.c | 92 ++++++++++++-
|
||||
NetworkPkg/TcpDxe/TcpDxe.inf | 8 +-
|
||||
NetworkPkg/TcpDxe/TcpFunc.h | 23 ++--
|
||||
NetworkPkg/TcpDxe/TcpInput.c | 13 +-
|
||||
NetworkPkg/TcpDxe/TcpMain.h | 59 ++++++--
|
||||
NetworkPkg/TcpDxe/TcpMisc.c | 244 ++++++++++++++++++++++++++++++++--
|
||||
NetworkPkg/TcpDxe/TcpTimer.c | 3 +-
|
||||
8 files changed, 415 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml
|
||||
index a44cfc4..00ebacb 100644
|
||||
--- a/NetworkPkg/SecurityFixes.yaml
|
||||
+++ b/NetworkPkg/SecurityFixes.yaml
|
||||
@@ -122,6 +122,28 @@ CVE_2023_45235:
|
||||
- http://www.openwall.com/lists/oss-security/2024/01/16/2
|
||||
- http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
|
||||
- https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
|
||||
+CVE_2023_45236:
|
||||
+ commit_titles:
|
||||
+ - "NetworkPkg: TcpDxe: SECURITY PATCH CVE-2023-45236 Patch"
|
||||
+ cve: CVE-2023-45236
|
||||
+ date_reported: 2023-08-28 13:56 UTC
|
||||
+ description: "Bug 08 - edk2/NetworkPkg: Predictable TCP Initial Sequence Numbers"
|
||||
+ note:
|
||||
+ files_impacted:
|
||||
+ - NetworkPkg/Include/Library/NetLib.h
|
||||
+ - NetworkPkg/TcpDxe/TcpDriver.c
|
||||
+ - NetworkPkg/TcpDxe/TcpDxe.inf
|
||||
+ - NetworkPkg/TcpDxe/TcpFunc.h
|
||||
+ - NetworkPkg/TcpDxe/TcpInput.c
|
||||
+ - NetworkPkg/TcpDxe/TcpMain.h
|
||||
+ - NetworkPkg/TcpDxe/TcpMisc.c
|
||||
+ - NetworkPkg/TcpDxe/TcpTimer.c
|
||||
+ links:
|
||||
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4541
|
||||
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45236
|
||||
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
|
||||
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
|
||||
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
|
||||
CVE_2023_45237:
|
||||
commit_titles:
|
||||
- "NetworkPkg:: SECURITY PATCH CVE 2023-45237"
|
||||
diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c
|
||||
index f5d10c6..32cff88 100644
|
||||
--- a/NetworkPkg/TcpDxe/TcpDriver.c
|
||||
+++ b/NetworkPkg/TcpDxe/TcpDriver.c
|
||||
@@ -83,6 +83,12 @@ EFI_SERVICE_BINDING_PROTOCOL gTcpServiceBinding = {
|
||||
TcpServiceBindingDestroyChild
|
||||
};
|
||||
|
||||
+//
|
||||
+// This is the handle for the Hash2ServiceBinding Protocol instance this driver produces
|
||||
+// if the platform does not provide one.
|
||||
+//
|
||||
+EFI_HANDLE mHash2ServiceHandle = NULL;
|
||||
+
|
||||
/**
|
||||
Create and start the heartbeat timer for the TCP driver.
|
||||
|
||||
@@ -165,6 +171,23 @@ TcpDriverEntryPoint (
|
||||
EFI_STATUS Status;
|
||||
UINT32 Random;
|
||||
|
||||
+ //
|
||||
+ // Initialize the Secret used for hashing TCP sequence numbers
|
||||
+ //
|
||||
+ // Normally this should be regenerated periodically, but since
|
||||
+ // this is only used for UEFI networking and not a general purpose
|
||||
+ // operating system, it is not necessary to regenerate it.
|
||||
+ //
|
||||
+ Status = PseudoRandomU32 (&mTcpGlobalSecret);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Get a random number used to generate a random port number
|
||||
+ // Intentionally not linking this to mTcpGlobalSecret to avoid leaking information about the secret
|
||||
+ //
|
||||
Status = PseudoRandomU32 (&Random);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a Failed to generate random number: %r\n", __func__, Status));
|
||||
@@ -207,9 +230,8 @@ TcpDriverEntryPoint (
|
||||
}
|
||||
|
||||
//
|
||||
- // Initialize ISS and random port.
|
||||
+ // Initialize the random port.
|
||||
//
|
||||
- mTcpGlobalIss = Random % mTcpGlobalIss;
|
||||
mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (Random % TCP_PORT_KNOWN));
|
||||
mTcp6RandomPort = mTcp4RandomPort;
|
||||
|
||||
@@ -224,6 +246,8 @@ TcpDriverEntryPoint (
|
||||
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.
|
||||
+ @retval EFI_UNSUPPORTED Service Binding Protocols are unavailable.
|
||||
+ @retval EFI_ALREADY_STARTED The TCP driver is already started on the controller.
|
||||
@retval EFI_SUCCESS A new IP6 service binding private was created.
|
||||
|
||||
**/
|
||||
@@ -234,11 +258,13 @@ TcpCreateService (
|
||||
IN UINT8 IpVersion
|
||||
)
|
||||
{
|
||||
- EFI_STATUS Status;
|
||||
- EFI_GUID *IpServiceBindingGuid;
|
||||
- EFI_GUID *TcpServiceBindingGuid;
|
||||
- TCP_SERVICE_DATA *TcpServiceData;
|
||||
- IP_IO_OPEN_DATA OpenData;
|
||||
+ EFI_STATUS Status;
|
||||
+ EFI_GUID *IpServiceBindingGuid;
|
||||
+ EFI_GUID *TcpServiceBindingGuid;
|
||||
+ TCP_SERVICE_DATA *TcpServiceData;
|
||||
+ IP_IO_OPEN_DATA OpenData;
|
||||
+ EFI_SERVICE_BINDING_PROTOCOL *Hash2ServiceBinding;
|
||||
+ EFI_HASH2_PROTOCOL *Hash2Protocol;
|
||||
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
IpServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;
|
||||
@@ -272,6 +298,33 @@ TcpCreateService (
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
+ Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ //
|
||||
+ // If we can't find the Hashing protocol, then we need to create one.
|
||||
+ //
|
||||
+
|
||||
+ //
|
||||
+ // Platform is expected to publish the hash service binding protocol to support TCP.
|
||||
+ //
|
||||
+ Status = gBS->LocateProtocol (
|
||||
+ &gEfiHash2ServiceBindingProtocolGuid,
|
||||
+ NULL,
|
||||
+ (VOID **)&Hash2ServiceBinding
|
||||
+ );
|
||||
+ if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->CreateChild == NULL)) {
|
||||
+ return EFI_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Create an instance of the hash protocol for this controller.
|
||||
+ //
|
||||
+ Status = Hash2ServiceBinding->CreateChild (Hash2ServiceBinding, &mHash2ServiceHandle);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return EFI_UNSUPPORTED;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
//
|
||||
// Create the TCP service data.
|
||||
//
|
||||
@@ -423,6 +476,7 @@ TcpDestroyService (
|
||||
EFI_STATUS Status;
|
||||
LIST_ENTRY *List;
|
||||
TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
|
||||
+ EFI_SERVICE_BINDING_PROTOCOL *Hash2ServiceBinding;
|
||||
|
||||
ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
|
||||
|
||||
@@ -439,6 +493,30 @@ TcpDestroyService (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
+ //
|
||||
+ // Destroy the Hash2ServiceBinding instance if it is created by Tcp driver.
|
||||
+ //
|
||||
+ if (mHash2ServiceHandle != NULL) {
|
||||
+ Status = gBS->LocateProtocol (
|
||||
+ &gEfiHash2ServiceBindingProtocolGuid,
|
||||
+ NULL,
|
||||
+ (VOID **)&Hash2ServiceBinding
|
||||
+ );
|
||||
+ if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->DestroyChild == NULL)) {
|
||||
+ return EFI_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Destroy the instance of the hashing protocol for this controller.
|
||||
+ //
|
||||
+ Status = Hash2ServiceBinding->DestroyChild (Hash2ServiceBinding, &mHash2ServiceHandle);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return EFI_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ mHash2ServiceHandle = NULL;
|
||||
+ }
|
||||
+
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
ServiceBindingGuid,
|
||||
diff --git a/NetworkPkg/TcpDxe/TcpDxe.inf b/NetworkPkg/TcpDxe/TcpDxe.inf
|
||||
index 1b30980..dc08f76 100644
|
||||
--- a/NetworkPkg/TcpDxe/TcpDxe.inf
|
||||
+++ b/NetworkPkg/TcpDxe/TcpDxe.inf
|
||||
@@ -6,6 +6,7 @@
|
||||
# stack has been loaded in system. This driver supports both IPv4 and IPv6 network stack.
|
||||
#
|
||||
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
+# Copyright (c) Microsoft Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
@@ -68,7 +69,6 @@
|
||||
NetLib
|
||||
IpIoLib
|
||||
|
||||
-
|
||||
[Protocols]
|
||||
## SOMETIMES_CONSUMES
|
||||
## SOMETIMES_PRODUCES
|
||||
@@ -81,6 +81,12 @@
|
||||
gEfiIp6ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiTcp6ProtocolGuid ## BY_START
|
||||
gEfiTcp6ServiceBindingProtocolGuid ## BY_START
|
||||
+ gEfiHash2ProtocolGuid ## BY_START
|
||||
+ gEfiHash2ServiceBindingProtocolGuid ## BY_START
|
||||
+
|
||||
+[Guids]
|
||||
+ gEfiHashAlgorithmMD5Guid ## CONSUMES
|
||||
+ gEfiHashAlgorithmSha256Guid ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiHash2ServiceBindingProtocolGuid
|
||||
diff --git a/NetworkPkg/TcpDxe/TcpFunc.h b/NetworkPkg/TcpDxe/TcpFunc.h
|
||||
index a7af01f..35ea55d 100644
|
||||
--- a/NetworkPkg/TcpDxe/TcpFunc.h
|
||||
+++ b/NetworkPkg/TcpDxe/TcpFunc.h
|
||||
@@ -2,7 +2,7 @@
|
||||
Declaration of external functions shared in TCP driver.
|
||||
|
||||
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
-
|
||||
+ Copyright (c) Microsoft Corporation
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
@@ -36,8 +36,11 @@ VOID
|
||||
|
||||
@param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
+ @retval EFI_SUCCESS The operation completed successfully
|
||||
+ @retval others The underlying functions failed and could not complete the operation
|
||||
+
|
||||
**/
|
||||
-VOID
|
||||
+EFI_STATUS
|
||||
TcpInitTcbLocal (
|
||||
IN OUT TCP_CB *Tcb
|
||||
);
|
||||
@@ -128,17 +131,6 @@ TcpCloneTcb (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
-/**
|
||||
- Compute an ISS to be used by a new connection.
|
||||
-
|
||||
- @return The result ISS.
|
||||
-
|
||||
-**/
|
||||
-TCP_SEQNO
|
||||
-TcpGetIss (
|
||||
- VOID
|
||||
- );
|
||||
-
|
||||
/**
|
||||
Get the local mss.
|
||||
|
||||
@@ -202,8 +194,11 @@ TcpFormatNetbuf (
|
||||
@param[in, out] Tcb Pointer to the TCP_CB that wants to initiate a
|
||||
connection.
|
||||
|
||||
+ @retval EFI_SUCCESS The operation completed successfully
|
||||
+ @retval others The underlying functions failed and could not complete the operation
|
||||
+
|
||||
**/
|
||||
-VOID
|
||||
+EFI_STATUS
|
||||
TcpOnAppConnect (
|
||||
IN OUT TCP_CB *Tcb
|
||||
);
|
||||
diff --git a/NetworkPkg/TcpDxe/TcpInput.c b/NetworkPkg/TcpDxe/TcpInput.c
|
||||
index 7b329be..63fd03a 100644
|
||||
--- a/NetworkPkg/TcpDxe/TcpInput.c
|
||||
+++ b/NetworkPkg/TcpDxe/TcpInput.c
|
||||
@@ -724,6 +724,7 @@ TcpInput (
|
||||
TCP_SEQNO Urg;
|
||||
UINT16 Checksum;
|
||||
INT32 Usable;
|
||||
+ EFI_STATUS Status;
|
||||
|
||||
ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6));
|
||||
|
||||
@@ -872,7 +873,17 @@ TcpInput (
|
||||
Tcb->LocalEnd.Port = Head->DstPort;
|
||||
Tcb->RemoteEnd.Port = Head->SrcPort;
|
||||
|
||||
- TcpInitTcbLocal (Tcb);
|
||||
+ Status = TcpInitTcbLocal (Tcb);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG (
|
||||
+ (DEBUG_ERROR,
|
||||
+ "TcpInput: discard a segment because failed to init local end for TCB %p\n",
|
||||
+ Tcb)
|
||||
+ );
|
||||
+
|
||||
+ goto DISCARD;
|
||||
+ }
|
||||
+
|
||||
TcpInitTcbPeer (Tcb, Seg, &Option);
|
||||
|
||||
TcpSetState (Tcb, TCP_SYN_RCVD);
|
||||
diff --git a/NetworkPkg/TcpDxe/TcpMain.h b/NetworkPkg/TcpDxe/TcpMain.h
|
||||
index c0c9b7f..dbc1da2 100644
|
||||
--- a/NetworkPkg/TcpDxe/TcpMain.h
|
||||
+++ b/NetworkPkg/TcpDxe/TcpMain.h
|
||||
@@ -3,7 +3,7 @@
|
||||
It is the common head file for all Tcp*.c in TCP driver.
|
||||
|
||||
Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
-
|
||||
+ Copyright (c) Microsoft Corporation
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
#include <Protocol/DriverBinding.h>
|
||||
+#include <Protocol/Hash2.h>
|
||||
#include <Library/IpIoLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
@@ -31,7 +32,7 @@ extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;
|
||||
|
||||
extern LIST_ENTRY mTcpRunQue;
|
||||
extern LIST_ENTRY mTcpListenQue;
|
||||
-extern TCP_SEQNO mTcpGlobalIss;
|
||||
+extern TCP_SEQNO mTcpGlobalSecret;
|
||||
extern UINT32 mTcpTick;
|
||||
|
||||
///
|
||||
@@ -45,14 +46,6 @@ extern UINT32 mTcpTick;
|
||||
|
||||
#define TCP_EXPIRE_TIME 65535
|
||||
|
||||
-///
|
||||
-/// The implementation selects the initial send sequence number and the unit to
|
||||
-/// be added when it is increased.
|
||||
-///
|
||||
-#define TCP_BASE_ISS 0x4d7e980b
|
||||
-#define TCP_ISS_INCREMENT_1 2048
|
||||
-#define TCP_ISS_INCREMENT_2 100
|
||||
-
|
||||
typedef union {
|
||||
EFI_TCP4_CONFIG_DATA Tcp4CfgData;
|
||||
EFI_TCP6_CONFIG_DATA Tcp6CfgData;
|
||||
@@ -774,4 +767,50 @@ Tcp6Poll (
|
||||
IN EFI_TCP6_PROTOCOL *This
|
||||
);
|
||||
|
||||
+/**
|
||||
+ Retrieves the Initial Sequence Number (ISN) for a TCP connection identified by local
|
||||
+ and remote IP addresses and ports.
|
||||
+
|
||||
+ This method is based on https://datatracker.ietf.org/doc/html/rfc9293#section-3.4.1
|
||||
+ Where the ISN is computed as follows:
|
||||
+ ISN = TimeStamp + MD5(LocalIP, LocalPort, RemoteIP, RemotePort, Secret)
|
||||
+
|
||||
+ Otherwise:
|
||||
+ ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
|
||||
+
|
||||
+ "Here M is the 4 microsecond timer, and F() is a pseudorandom function (PRF) of the
|
||||
+ connection's identifying parameters ("localip, localport, remoteip, remoteport")
|
||||
+ and a secret key ("secretkey") (SHLD-1). F() MUST NOT be computable from the
|
||||
+ outside (MUST-9), or an attacker could still guess at sequence numbers from the
|
||||
+ ISN used for some other connection. The PRF could be implemented as a
|
||||
+ cryptographic hash of the concatenation of the TCP connection parameters and some
|
||||
+ secret data. For discussion of the selection of a specific hash algorithm and
|
||||
+ management of the secret key data."
|
||||
+
|
||||
+ @param[in] LocalIp A pointer to the local IP address of the TCP connection.
|
||||
+ @param[in] LocalIpSize The size, in bytes, of the LocalIp buffer.
|
||||
+ @param[in] LocalPort The local port number of the TCP connection.
|
||||
+ @param[in] RemoteIp A pointer to the remote IP address of the TCP connection.
|
||||
+ @param[in] RemoteIpSize The size, in bytes, of the RemoteIp buffer.
|
||||
+ @param[in] RemotePort The remote port number of the TCP connection.
|
||||
+ @param[out] Isn A pointer to the variable that will receive the Initial
|
||||
+ Sequence Number (ISN).
|
||||
+
|
||||
+ @retval EFI_SUCCESS The operation completed successfully, and the ISN was
|
||||
+ retrieved.
|
||||
+ @retval EFI_INVALID_PARAMETER One or more of the input parameters are invalid.
|
||||
+ @retval EFI_UNSUPPORTED The operation is not supported.
|
||||
+
|
||||
+**/
|
||||
+EFI_STATUS
|
||||
+TcpGetIsn (
|
||||
+ IN UINT8 *LocalIp,
|
||||
+ IN UINTN LocalIpSize,
|
||||
+ IN UINT16 LocalPort,
|
||||
+ IN UINT8 *RemoteIp,
|
||||
+ IN UINTN RemoteIpSize,
|
||||
+ IN UINT16 RemotePort,
|
||||
+ OUT TCP_SEQNO *Isn
|
||||
+ );
|
||||
+
|
||||
#endif
|
||||
diff --git a/NetworkPkg/TcpDxe/TcpMisc.c b/NetworkPkg/TcpDxe/TcpMisc.c
|
||||
index c93212d..753dec5 100644
|
||||
--- a/NetworkPkg/TcpDxe/TcpMisc.c
|
||||
+++ b/NetworkPkg/TcpDxe/TcpMisc.c
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
|
||||
Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
-
|
||||
+ Copyright (c) Microsoft Corporation
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
@@ -20,7 +20,34 @@ LIST_ENTRY mTcpListenQue = {
|
||||
&mTcpListenQue
|
||||
};
|
||||
|
||||
-TCP_SEQNO mTcpGlobalIss = TCP_BASE_ISS;
|
||||
+//
|
||||
+// The Session secret
|
||||
+// This must be initialized to a random value at boot time
|
||||
+//
|
||||
+TCP_SEQNO mTcpGlobalSecret;
|
||||
+
|
||||
+//
|
||||
+// Union to hold either an IPv4 or IPv6 address
|
||||
+// This is used to simplify the ISN hash computation
|
||||
+//
|
||||
+typedef union {
|
||||
+ UINT8 IPv4[4];
|
||||
+ UINT8 IPv6[16];
|
||||
+} NETWORK_ADDRESS;
|
||||
+
|
||||
+//
|
||||
+// The ISN is computed by hashing this structure
|
||||
+// It is initialized with the local and remote IP addresses and ports
|
||||
+// and the secret
|
||||
+//
|
||||
+//
|
||||
+typedef struct {
|
||||
+ UINT16 LocalPort;
|
||||
+ UINT16 RemotePort;
|
||||
+ NETWORK_ADDRESS LocalAddress;
|
||||
+ NETWORK_ADDRESS RemoteAddress;
|
||||
+ TCP_SEQNO Secret;
|
||||
+} ISN_HASH_CTX;
|
||||
|
||||
CHAR16 *mTcpStateName[] = {
|
||||
L"TCP_CLOSED",
|
||||
@@ -41,12 +68,18 @@ CHAR16 *mTcpStateName[] = {
|
||||
|
||||
@param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
+ @retval EFI_SUCCESS The operation completed successfully
|
||||
+ @retval others The underlying functions failed and could not complete the operation
|
||||
+
|
||||
**/
|
||||
-VOID
|
||||
+EFI_STATUS
|
||||
TcpInitTcbLocal (
|
||||
IN OUT TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
+ TCP_SEQNO Isn;
|
||||
+ EFI_STATUS Status;
|
||||
+
|
||||
//
|
||||
// Compute the checksum of the fixed parts of pseudo header
|
||||
//
|
||||
@@ -57,6 +90,16 @@ TcpInitTcbLocal (
|
||||
0x06,
|
||||
0
|
||||
);
|
||||
+
|
||||
+ Status = TcpGetIsn (
|
||||
+ Tcb->LocalEnd.Ip.v4.Addr,
|
||||
+ sizeof (IPv4_ADDRESS),
|
||||
+ Tcb->LocalEnd.Port,
|
||||
+ Tcb->RemoteEnd.Ip.v4.Addr,
|
||||
+ sizeof (IPv4_ADDRESS),
|
||||
+ Tcb->RemoteEnd.Port,
|
||||
+ &Isn
|
||||
+ );
|
||||
} else {
|
||||
Tcb->HeadSum = NetIp6PseudoHeadChecksum (
|
||||
&Tcb->LocalEnd.Ip.v6,
|
||||
@@ -64,9 +107,25 @@ TcpInitTcbLocal (
|
||||
0x06,
|
||||
0
|
||||
);
|
||||
+
|
||||
+ Status = TcpGetIsn (
|
||||
+ Tcb->LocalEnd.Ip.v6.Addr,
|
||||
+ sizeof (IPv6_ADDRESS),
|
||||
+ Tcb->LocalEnd.Port,
|
||||
+ Tcb->RemoteEnd.Ip.v6.Addr,
|
||||
+ sizeof (IPv6_ADDRESS),
|
||||
+ Tcb->RemoteEnd.Port,
|
||||
+ &Isn
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG ((DEBUG_ERROR, "TcpInitTcbLocal: failed to get isn\n"));
|
||||
+ ASSERT (FALSE);
|
||||
+ return Status;
|
||||
}
|
||||
|
||||
- Tcb->Iss = TcpGetIss ();
|
||||
+ Tcb->Iss = Isn;
|
||||
Tcb->SndUna = Tcb->Iss;
|
||||
Tcb->SndNxt = Tcb->Iss;
|
||||
|
||||
@@ -82,6 +141,8 @@ TcpInitTcbLocal (
|
||||
Tcb->RetxmitSeqMax = 0;
|
||||
|
||||
Tcb->ProbeTimerOn = FALSE;
|
||||
+
|
||||
+ return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -506,18 +567,162 @@ TcpCloneTcb (
|
||||
}
|
||||
|
||||
/**
|
||||
- Compute an ISS to be used by a new connection.
|
||||
-
|
||||
- @return The resulting ISS.
|
||||
+ Retrieves the Initial Sequence Number (ISN) for a TCP connection identified by local
|
||||
+ and remote IP addresses and ports.
|
||||
+
|
||||
+ This method is based on https://datatracker.ietf.org/doc/html/rfc9293#section-3.4.1
|
||||
+ Where the ISN is computed as follows:
|
||||
+ ISN = TimeStamp + MD5(LocalIP, LocalPort, RemoteIP, RemotePort, Secret)
|
||||
+
|
||||
+ Otherwise:
|
||||
+ ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
|
||||
+
|
||||
+ "Here M is the 4 microsecond timer, and F() is a pseudorandom function (PRF) of the
|
||||
+ connection's identifying parameters ("localip, localport, remoteip, remoteport")
|
||||
+ and a secret key ("secretkey") (SHLD-1). F() MUST NOT be computable from the
|
||||
+ outside (MUST-9), or an attacker could still guess at sequence numbers from the
|
||||
+ ISN used for some other connection. The PRF could be implemented as a
|
||||
+ cryptographic hash of the concatenation of the TCP connection parameters and some
|
||||
+ secret data. For discussion of the selection of a specific hash algorithm and
|
||||
+ management of the secret key data."
|
||||
+
|
||||
+ @param[in] LocalIp A pointer to the local IP address of the TCP connection.
|
||||
+ @param[in] LocalIpSize The size, in bytes, of the LocalIp buffer.
|
||||
+ @param[in] LocalPort The local port number of the TCP connection.
|
||||
+ @param[in] RemoteIp A pointer to the remote IP address of the TCP connection.
|
||||
+ @param[in] RemoteIpSize The size, in bytes, of the RemoteIp buffer.
|
||||
+ @param[in] RemotePort The remote port number of the TCP connection.
|
||||
+ @param[out] Isn A pointer to the variable that will receive the Initial
|
||||
+ Sequence Number (ISN).
|
||||
+
|
||||
+ @retval EFI_SUCCESS The operation completed successfully, and the ISN was
|
||||
+ retrieved.
|
||||
+ @retval EFI_INVALID_PARAMETER One or more of the input parameters are invalid.
|
||||
+ @retval EFI_UNSUPPORTED The operation is not supported.
|
||||
|
||||
**/
|
||||
-TCP_SEQNO
|
||||
-TcpGetIss (
|
||||
- VOID
|
||||
+EFI_STATUS
|
||||
+TcpGetIsn (
|
||||
+ IN UINT8 *LocalIp,
|
||||
+ IN UINTN LocalIpSize,
|
||||
+ IN UINT16 LocalPort,
|
||||
+ IN UINT8 *RemoteIp,
|
||||
+ IN UINTN RemoteIpSize,
|
||||
+ IN UINT16 RemotePort,
|
||||
+ OUT TCP_SEQNO *Isn
|
||||
)
|
||||
{
|
||||
- mTcpGlobalIss += TCP_ISS_INCREMENT_1;
|
||||
- return mTcpGlobalIss;
|
||||
+ EFI_STATUS Status;
|
||||
+ EFI_HASH2_PROTOCOL *Hash2Protocol;
|
||||
+ EFI_HASH2_OUTPUT HashResult;
|
||||
+ ISN_HASH_CTX IsnHashCtx;
|
||||
+ EFI_TIME TimeStamp;
|
||||
+
|
||||
+ //
|
||||
+ // Check that the ISN pointer is valid
|
||||
+ //
|
||||
+ if (Isn == NULL) {
|
||||
+ return EFI_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // The local ip may be a v4 or v6 address and may not be NULL
|
||||
+ //
|
||||
+ if ((LocalIp == NULL) || (LocalIpSize == 0) || (RemoteIp == NULL) || (RemoteIpSize == 0)) {
|
||||
+ return EFI_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // the local ip may be a v4 or v6 address
|
||||
+ //
|
||||
+ if ((LocalIpSize != sizeof (EFI_IPv4_ADDRESS)) && (LocalIpSize != sizeof (EFI_IPv6_ADDRESS))) {
|
||||
+ return EFI_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Locate the Hash Protocol
|
||||
+ //
|
||||
+ Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG ((DEBUG_NET, "Failed to locate Hash Protocol: %r\n", Status));
|
||||
+
|
||||
+ //
|
||||
+ // TcpCreateService(..) is expected to be called prior to this function
|
||||
+ //
|
||||
+ ASSERT_EFI_ERROR (Status);
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Initialize the hash algorithm
|
||||
+ //
|
||||
+ Status = Hash2Protocol->HashInit (Hash2Protocol, &gEfiHashAlgorithmSha256Guid);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG ((DEBUG_NET, "Failed to initialize sha256 hash algorithm: %r\n", Status));
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ IsnHashCtx.LocalPort = LocalPort;
|
||||
+ IsnHashCtx.RemotePort = RemotePort;
|
||||
+ IsnHashCtx.Secret = mTcpGlobalSecret;
|
||||
+
|
||||
+ //
|
||||
+ // Check the IP address family and copy accordingly
|
||||
+ //
|
||||
+ if (LocalIpSize == sizeof (EFI_IPv4_ADDRESS)) {
|
||||
+ CopyMem (&IsnHashCtx.LocalAddress.IPv4, LocalIp, LocalIpSize);
|
||||
+ } else if (LocalIpSize == sizeof (EFI_IPv6_ADDRESS)) {
|
||||
+ CopyMem (&IsnHashCtx.LocalAddress.IPv6, LocalIp, LocalIpSize);
|
||||
+ } else {
|
||||
+ return EFI_INVALID_PARAMETER; // Unsupported address size
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Repeat the process for the remote IP address
|
||||
+ //
|
||||
+ if (RemoteIpSize == sizeof (EFI_IPv4_ADDRESS)) {
|
||||
+ CopyMem (&IsnHashCtx.RemoteAddress.IPv4, RemoteIp, RemoteIpSize);
|
||||
+ } else if (RemoteIpSize == sizeof (EFI_IPv6_ADDRESS)) {
|
||||
+ CopyMem (&IsnHashCtx.RemoteAddress.IPv6, RemoteIp, RemoteIpSize);
|
||||
+ } else {
|
||||
+ return EFI_INVALID_PARAMETER; // Unsupported address size
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Compute the hash
|
||||
+ // Update the hash with the data
|
||||
+ //
|
||||
+ Status = Hash2Protocol->HashUpdate (Hash2Protocol, (UINT8 *)&IsnHashCtx, sizeof (IsnHashCtx));
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG ((DEBUG_NET, "Failed to update hash: %r\n", Status));
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Finalize the hash and retrieve the result
|
||||
+ //
|
||||
+ Status = Hash2Protocol->HashFinal (Hash2Protocol, &HashResult);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG ((DEBUG_NET, "Failed to finalize hash: %r\n", Status));
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ Status = gRT->GetTime (&TimeStamp, NULL);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // copy the first 4 bytes of the hash result into the ISN
|
||||
+ //
|
||||
+ CopyMem (Isn, HashResult.Md5Hash, sizeof (*Isn));
|
||||
+
|
||||
+ //
|
||||
+ // now add the timestamp to the ISN as 4 microseconds units (1000 / 4 = 250)
|
||||
+ //
|
||||
+ *Isn += (TCP_SEQNO)TimeStamp.Nanosecond * 250;
|
||||
+
|
||||
+ return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -721,17 +926,28 @@ TcpFormatNetbuf (
|
||||
@param[in, out] Tcb Pointer to the TCP_CB that wants to initiate a
|
||||
connection.
|
||||
|
||||
+ @retval EFI_SUCCESS The operation completed successfully
|
||||
+ @retval others The underlying functions failed and could not complete the operation
|
||||
+
|
||||
**/
|
||||
-VOID
|
||||
+EFI_STATUS
|
||||
TcpOnAppConnect (
|
||||
IN OUT TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
- TcpInitTcbLocal (Tcb);
|
||||
+ EFI_STATUS Status;
|
||||
+
|
||||
+ Status = TcpInitTcbLocal (Tcb);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
TcpSetState (Tcb, TCP_SYN_SENT);
|
||||
|
||||
TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout);
|
||||
TcpToSendData (Tcb, 1);
|
||||
+
|
||||
+ return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/NetworkPkg/TcpDxe/TcpTimer.c b/NetworkPkg/TcpDxe/TcpTimer.c
|
||||
index 5d2e124..f45d4fb 100644
|
||||
--- a/NetworkPkg/TcpDxe/TcpTimer.c
|
||||
+++ b/NetworkPkg/TcpDxe/TcpTimer.c
|
||||
@@ -2,7 +2,7 @@
|
||||
TCP timer related functions.
|
||||
|
||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
-
|
||||
+ Copyright (c) Microsoft Corporation
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
@@ -483,7 +483,6 @@ TcpTickingDpc (
|
||||
INT16 Index;
|
||||
|
||||
mTcpTick++;
|
||||
- mTcpGlobalIss += TCP_ISS_INCREMENT_2;
|
||||
|
||||
//
|
||||
// Don't use LIST_FOR_EACH, which isn't delete safe.
|
||||
--
|
||||
2.33.0
|
||||
|
||||
137
0057-MdePkg-Add-StandardSignatureIsHygonGenuine-in-BaseCp.patch
Normal file
137
0057-MdePkg-Add-StandardSignatureIsHygonGenuine-in-BaseCp.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From 4fd49b9dd37821a12c480234cdef0217a31baae2 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 3f29937d..220e4e8e 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 00000000..e8a2c76b
|
||||
--- /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 1cad32a4..6d7ceb11 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.43.0
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
From ee70f4f384975e7f0fa97aacbd72c8431f441eb9 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 d56c6275..6c035ee3 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 aa4eb111..2fa614cd 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.43.0
|
||||
|
||||
706
0059-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-CPU.patch
Normal file
706
0059-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-CPU.patch
Normal file
@ -0,0 +1,706 @@
|
||||
From 2b2a93b70ee396bb7932e78fa80f0f3697888cdb 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 2c6ed7c9..c70edd36 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 463bd3e9..7afa73aa 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 00000000..ceeab7dc
|
||||
--- /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 00000000..332e8ee6
|
||||
--- /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 00000000..57efbe70
|
||||
--- /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 00000000..15d3aa89
|
||||
--- /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 00000000..13d06d7c
|
||||
--- /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 e3861e5c..f19a356f 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 80d8e370..6e561690 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 d9757149..80849705 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 b12d874d..7b276916 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 41912fc1..41fdb8b8 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.43.0
|
||||
|
||||
219
0060-OvmfPkg-ResetVector-Support-CSV-in-ResetVector-phase.patch
Normal file
219
0060-OvmfPkg-ResetVector-Support-CSV-in-ResetVector-phase.patch
Normal file
@ -0,0 +1,219 @@
|
||||
From 1cfbda43138702311663a81e1cc5679d3df72ae3 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 12f2cedd..c86b0499 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 3abc8300..8f6de37c 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 00000000..0744a35e
|
||||
--- /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 a4154ca9..e4adedb8 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 94fbb0a8..d156a511 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.43.0
|
||||
|
||||
214
0061-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memory.patch
Normal file
214
0061-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memory.patch
Normal file
@ -0,0 +1,214 @@
|
||||
From d9a779013ce911160125d13e20a395495d30c723 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 57b18b94..6c28c7fb 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 662e7e85..3c9f01cf 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 00000000..5ab83312
|
||||
--- /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 f5dc41c3..34d764e4 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 1cf44844..1893f3fe 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 3934aeed..45d16889 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.43.0
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
From f462635b8603a20615d371f434bfcd561d39f367 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 cc24961c..3a1d3089 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 dee3fb89..a49cf125 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.43.0
|
||||
|
||||
41
0063-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptPei.patch
Normal file
41
0063-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptPei.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From f4621a7af63f9a29e57f563d4a85faa610a8a93b 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 193657ff..e9cdd70f 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 51ad6d0d..402e4c9a 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.43.0
|
||||
|
||||
641
0064-OvmfPkg-Add-CsvDxe-driver.patch
Normal file
641
0064-OvmfPkg-Add-CsvDxe-driver.patch
Normal file
@ -0,0 +1,641 @@
|
||||
From a0a40a843c2811ab73fec8301697742e0f9ac440 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 c70edd36..31bff348 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 7afa73aa..5d5612ab 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 00000000..d7edf3b9
|
||||
--- /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 00000000..0dc88605
|
||||
--- /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 00000000..fbebc615
|
||||
--- /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 00000000..16348181
|
||||
--- /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 00000000..ba62f3a4
|
||||
--- /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 f19a356f..593a5360 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 80849705..577583d0 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 7f599f15..429c0eb2 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 7b276916..9e018485 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 41fdb8b8..597c9def 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.43.0
|
||||
|
||||
725
0065-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch
Normal file
725
0065-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch
Normal file
@ -0,0 +1,725 @@
|
||||
From 00de2f4a698ec30eff79f115c4f35d3ff6cf84f8 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 00000000..2a46e984
|
||||
--- /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 00000000..431d2843
|
||||
--- /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 aab6d8b9..cd03ca90 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 17fca528..37d0d819 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.43.0
|
||||
|
||||
154
0066-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-guest.patch
Normal file
154
0066-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-guest.patch
Normal file
@ -0,0 +1,154 @@
|
||||
From 7efbcd65c6ec50be3ac691cf859b3d1fea9a73dd 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 5d5612ab..714ab004 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 593a5360..34bca309 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 597c9def..b1cf0d99 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 5ab83312..a52112d5 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 45d16889..07de179f 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 c86b0499..dc7348e9 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 e4adedb8..5dfba883 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 d156a511..da4068b7 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.43.0
|
||||
|
||||
67
0067-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch
Normal file
67
0067-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From 26d16863ccb72fd9ac3cbec8d732e0574610893b 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 57efbe70..bcb6546f 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 3c9f01cf..7eef68a0 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 5a79d95b..8fc80f48 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.43.0
|
||||
|
||||
330
0068-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch
Normal file
330
0068-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch
Normal file
@ -0,0 +1,330 @@
|
||||
From ae4bf41d9c71137a21e7b8fc4aceca7212145b40 Mon Sep 17 00:00:00 2001
|
||||
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||
Date: Tue, 5 Apr 2022 16:09:28 +0000
|
||||
Subject: [PATCH 1/9] OvmfPkg/BaseMemEncryptLib: Detect SEV live migration
|
||||
feature.
|
||||
|
||||
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||
|
||||
Add support to check if we are running inside KVM HVM and
|
||||
KVM HVM supports SEV Live Migration feature.
|
||||
|
||||
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||
---
|
||||
OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 ++++
|
||||
.../DxeMemEncryptSevLibInternal.c | 49 ++++++++++++++--
|
||||
.../PeiDxeMemEncryptSevLibInternal.c | 58 +++++++++++++++++++
|
||||
.../PeiDxeMemEncryptSevLibInternal.h | 31 ++++++++++
|
||||
.../PeiMemEncryptSevLibInternal.c | 42 ++++++++++++++
|
||||
.../SecMemEncryptSevLibInternal.c | 18 ++++++
|
||||
6 files changed, 206 insertions(+), 4 deletions(-)
|
||||
create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h
|
||||
|
||||
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||
index 4fa9c0d7..babec60d 100644
|
||||
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||
@@ -83,6 +83,18 @@ MemEncryptSevIsEnabled (
|
||||
VOID
|
||||
);
|
||||
|
||||
+/**
|
||||
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||
+
|
||||
+ @retval TRUE SEV live migration is enabled
|
||||
+ @retval FALSE SEV live migration is not enabled
|
||||
+**/
|
||||
+BOOLEAN
|
||||
+EFIAPI
|
||||
+MemEncryptSevLiveMigrationIsEnabled (
|
||||
+ VOID
|
||||
+ );
|
||||
+
|
||||
/**
|
||||
This function clears memory encryption bit for the memory region specified by
|
||||
BaseAddress and NumPages from the current page table context.
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||
index 4aba0075..d80ebe2f 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||
@@ -18,10 +18,14 @@
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
#include <ConfidentialComputingGuestAttr.h>
|
||||
|
||||
-STATIC UINT64 mCurrentAttr = 0;
|
||||
-STATIC BOOLEAN mCurrentAttrRead = FALSE;
|
||||
-STATIC UINT64 mSevEncryptionMask = 0;
|
||||
-STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;
|
||||
+#include "PeiDxeMemEncryptSevLibInternal.h"
|
||||
+
|
||||
+STATIC UINT64 mCurrentAttr = 0;
|
||||
+STATIC BOOLEAN mCurrentAttrRead = FALSE;
|
||||
+STATIC UINT64 mSevEncryptionMask = 0;
|
||||
+STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;
|
||||
+STATIC BOOLEAN mSevLiveMigrationStatus = FALSE;
|
||||
+STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE;
|
||||
|
||||
/**
|
||||
The function check if the specified Attr is set.
|
||||
@@ -111,6 +115,24 @@ MemEncryptSevSnpIsEnabled (
|
||||
return ConfidentialComputingGuestHas (CCAttrAmdSevSnp);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ Figures out if we are running inside KVM HVM and
|
||||
+ KVM HVM supports SEV Live Migration feature.
|
||||
+**/
|
||||
+STATIC
|
||||
+VOID
|
||||
+EFIAPI
|
||||
+InternalDetectSevLiveMigrationFeature (
|
||||
+ VOID
|
||||
+ )
|
||||
+{
|
||||
+ if (KvmDetectSevLiveMigrationFeature ()) {
|
||||
+ mSevLiveMigrationStatus = TRUE;
|
||||
+ }
|
||||
+
|
||||
+ mSevLiveMigrationStatusChecked = TRUE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
Returns a boolean to indicate whether SEV-ES is enabled.
|
||||
|
||||
@@ -141,6 +163,25 @@ MemEncryptSevIsEnabled (
|
||||
return ConfidentialComputingGuestHas (CCAttrAmdSev);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||
+
|
||||
+ @retval TRUE SEV live migration is enabled
|
||||
+ @retval FALSE SEV live migration is not enabled
|
||||
+**/
|
||||
+BOOLEAN
|
||||
+EFIAPI
|
||||
+MemEncryptSevLiveMigrationIsEnabled (
|
||||
+ VOID
|
||||
+ )
|
||||
+{
|
||||
+ if (!mSevLiveMigrationStatusChecked) {
|
||||
+ InternalDetectSevLiveMigrationFeature ();
|
||||
+ }
|
||||
+
|
||||
+ return mSevLiveMigrationStatus;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
Returns the SEV encryption mask.
|
||||
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
|
||||
index 78ea16ae..868392f7 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <Register/SmramSaveStateMap.h>
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
|
||||
+#include "PeiDxeMemEncryptSevLibInternal.h"
|
||||
+
|
||||
/**
|
||||
Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM
|
||||
Save State Map.
|
||||
@@ -61,3 +63,59 @@ MemEncryptSevLocateInitialSmramSaveStateMapPages (
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ Figures out if we are running inside KVM HVM and
|
||||
+ KVM HVM supports SEV Live Migration feature.
|
||||
+
|
||||
+ @retval TRUE SEV live migration is supported.
|
||||
+ @retval FALSE SEV live migration is not supported.
|
||||
+**/
|
||||
+BOOLEAN
|
||||
+EFIAPI
|
||||
+KvmDetectSevLiveMigrationFeature (
|
||||
+ VOID
|
||||
+ )
|
||||
+{
|
||||
+ CHAR8 Signature[13];
|
||||
+ UINT32 mKvmLeaf;
|
||||
+ UINT32 RegEax;
|
||||
+ UINT32 RegEbx;
|
||||
+ UINT32 RegEcx;
|
||||
+ UINT32 RegEdx;
|
||||
+
|
||||
+ Signature[12] = '\0';
|
||||
+ for (mKvmLeaf = 0x40000000; mKvmLeaf < 0x40010000; mKvmLeaf += 0x100) {
|
||||
+ AsmCpuid (
|
||||
+ mKvmLeaf,
|
||||
+ NULL,
|
||||
+ (UINT32 *)&Signature[0],
|
||||
+ (UINT32 *)&Signature[4],
|
||||
+ (UINT32 *)&Signature[8]
|
||||
+ );
|
||||
+
|
||||
+ if (AsciiStrCmp (Signature, "KVMKVMKVM") == 0) {
|
||||
+ DEBUG ((
|
||||
+ DEBUG_INFO,
|
||||
+ "%a: KVM Detected, signature = %a\n",
|
||||
+ __FUNCTION__,
|
||||
+ Signature
|
||||
+ ));
|
||||
+
|
||||
+ RegEax = mKvmLeaf + 1;
|
||||
+ RegEcx = 0;
|
||||
+ AsmCpuid (mKvmLeaf + 1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
|
||||
+ if ((RegEax & KVM_FEATURE_MIGRATION_CONTROL) != 0) {
|
||||
+ DEBUG ((
|
||||
+ DEBUG_INFO,
|
||||
+ "%a: SEV Live Migration feature supported\n",
|
||||
+ __FUNCTION__
|
||||
+ ));
|
||||
+
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return FALSE;
|
||||
+}
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h
|
||||
new file mode 100644
|
||||
index 00000000..b0ef053c
|
||||
--- /dev/null
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+/** @file
|
||||
+
|
||||
+ Secure Encrypted Virtualization (SEV) library helper function
|
||||
+
|
||||
+ Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
|
||||
+
|
||||
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
+
|
||||
+**/
|
||||
+
|
||||
+#ifndef PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_
|
||||
+#define PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_
|
||||
+
|
||||
+#include <Library/BaseLib.h>
|
||||
+
|
||||
+#define KVM_FEATURE_MIGRATION_CONTROL BIT17
|
||||
+
|
||||
+/**
|
||||
+ Figures out if we are running inside KVM HVM and
|
||||
+ KVM HVM supports SEV Live Migration feature.
|
||||
+
|
||||
+ @retval TRUE SEV live migration is supported.
|
||||
+ @retval FALSE SEV live migration is not supported.
|
||||
+**/
|
||||
+BOOLEAN
|
||||
+EFIAPI
|
||||
+KvmDetectSevLiveMigrationFeature (
|
||||
+ VOID
|
||||
+ );
|
||||
+
|
||||
+#endif // PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
|
||||
index 41d1246a..307087a1 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
|
||||
@@ -17,6 +17,11 @@
|
||||
#include <Register/Cpuid.h>
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
|
||||
+#include "PeiDxeMemEncryptSevLibInternal.h"
|
||||
+
|
||||
+STATIC BOOLEAN mSevLiveMigrationStatus = FALSE;
|
||||
+STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE;
|
||||
+
|
||||
/**
|
||||
Read the workarea to determine whether SEV is enabled. If enabled,
|
||||
then return the SevEsWorkArea pointer.
|
||||
@@ -83,6 +88,24 @@ MemEncryptSevSnpIsEnabled (
|
||||
return Msr.Bits.SevSnpBit ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ Figures out if we are running inside KVM HVM and
|
||||
+ KVM HVM supports SEV Live Migration feature.
|
||||
+**/
|
||||
+STATIC
|
||||
+VOID
|
||||
+EFIAPI
|
||||
+InternalDetectSevLiveMigrationFeature (
|
||||
+ VOID
|
||||
+ )
|
||||
+{
|
||||
+ if (KvmDetectSevLiveMigrationFeature ()) {
|
||||
+ mSevLiveMigrationStatus = TRUE;
|
||||
+ }
|
||||
+
|
||||
+ mSevLiveMigrationStatusChecked = TRUE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
Returns a boolean to indicate whether SEV-ES is enabled.
|
||||
|
||||
@@ -121,6 +144,25 @@ MemEncryptSevIsEnabled (
|
||||
return Msr.Bits.SevBit ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||
+
|
||||
+ @retval TRUE SEV live migration is enabled
|
||||
+ @retval FALSE SEV live migration is not enabled
|
||||
+**/
|
||||
+BOOLEAN
|
||||
+EFIAPI
|
||||
+MemEncryptSevLiveMigrationIsEnabled (
|
||||
+ VOID
|
||||
+ )
|
||||
+{
|
||||
+ if (!mSevLiveMigrationStatusChecked) {
|
||||
+ InternalDetectSevLiveMigrationFeature ();
|
||||
+ }
|
||||
+
|
||||
+ return mSevLiveMigrationStatus;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
Returns the SEV encryption mask.
|
||||
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||
index 27148c7e..9142ac40 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||
@@ -121,6 +121,24 @@ MemEncryptSevIsEnabled (
|
||||
return Msr.Bits.SevBit ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||
+
|
||||
+ @retval TRUE SEV live migration is enabled
|
||||
+ @retval FALSE SEV live migration is not enabled
|
||||
+**/
|
||||
+BOOLEAN
|
||||
+EFIAPI
|
||||
+MemEncryptSevLiveMigrationIsEnabled (
|
||||
+ VOID
|
||||
+ )
|
||||
+{
|
||||
+ //
|
||||
+ // Not used in SEC phase.
|
||||
+ //
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
Returns the SEV encryption mask.
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
301
0069-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch
Normal file
301
0069-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch
Normal file
@ -0,0 +1,301 @@
|
||||
From 2c000372cab80ab68a8672138c8d0f5cb1ae43d9 Mon Sep 17 00:00:00 2001
|
||||
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||
Date: Tue, 5 Apr 2022 16:23:53 +0000
|
||||
Subject: [PATCH 2/9] OvmfPkg/BaseMemEncryptLib: Hypercall API for page
|
||||
encryption state change
|
||||
|
||||
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||
|
||||
Add API to issue hypercall on page encryption state change.
|
||||
|
||||
By default all the SEV guest memory regions are considered encrypted,
|
||||
if a guest changes the encryption attribute of the page (e.g mark a
|
||||
page as decrypted) then notify hypervisor. Hypervisor will need to
|
||||
track the unencrypted pages. The information will be used during
|
||||
guest live migration, guest page migration and guest debugging.
|
||||
|
||||
This hypercall is used to notify hypervisor when the page's
|
||||
encryption state changes.
|
||||
|
||||
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||
---
|
||||
OvmfPkg/Include/Library/MemEncryptSevLib.h | 52 +++++++++++++++
|
||||
.../DxeMemEncryptSevLib.inf | 1 +
|
||||
.../Ia32/MemEncryptSevLib.c | 27 ++++++++
|
||||
.../PeiMemEncryptSevLib.inf | 1 +
|
||||
.../SecMemEncryptSevLibInternal.c | 20 ++++++
|
||||
.../X64/AsmHelperStub.nasm | 33 ++++++++++
|
||||
.../X64/MemEncryptSevLib.c | 66 +++++++++++++++++++
|
||||
7 files changed, 200 insertions(+)
|
||||
create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm
|
||||
|
||||
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||
index babec60d..b60496c2 100644
|
||||
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||
@@ -240,4 +240,56 @@ MemEncryptSevSnpPreValidateSystemRam (
|
||||
IN UINTN NumPages
|
||||
);
|
||||
|
||||
+/**
|
||||
+ This hypercall is used to notify hypervisor when the page's encryption
|
||||
+ state changes.
|
||||
+
|
||||
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||
+ of a memory region.
|
||||
+ @param[in] Pages Number of pages in memory region.
|
||||
+ @param[in] IsEncrypted Encrypted or Decrypted.
|
||||
+
|
||||
+ @retval RETURN_SUCCESS Hypercall returned success.
|
||||
+ @retval RETURN_UNSUPPORTED Hypercall not supported.
|
||||
+ @retval RETURN_NO_MAPPING Hypercall returned error.
|
||||
+**/
|
||||
+RETURN_STATUS
|
||||
+EFIAPI
|
||||
+SetMemoryEncDecHypercall3 (
|
||||
+ IN UINTN PhysicalAddress,
|
||||
+ IN UINTN Pages,
|
||||
+ IN BOOLEAN IsEncrypted
|
||||
+ );
|
||||
+
|
||||
+#define KVM_HC_MAP_GPA_RANGE 12
|
||||
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_4K 0
|
||||
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_2M BIT0
|
||||
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_1G BIT1
|
||||
+#define KVM_MAP_GPA_RANGE_ENC_STATE(n) ((n) << 4)
|
||||
+#define KVM_MAP_GPA_RANGE_ENCRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(1)
|
||||
+#define KVM_MAP_GPA_RANGE_DECRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(0)
|
||||
+
|
||||
+/**
|
||||
+ Interface exposed by the ASM implementation of the core hypercall
|
||||
+
|
||||
+ @param[in] HypercallNum KVM_HC_MAP_GPA_RANGE hypercall.
|
||||
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||
+ of a memory region.
|
||||
+ @param[in] Pages Number of pages in memory region.
|
||||
+ @param[in] Attributes Bits 3:0 - preferred page size encoding,
|
||||
+ 0 = 4kb, 1 = 2mb, 2 = 1gb, etc...
|
||||
+ Bit 4 - plaintext = 0, encrypted = 1
|
||||
+ Bits 63:5 - reserved (must be zero)
|
||||
+
|
||||
+ @retval Hypercall returned status.
|
||||
+**/
|
||||
+UINTN
|
||||
+EFIAPI
|
||||
+SetMemoryEncDecHypercall3AsmStub (
|
||||
+ IN UINTN HypercallNum,
|
||||
+ IN UINTN PhysicalAddress,
|
||||
+ IN UINTN Pages,
|
||||
+ IN UINTN Attributes
|
||||
+ );
|
||||
+
|
||||
#endif // _MEM_ENCRYPT_SEV_LIB_H_
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||
index 3a1d3089..4d32fae6 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||
@@ -40,6 +40,7 @@
|
||||
X64/SnpPageStateChangeInternal.c
|
||||
X64/VirtualMemory.c
|
||||
X64/VirtualMemory.h
|
||||
+ X64/AsmHelperStub.nasm
|
||||
|
||||
[Sources.IA32]
|
||||
Ia32/MemEncryptSevLib.c
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
|
||||
index f92299fc..c1c10a61 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
|
||||
@@ -153,3 +153,30 @@ MemEncryptSevSnpPreValidateSystemRam (
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ This hyercall is used to notify hypervisor when the page's encryption
|
||||
+ state changes.
|
||||
+
|
||||
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||
+ of a memory region.
|
||||
+ @param[in] Pages Number of Pages in the memory region.
|
||||
+ @param[in] IsEncrypted Encrypted or Decrypted.
|
||||
+
|
||||
+ @retval RETURN_SUCCESS Hypercall returned success.
|
||||
+ @retval RETURN_UNSUPPORTED Hypercall not supported.
|
||||
+ @retval RETURN_NO_MAPPING Hypercall returned error.
|
||||
+**/
|
||||
+RETURN_STATUS
|
||||
+EFIAPI
|
||||
+SetMemoryEncDecHypercall3 (
|
||||
+ IN UINTN PhysicalAddress,
|
||||
+ IN UINTN Pages,
|
||||
+ IN BOOLEAN IsEncrypted
|
||||
+ )
|
||||
+{
|
||||
+ //
|
||||
+ // Memory encryption bit is not accessible in 32-bit mode
|
||||
+ //
|
||||
+ return RETURN_UNSUPPORTED;
|
||||
+}
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
|
||||
index 8f56783d..3f11f06a 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
|
||||
@@ -40,6 +40,7 @@
|
||||
X64/SnpPageStateChangeInternal.c
|
||||
X64/VirtualMemory.c
|
||||
X64/VirtualMemory.h
|
||||
+ X64/AsmHelperStub.nasm
|
||||
|
||||
[Sources.IA32]
|
||||
Ia32/MemEncryptSevLib.c
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||
index 9142ac40..ffb22a08 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||
@@ -139,6 +139,26 @@ MemEncryptSevLiveMigrationIsEnabled (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ Interface exposed by the ASM implementation of the core hypercall
|
||||
+
|
||||
+ @retval Hypercall returned status.
|
||||
+**/
|
||||
+UINTN
|
||||
+EFIAPI
|
||||
+SetMemoryEncDecHypercall3AsmStub (
|
||||
+ IN UINTN HypercallNum,
|
||||
+ IN UINTN PhysicalAddress,
|
||||
+ IN UINTN Pages,
|
||||
+ IN UINTN Attributes
|
||||
+ )
|
||||
+{
|
||||
+ //
|
||||
+ // Not used in SEC phase.
|
||||
+ //
|
||||
+ return RETURN_UNSUPPORTED;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
Returns the SEV encryption mask.
|
||||
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm
|
||||
new file mode 100644
|
||||
index 00000000..0ec35dd9
|
||||
--- /dev/null
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm
|
||||
@@ -0,0 +1,33 @@
|
||||
+/** @file
|
||||
+
|
||||
+ ASM helper stub to invoke hypercall
|
||||
+
|
||||
+ Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
|
||||
+
|
||||
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
+
|
||||
+**/
|
||||
+
|
||||
+DEFAULT REL
|
||||
+SECTION .text
|
||||
+
|
||||
+; UINTN
|
||||
+; EFIAPI
|
||||
+; SetMemoryEncDecHypercall3AsmStub (
|
||||
+; IN UINTN HypercallNum,
|
||||
+; IN UINTN Arg1,
|
||||
+; IN UINTN Arg2,
|
||||
+; IN UINTN Arg3
|
||||
+; );
|
||||
+global ASM_PFX(SetMemoryEncDecHypercall3AsmStub)
|
||||
+ASM_PFX(SetMemoryEncDecHypercall3AsmStub):
|
||||
+ ; UEFI calling conventions require RBX to
|
||||
+ ; be nonvolatile/callee-saved.
|
||||
+ push rbx
|
||||
+ mov rax, rcx ; Copy HypercallNumber to rax
|
||||
+ mov rbx, rdx ; Copy Arg1 to the register expected by KVM
|
||||
+ mov rcx, r8 ; Copy Arg2 to register expected by KVM
|
||||
+ mov rdx, r9 ; Copy Arg3 to register expected by KVM
|
||||
+ vmmcall ; Call VMMCALL
|
||||
+ pop rbx
|
||||
+ ret
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||
index e7c703bb..a64ff2a5 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||
@@ -142,3 +142,69 @@ MemEncryptSevClearMmioPageEncMask (
|
||||
EFI_PAGES_TO_SIZE (NumPages)
|
||||
);
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ This hyercall is used to notify hypervisor when the page's encryption
|
||||
+ state changes.
|
||||
+
|
||||
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||
+ of a memory region.
|
||||
+ @param[in] Pages Number of Pages in the memory region.
|
||||
+ @param[in] IsEncrypted Encrypted or Decrypted.
|
||||
+
|
||||
+ @retval RETURN_SUCCESS Hypercall returned success.
|
||||
+ @retval RETURN_UNSUPPORTED Hypercall not supported.
|
||||
+ @retval RETURN_NO_MAPPING Hypercall returned error.
|
||||
+**/
|
||||
+RETURN_STATUS
|
||||
+EFIAPI
|
||||
+SetMemoryEncDecHypercall3 (
|
||||
+ IN UINTN PhysicalAddress,
|
||||
+ IN UINTN Pages,
|
||||
+ IN BOOLEAN IsEncrypted
|
||||
+ )
|
||||
+{
|
||||
+ RETURN_STATUS Ret;
|
||||
+ UINTN Error;
|
||||
+ UINTN EncryptState;
|
||||
+
|
||||
+ Ret = RETURN_UNSUPPORTED;
|
||||
+
|
||||
+ if (MemEncryptSevLiveMigrationIsEnabled ()) {
|
||||
+ Ret = RETURN_SUCCESS;
|
||||
+ //
|
||||
+ // The encryption bit is set/clear on the smallest page size, hence
|
||||
+ // use the 4k page size in MAP_GPA_RANGE hypercall below.
|
||||
+ //
|
||||
+ // Also, when the GCD map is being walked and the c-bit being cleared
|
||||
+ // from MMIO and NonExistent memory spaces, the physical address
|
||||
+ // range being passed may not be page-aligned and adding an assert
|
||||
+ // here prevents booting. Hence, rounding it down when calling
|
||||
+ // SetMemoryEncDecHypercall3AsmStub below.
|
||||
+ //
|
||||
+
|
||||
+ EncryptState = IsEncrypted ? KVM_MAP_GPA_RANGE_ENCRYPTED :
|
||||
+ KVM_MAP_GPA_RANGE_DECRYPTED;
|
||||
+
|
||||
+ Error = SetMemoryEncDecHypercall3AsmStub (
|
||||
+ KVM_HC_MAP_GPA_RANGE,
|
||||
+ PhysicalAddress & ~EFI_PAGE_MASK,
|
||||
+ Pages,
|
||||
+ KVM_MAP_GPA_RANGE_PAGE_SZ_4K | EncryptState
|
||||
+ );
|
||||
+
|
||||
+ if (Error != 0) {
|
||||
+ DEBUG ((
|
||||
+ DEBUG_ERROR,
|
||||
+ "SetMemoryEncDecHypercall3 failed, Phys = %x, Pages = %d, Err = %Ld\n",
|
||||
+ PhysicalAddress,
|
||||
+ Pages,
|
||||
+ (INT64)Error
|
||||
+ ));
|
||||
+
|
||||
+ Ret = RETURN_NO_MAPPING;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return Ret;
|
||||
+}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
From 481f0a191fc03e79bbb52b08c1d4890b6331e68d Mon Sep 17 00:00:00 2001
|
||||
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||
Date: Tue, 5 Apr 2022 16:26:02 +0000
|
||||
Subject: [PATCH 3/9] OvmfPkg/BaseMemEncryptLib: Invoke page encryption state
|
||||
change hypercall
|
||||
|
||||
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||
|
||||
Invoke the hypercall API to notify hypervisor when the page's
|
||||
encryption state changes.
|
||||
|
||||
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||
---
|
||||
.../X64/PeiDxeVirtualMemory.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||
index a49cf125..42e3b03f 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||
@@ -727,6 +727,7 @@ SetMemoryEncDec (
|
||||
UINT64 PgTableMask;
|
||||
UINT64 AddressEncMask;
|
||||
BOOLEAN IsWpEnabled;
|
||||
+ BOOLEAN CBitChanged;
|
||||
UINTN OrigLength;
|
||||
RETURN_STATUS Status;
|
||||
PHYSICAL_ADDRESS PageAddress;
|
||||
@@ -800,6 +801,7 @@ SetMemoryEncDec (
|
||||
// Save the specified length and physical address (we need it later).
|
||||
//
|
||||
OrigLength = Length;
|
||||
+ CBitChanged = FALSE;
|
||||
OrigPhysicalAddress = PhysicalAddress;
|
||||
|
||||
while (Length != 0) {
|
||||
@@ -860,6 +862,7 @@ SetMemoryEncDec (
|
||||
));
|
||||
PhysicalAddress += BIT30;
|
||||
Length -= BIT30;
|
||||
+ CBitChanged = TRUE;
|
||||
} else {
|
||||
//
|
||||
// We must split the page
|
||||
@@ -915,6 +918,7 @@ SetMemoryEncDec (
|
||||
SetOrClearCBit (&PageDirectory2MEntry->Uint64, Mode);
|
||||
PhysicalAddress += BIT21;
|
||||
Length -= BIT21;
|
||||
+ CBitChanged = TRUE;
|
||||
} else {
|
||||
//
|
||||
// We must split up this page into 4K pages
|
||||
@@ -958,6 +962,7 @@ SetMemoryEncDec (
|
||||
SetOrClearCBit (&PageTableEntry->Uint64, Mode);
|
||||
PhysicalAddress += EFI_PAGE_SIZE;
|
||||
Length -= EFI_PAGE_SIZE;
|
||||
+ CBitChanged = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -990,6 +995,17 @@ SetMemoryEncDec (
|
||||
);
|
||||
}
|
||||
|
||||
+ //
|
||||
+ // Notify Hypervisor on C-bit status
|
||||
+ //
|
||||
+ if (CBitChanged) {
|
||||
+ Status = SetMemoryEncDecHypercall3 (
|
||||
+ OrigPhysicalAddress,
|
||||
+ EFI_SIZE_TO_PAGES (OrigLength),
|
||||
+ (Mode == SetCBit) ? TRUE : FALSE
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
Done:
|
||||
//
|
||||
// Restore page table write protection, if any.
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From 1058be0934a043804f2ae0b8ea1aa42454dc0eb8 Mon Sep 17 00:00:00 2001
|
||||
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||
Date: Tue, 5 Apr 2022 16:27:26 +0000
|
||||
Subject: [PATCH 4/9] OvmfPkg/VmgExitLib: Encryption state change hypercall
|
||||
support in VC handler
|
||||
|
||||
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||
|
||||
Make the #VC handler aware of the page encryption state
|
||||
change hypercall by adding support to check KVM_HC_MAP_GPA_RANGE
|
||||
hypercall and add the additional register values used by
|
||||
hypercall in the GHCB.
|
||||
|
||||
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||
---
|
||||
OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
|
||||
index 0fc30f7b..5c9a9085 100644
|
||||
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
|
||||
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
|
||||
@@ -677,6 +677,19 @@ VmmCallExit (
|
||||
Ghcb->SaveArea.Cpl = (UINT8)(Regs->Cs & 0x3);
|
||||
CcExitVmgSetOffsetValid (Ghcb, GhcbCpl);
|
||||
|
||||
+ if (Regs->Rax == KVM_HC_MAP_GPA_RANGE) {
|
||||
+ //
|
||||
+ // KVM_HC_MAP_GPA_RANGE hypercall requires these
|
||||
+ // extra registers.
|
||||
+ //
|
||||
+ Ghcb->SaveArea.Rbx = Regs->Rbx;
|
||||
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRbx);
|
||||
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
|
||||
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRcx);
|
||||
+ Ghcb->SaveArea.Rdx = Regs->Rdx;
|
||||
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRdx);
|
||||
+ }
|
||||
+
|
||||
Status = CcExitVmgExit (Ghcb, SVM_EXIT_VMMCALL, 0, 0);
|
||||
if (Status != 0) {
|
||||
return Status;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
From 16e7adce62f7c28cc1823229b40a27493737cae6 Mon Sep 17 00:00:00 2001
|
||||
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||
Date: Tue, 5 Apr 2022 16:30:54 +0000
|
||||
Subject: [PATCH 5/9] OvmfPkg/PlatformPei: Mark SEC GHCB page as unencrypted
|
||||
via hypercall
|
||||
|
||||
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||
|
||||
Mark the SEC GHCB page (that is mapped as unencrypted in
|
||||
ResetVector code) in the hypervisor's guest page encryption
|
||||
state tracking.
|
||||
|
||||
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||
---
|
||||
OvmfPkg/PlatformPei/AmdSev.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
|
||||
index e6b602d7..553e841e 100644
|
||||
--- a/OvmfPkg/PlatformPei/AmdSev.c
|
||||
+++ b/OvmfPkg/PlatformPei/AmdSev.c
|
||||
@@ -229,6 +229,17 @@ AmdSevEsInitialize (
|
||||
Status = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
|
||||
ASSERT_RETURN_ERROR (Status);
|
||||
|
||||
+ //
|
||||
+ // The SEC Ghcb setup during reset-vector needs to be marked as
|
||||
+ // decrypted in the hypervisor's guest page encryption state
|
||||
+ // tracking.
|
||||
+ //
|
||||
+ SetMemoryEncDecHypercall3 (
|
||||
+ FixedPcdGet32 (PcdOvmfSecGhcbBase),
|
||||
+ EFI_SIZE_TO_PAGES (FixedPcdGet32 (PcdOvmfSecGhcbSize)),
|
||||
+ FALSE
|
||||
+ );
|
||||
+
|
||||
//
|
||||
// Allocate GHCB and per-CPU variable pages.
|
||||
// Since the pages must survive across the UEFI to OS transition
|
||||
--
|
||||
2.25.1
|
||||
|
||||
196
0073-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch
Normal file
196
0073-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch
Normal file
@ -0,0 +1,196 @@
|
||||
From 8d82fca148d9564b666b5f4185a0e78e1f77e230 Mon Sep 17 00:00:00 2001
|
||||
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||
Date: Tue, 5 Apr 2022 16:40:03 +0000
|
||||
Subject: [PATCH 6/9] OvmfPkg/AmdSevDxe: Add support for SEV live migration.
|
||||
|
||||
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||
|
||||
Check for SEV live migration feature support, if detected
|
||||
setup a new UEFI enviroment variable to indicate OVMF
|
||||
support for SEV live migration.
|
||||
|
||||
This environment variable is created by UEFI but consumed
|
||||
by the (guest) linux kernel. This is actually part of a
|
||||
3-way negotiation of the live migration feature between
|
||||
hypervisor, guest OVMF and guest kernel. Host indicates
|
||||
support for live migration, which is detected by OVMF
|
||||
and correspondingly OVMF sets this SetLiveMigrationEnabled
|
||||
UEFI variable, which is read by the guest kernel and it
|
||||
indicates to the guest kernel that both host and OVMF
|
||||
support and have enabled the live migration feature.
|
||||
|
||||
The new runtime UEFI environment variable is set via the
|
||||
notification function registered for the
|
||||
EFI_END_OF_DXE_EVENT_GROUP_GUID event in AmdSevDxe driver.
|
||||
|
||||
AmdSevDxe module is an apriori driver so it gets loaded between PEI
|
||||
and DXE phases and the SetVariable call will fail at the driver's
|
||||
entry point as the Variable DXE module is still not loaded yet.
|
||||
So we need to wait for an event notification which is signaled
|
||||
after the Variable DXE module is loaded, hence, using the
|
||||
EndOfDxe event notification to make this call.
|
||||
|
||||
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||
---
|
||||
OvmfPkg/AmdSevDxe/AmdSevDxe.c | 67 ++++++++++++++++++++++
|
||||
OvmfPkg/AmdSevDxe/AmdSevDxe.inf | 4 ++
|
||||
OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h | 20 +++++++
|
||||
OvmfPkg/OvmfPkg.dec | 1 +
|
||||
4 files changed, 92 insertions(+)
|
||||
create mode 100644 OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h
|
||||
|
||||
diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
|
||||
index db3675ae..e3a8049d 100644
|
||||
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c
|
||||
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
|
||||
@@ -15,10 +15,13 @@
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
+#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/MemEncryptSevLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Guid/ConfidentialComputingSevSnpBlob.h>
|
||||
+#include <Guid/AmdSevMemEncryptLib.h>
|
||||
+#include <Guid/EventGroup.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Pi/PrePiDxeCis.h>
|
||||
#include <Protocol/SevMemoryAcceptance.h>
|
||||
@@ -191,6 +194,39 @@ STATIC EDKII_MEMORY_ACCEPT_PROTOCOL mMemoryAcceptProtocol = {
|
||||
AmdSevMemoryAccept
|
||||
};
|
||||
|
||||
+STATIC
|
||||
+VOID
|
||||
+EFIAPI
|
||||
+AmdSevDxeOnEndOfDxe (
|
||||
+ IN EFI_EVENT Event,
|
||||
+ IN VOID *EventToSignal
|
||||
+ )
|
||||
+{
|
||||
+ EFI_STATUS Status;
|
||||
+ BOOLEAN SevLiveMigrationEnabled;
|
||||
+
|
||||
+ SevLiveMigrationEnabled = MemEncryptSevLiveMigrationIsEnabled ();
|
||||
+
|
||||
+ if (SevLiveMigrationEnabled) {
|
||||
+ Status = gRT->SetVariable (
|
||||
+ L"SevLiveMigrationEnabled",
|
||||
+ &gAmdSevMemEncryptGuid,
|
||||
+ EFI_VARIABLE_NON_VOLATILE |
|
||||
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
+ EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
+ sizeof SevLiveMigrationEnabled,
|
||||
+ &SevLiveMigrationEnabled
|
||||
+ );
|
||||
+
|
||||
+ DEBUG ((
|
||||
+ DEBUG_INFO,
|
||||
+ "%a: Setting SevLiveMigrationEnabled variable, status = %lx\n",
|
||||
+ __FUNCTION__,
|
||||
+ Status
|
||||
+ ));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
AmdSevDxeEntryPoint (
|
||||
@@ -203,6 +239,7 @@ AmdSevDxeEntryPoint (
|
||||
UINTN NumEntries;
|
||||
UINTN Index;
|
||||
CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION *SnpBootDxeTable;
|
||||
+ EFI_EVENT Event;
|
||||
|
||||
//
|
||||
// Do nothing when SEV is not enabled
|
||||
@@ -361,5 +398,35 @@ AmdSevDxeEntryPoint (
|
||||
);
|
||||
}
|
||||
|
||||
+ //
|
||||
+ // AmdSevDxe module is an apriori driver so it gets loaded between PEI
|
||||
+ // and DXE phases and the SetVariable call will fail at the driver's
|
||||
+ // entry point as the Variable DXE module is still not loaded yet.
|
||||
+ // So we need to wait for an event notification which is signaled
|
||||
+ // after the Variable DXE module is loaded, hence, using the
|
||||
+ // EndOfDxe event notification to make this call.
|
||||
+ //
|
||||
+ // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
|
||||
+ // The notification function sets the runtime variable indicating OVMF
|
||||
+ // support for SEV live migration.
|
||||
+ //
|
||||
+ Status = gBS->CreateEventEx (
|
||||
+ EVT_NOTIFY_SIGNAL,
|
||||
+ TPL_CALLBACK,
|
||||
+ AmdSevDxeOnEndOfDxe,
|
||||
+ NULL,
|
||||
+ &gEfiEndOfDxeEventGroupGuid,
|
||||
+ &Event
|
||||
+ );
|
||||
+
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ DEBUG ((
|
||||
+ DEBUG_ERROR,
|
||||
+ "%a: CreateEventEx(): %r\n",
|
||||
+ __FUNCTION__,
|
||||
+ Status
|
||||
+ ));
|
||||
+ }
|
||||
+
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
|
||||
index e7c7d526..dd1da527 100644
|
||||
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
|
||||
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
|
||||
@@ -57,3 +57,7 @@
|
||||
|
||||
[Pcd]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
|
||||
+
|
||||
+[Guids]
|
||||
+ gAmdSevMemEncryptGuid
|
||||
+ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
|
||||
diff --git a/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h
|
||||
new file mode 100644
|
||||
index 00000000..62d22e79
|
||||
--- /dev/null
|
||||
+++ b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/** @file
|
||||
+
|
||||
+ AMD Memory Encryption GUID, define a new GUID for defining
|
||||
+ new UEFI environment variables assocaiated with SEV Memory Encryption.
|
||||
+
|
||||
+ Copyright (c) 2021, AMD Inc. All rights reserved.<BR>
|
||||
+
|
||||
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
+
|
||||
+**/
|
||||
+
|
||||
+#ifndef __AMD_SEV_MEMENCRYPT_LIB_H__
|
||||
+#define __AMD_SEV_MEMENCRYPT_LIB_H__
|
||||
+
|
||||
+#define AMD_SEV_MEMENCRYPT_GUID \
|
||||
+{0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
|
||||
+
|
||||
+extern EFI_GUID gAmdSevMemEncryptGuid;
|
||||
+
|
||||
+#endif
|
||||
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
|
||||
index 34bca309..d50b1ae3 100644
|
||||
--- a/OvmfPkg/OvmfPkg.dec
|
||||
+++ b/OvmfPkg/OvmfPkg.dec
|
||||
@@ -170,6 +170,7 @@
|
||||
gUefiOvmfPkgTdxAcpiHobGuid = {0x6a0c5870, 0xd4ed, 0x44f4, {0xa1, 0x35, 0xdd, 0x23, 0x8b, 0x6f, 0x0c, 0x8d}}
|
||||
gEfiNonCcFvGuid = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}}
|
||||
gOvmfVariableGuid = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}}
|
||||
+ gAmdSevMemEncryptGuid = {0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
|
||||
|
||||
[Ppis]
|
||||
# PPI whose presence in the PPI database signals that the TPM base address
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
From fbdd6e4664e41eb299a797f1ab615d81b1bd958b Mon Sep 17 00:00:00 2001
|
||||
From: hanliyang <hanliyang@hygon.cn>
|
||||
Date: Mon, 17 Jan 2022 01:19:21 -0500
|
||||
Subject: [PATCH 7/9] OvmfPkg/BaseMemcryptSevLib: Correct the calculation of
|
||||
page range that notified to hypervisor
|
||||
|
||||
Correct the calculation of page range that notified to hypervisor.
|
||||
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
.../Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||
index 42e3b03f..69ada871 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||
@@ -999,9 +999,13 @@ SetMemoryEncDec (
|
||||
// Notify Hypervisor on C-bit status
|
||||
//
|
||||
if (CBitChanged) {
|
||||
+ UINTN StartPfn = OrigPhysicalAddress >> EFI_PAGE_SHIFT;
|
||||
+ UINTN EndPfn = (OrigPhysicalAddress + OrigLength +
|
||||
+ ((1 << EFI_PAGE_SHIFT) - 1)) >> EFI_PAGE_SHIFT;
|
||||
+
|
||||
Status = SetMemoryEncDecHypercall3 (
|
||||
OrigPhysicalAddress,
|
||||
- EFI_SIZE_TO_PAGES (OrigLength),
|
||||
+ (EndPfn - StartPfn),
|
||||
(Mode == SetCBit) ? TRUE : FALSE
|
||||
);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From 6b7bb04614be39e9903c602dd65ba18426f6a6f2 Mon Sep 17 00:00:00 2001
|
||||
From: hanliyang <hanliyang@hygon.cn>
|
||||
Date: Sun, 19 Jun 2022 18:12:35 +0800
|
||||
Subject: [PATCH 8/9] OvmfPkg/BaseMemEncryptLib: Return SUCCESS if not support
|
||||
SEV live migration
|
||||
|
||||
Add this change to avoid trigger 'ASSERT_EFI_ERROR (Status = Unsupported)'
|
||||
when QEMU doesn't support SEV live migration.
|
||||
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||
index a64ff2a5..7b29582d 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||
@@ -168,10 +168,12 @@ SetMemoryEncDecHypercall3 (
|
||||
UINTN Error;
|
||||
UINTN EncryptState;
|
||||
|
||||
- Ret = RETURN_UNSUPPORTED;
|
||||
+ //
|
||||
+ // Return success if not support migration.
|
||||
+ //
|
||||
+ Ret = RETURN_SUCCESS;
|
||||
|
||||
if (MemEncryptSevLiveMigrationIsEnabled ()) {
|
||||
- Ret = RETURN_SUCCESS;
|
||||
//
|
||||
// The encryption bit is set/clear on the smallest page size, hence
|
||||
// use the 4k page size in MAP_GPA_RANGE hypercall below.
|
||||
--
|
||||
2.25.1
|
||||
|
||||
159
0076-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt-status.patch
Normal file
159
0076-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt-status.patch
Normal file
@ -0,0 +1,159 @@
|
||||
From d9edefe3936aecbb9640a390cd990f1771e0dac2 Mon Sep 17 00:00:00 2001
|
||||
From: Xin Jiang <jiangxin@hygon.cn>
|
||||
Date: Wed, 10 Jan 2024 17:34:57 +0800
|
||||
Subject: [PATCH 9/9] OvmfPkg/BaseMemEncryptLib: Save memory encrypt status in
|
||||
reserved memory
|
||||
|
||||
The MMIO routine of VC handler will get memory encrypt status to
|
||||
validate MMIO address. MemEncryptSevGetEncryptionMask() will enable
|
||||
interrupt while interrupt must be disabled during VC.
|
||||
|
||||
During DXE stage, VC routine as below:
|
||||
CcExitHandleVc->MemEncryptSevGetAddressRangeState->
|
||||
MemEncryptSevGetEncryptionMask->PcdGet64(PcdPteMemoryEncryptionAddressOrMask)
|
||||
|
||||
Unfortunately, PcdGet64() will enable interrupt in VC context.
|
||||
|
||||
Signed-off-by: Xin Jiang <jiangxin@hygon.cn>
|
||||
---
|
||||
OvmfPkg/AmdSev/AmdSevX64.fdf | 5 ++++-
|
||||
.../Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 4 ++++
|
||||
.../BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c | 9 ++-------
|
||||
OvmfPkg/OvmfPkg.dec | 4 ++++
|
||||
OvmfPkg/OvmfPkgX64.fdf | 5 ++++-
|
||||
OvmfPkg/PlatformPei/AmdSev.c | 2 ++
|
||||
OvmfPkg/PlatformPei/Csv.c | 6 ++++++
|
||||
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
|
||||
8 files changed, 28 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
|
||||
index 714ab004..b0d9033f 100644
|
||||
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
|
||||
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
|
||||
@@ -80,7 +80,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGui
|
||||
0x012000|0x001000
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize
|
||||
|
||||
-0x013000|0x00D000
|
||||
+0x013000|0x001000
|
||||
+gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||
+
|
||||
+0x014000|0x00C000
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
|
||||
|
||||
0x020000|0x0E0000
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||
index 4d32fae6..6f2f69d0 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||
@@ -61,3 +61,7 @@
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
|
||||
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr
|
||||
+
|
||||
+[FixedPcd]
|
||||
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase
|
||||
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||
index d80ebe2f..a9d43237 100644
|
||||
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
STATIC UINT64 mCurrentAttr = 0;
|
||||
STATIC BOOLEAN mCurrentAttrRead = FALSE;
|
||||
-STATIC UINT64 mSevEncryptionMask = 0;
|
||||
-STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;
|
||||
STATIC BOOLEAN mSevLiveMigrationStatus = FALSE;
|
||||
STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE;
|
||||
|
||||
@@ -193,10 +191,7 @@ MemEncryptSevGetEncryptionMask (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
- if (!mSevEncryptionMaskSaved) {
|
||||
- mSevEncryptionMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);
|
||||
- mSevEncryptionMaskSaved = TRUE;
|
||||
- }
|
||||
+ UINT64 *MemEncryptStatus = (UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase);
|
||||
|
||||
- return mSevEncryptionMask;
|
||||
+ return *MemEncryptStatus;
|
||||
}
|
||||
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
|
||||
index d50b1ae3..a6016d58 100644
|
||||
--- a/OvmfPkg/OvmfPkg.dec
|
||||
+++ b/OvmfPkg/OvmfPkg.dec
|
||||
@@ -443,6 +443,10 @@
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|0|UINT32|0x72
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize|0|UINT32|0x73
|
||||
|
||||
+ ## the base address of memory encryption status.
|
||||
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|0|UINT32|0x74
|
||||
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize|0|UINT32|0x75
|
||||
+
|
||||
[PcdsDynamic, PcdsDynamicEx]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
|
||||
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
|
||||
index b1cf0d99..a34b9f57 100644
|
||||
--- a/OvmfPkg/OvmfPkgX64.fdf
|
||||
+++ b/OvmfPkg/OvmfPkgX64.fdf
|
||||
@@ -100,7 +100,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGui
|
||||
0x011000|0x001000
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize
|
||||
|
||||
-0x012000|0x00E000
|
||||
+0x012000|0x001000
|
||||
+gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||
+
|
||||
+0x013000|0x00D000
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
|
||||
|
||||
0x020000|0x0E0000
|
||||
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
|
||||
index 553e841e..7c4ef899 100644
|
||||
--- a/OvmfPkg/PlatformPei/AmdSev.c
|
||||
+++ b/OvmfPkg/PlatformPei/AmdSev.c
|
||||
@@ -379,6 +379,8 @@ AmdSevInitialize (
|
||||
PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask);
|
||||
ASSERT_RETURN_ERROR (PcdStatus);
|
||||
|
||||
+ *(UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase) = EncryptionMask;
|
||||
+
|
||||
DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask));
|
||||
|
||||
//
|
||||
diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c
|
||||
index a52112d5..fe8c059b 100644
|
||||
--- a/OvmfPkg/PlatformPei/Csv.c
|
||||
+++ b/OvmfPkg/PlatformPei/Csv.c
|
||||
@@ -33,6 +33,12 @@ CsvInitializeMemInfo (
|
||||
UINT64 LowerMemorySize;
|
||||
UINT64 UpperMemorySize;
|
||||
|
||||
+ BuildMemoryAllocationHob (
|
||||
+ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusBase),
|
||||
+ (UINT64)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusSize),
|
||||
+ EfiReservedMemoryType
|
||||
+ );
|
||||
+
|
||||
if (!CsvIsEnabled ()) {
|
||||
return ;
|
||||
}
|
||||
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
|
||||
index 07de179f..c2d503fa 100644
|
||||
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
|
||||
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
|
||||
@@ -137,6 +137,8 @@
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize
|
||||
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase
|
||||
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||
|
||||
[FeaturePcd]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable
|
||||
--
|
||||
2.25.1
|
||||
|
||||
218
0077-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch
Normal file
218
0077-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From ceb82e7d081399dd91cc6e0e8eabd5b7260afac0 Mon Sep 17 00:00:00 2001
|
||||
From: Adttil <2429917001@qq.com>
|
||||
Date: Fri, 29 Nov 2024 08:35:27 +0800
|
||||
Subject: [PATCH 1/3] VirtioDxe: add support of MMIO Bar for virtio devices
|
||||
|
||||
As some virtio devices support MMIO BAR, add support for
|
||||
it in Virtio10Dxe and VirtioPciDeviceDXE.
|
||||
|
||||
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
||||
---
|
||||
OvmfPkg/Include/Protocol/VirtioDevice.h | 12 +++
|
||||
.../VirtioMmioDeviceLib/VirtioMmioDevice.c | 1 +
|
||||
OvmfPkg/Virtio10Dxe/Virtio10.c | 1 +
|
||||
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c | 89 +++++++++++++++----
|
||||
4 files changed, 85 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
|
||||
index ad37f4e3..802b8970 100644
|
||||
--- a/OvmfPkg/Include/Protocol/VirtioDevice.h
|
||||
+++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
|
||||
@@ -466,6 +466,16 @@ EFI_STATUS
|
||||
IN VOID *Mapping
|
||||
);
|
||||
|
||||
+/**
|
||||
+ * Note: Zero virtio devices has BAR0 of type MMIO but not PIO which do not
|
||||
+ * flow the virtio 0.95 spec due to hw limiation. We extend edk2 to support
|
||||
+ * such variant.
|
||||
+ */
|
||||
+typedef enum {
|
||||
+ VirtioCfgSpaceAcessIo = 0,
|
||||
+ VirtioCfgSpaceAcessMem
|
||||
+} VIRTIO_CFG_SPACE_ACCESS_MODE;
|
||||
+
|
||||
///
|
||||
/// This protocol provides an abstraction over the VirtIo transport layer
|
||||
///
|
||||
@@ -482,6 +492,8 @@ struct _VIRTIO_DEVICE_PROTOCOL {
|
||||
//
|
||||
INT32 SubSystemDeviceId;
|
||||
|
||||
+ VIRTIO_CFG_SPACE_ACCESS_MODE CfgAccessMode;
|
||||
+
|
||||
VIRTIO_GET_DEVICE_FEATURES GetDeviceFeatures;
|
||||
VIRTIO_SET_GUEST_FEATURES SetGuestFeatures;
|
||||
|
||||
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
||||
index fac32422..a340711d 100644
|
||||
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
||||
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
||||
@@ -17,6 +17,7 @@
|
||||
STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {
|
||||
0, // Revision
|
||||
0, // SubSystemDeviceId
|
||||
+ 0, // CfgAccessMode
|
||||
VirtioMmioGetDeviceFeatures, // GetDeviceFeatures
|
||||
VirtioMmioSetGuestFeatures, // SetGuestFeatures
|
||||
VirtioMmioSetQueueAddress, // SetQueueAddress
|
||||
diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
|
||||
index 970524f6..b968b016 100644
|
||||
--- a/OvmfPkg/Virtio10Dxe/Virtio10.c
|
||||
+++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
|
||||
@@ -954,6 +954,7 @@ Virtio10UnmapSharedBuffer (
|
||||
STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
|
||||
VIRTIO_SPEC_REVISION (1, 0, 0),
|
||||
0, // SubSystemDeviceId, filled in dynamically
|
||||
+ 0, // CfgAccessMode
|
||||
Virtio10GetDeviceFeatures,
|
||||
Virtio10SetGuestFeatures,
|
||||
Virtio10SetQueueAddress,
|
||||
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
||||
index b4ac195b..61ff376d 100644
|
||||
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
||||
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
||||
@@ -23,6 +23,7 @@
|
||||
STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = {
|
||||
0, // Revision
|
||||
0, // SubSystemDeviceId
|
||||
+ 0, // CfgAccessMode
|
||||
VirtioPciGetDeviceFeatures, // GetDeviceFeatures
|
||||
VirtioPciSetGuestFeatures, // SetGuestFeatures
|
||||
VirtioPciSetQueueAddress, // SetQueueAddress
|
||||
@@ -117,14 +118,25 @@ VirtioPciIoRead (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
- return PciIo->Io.Read (
|
||||
- PciIo,
|
||||
- Width,
|
||||
- PCI_BAR_IDX0,
|
||||
- FieldOffset,
|
||||
- Count,
|
||||
- Buffer
|
||||
- );
|
||||
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
|
||||
+ return PciIo->Io.Read (
|
||||
+ PciIo,
|
||||
+ Width,
|
||||
+ PCI_BAR_IDX0,
|
||||
+ FieldOffset,
|
||||
+ Count,
|
||||
+ Buffer
|
||||
+ );
|
||||
+ } else {
|
||||
+ return PciIo->Mem.Read (
|
||||
+ PciIo,
|
||||
+ Width,
|
||||
+ PCI_BAR_IDX0,
|
||||
+ FieldOffset,
|
||||
+ Count,
|
||||
+ Buffer
|
||||
+ );
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,14 +209,25 @@ VirtioPciIoWrite (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
- return PciIo->Io.Write (
|
||||
- PciIo,
|
||||
- Width,
|
||||
- PCI_BAR_IDX0,
|
||||
- FieldOffset,
|
||||
- Count,
|
||||
- &Value
|
||||
- );
|
||||
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
|
||||
+ return PciIo->Io.Write (
|
||||
+ PciIo,
|
||||
+ Width,
|
||||
+ PCI_BAR_IDX0,
|
||||
+ FieldOffset,
|
||||
+ Count,
|
||||
+ &Value
|
||||
+ );
|
||||
+ } else {
|
||||
+ return PciIo->Mem.Write (
|
||||
+ PciIo,
|
||||
+ Width,
|
||||
+ PCI_BAR_IDX0,
|
||||
+ FieldOffset,
|
||||
+ Count,
|
||||
+ &Value
|
||||
+ );
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -332,6 +355,7 @@ VirtioPciInit (
|
||||
EFI_STATUS Status;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
PCI_TYPE00 Pci;
|
||||
+ VOID *Resources;
|
||||
|
||||
ASSERT (Device != NULL);
|
||||
PciIo = Device->PciIo;
|
||||
@@ -373,6 +397,27 @@ VirtioPciInit (
|
||||
Device->DeviceSpecificConfigurationOffset =
|
||||
VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI;
|
||||
|
||||
+ Status = PciIo->GetBarAttributes(PciIo, PCI_BAR_IDX0, NULL, &Resources);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ if (*(UINT8 *)Resources == ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) {
|
||||
+ EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
|
||||
+
|
||||
+ Descriptor = Resources;
|
||||
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
|
||||
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessMem;
|
||||
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio MMIO BAR used.\n", __FUNCTION__));
|
||||
+ } else {
|
||||
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
|
||||
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio IO BAR used.\n", __FUNCTION__));
|
||||
+ }
|
||||
+ } else {
|
||||
+ DEBUG ((DEBUG_WARN, "%a: Cannot determine BAR0 type, assume IO.\n", __FUNCTION__));
|
||||
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
|
||||
+ }
|
||||
+
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -434,6 +479,7 @@ VirtioPciDeviceBindingStart (
|
||||
{
|
||||
VIRTIO_PCI_DEVICE *Device;
|
||||
EFI_STATUS Status;
|
||||
+ UINT64 Attributes;
|
||||
|
||||
Device = (VIRTIO_PCI_DEVICE *)AllocateZeroPool (sizeof *Device);
|
||||
if (Device == NULL) {
|
||||
@@ -473,11 +519,18 @@ VirtioPciDeviceBindingStart (
|
||||
goto ClosePciIo;
|
||||
}
|
||||
|
||||
+ Status = Device->PciIo->Attributes (Device->PciIo,
|
||||
+ EfiPciIoAttributeOperationSupported,
|
||||
+ 0, &Attributes);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ goto ClosePciIo;
|
||||
+ }
|
||||
+
|
||||
+ Attributes &= (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO);
|
||||
Status = Device->PciIo->Attributes (
|
||||
Device->PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
- (EFI_PCI_IO_ATTRIBUTE_IO |
|
||||
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
|
||||
+ Attributes | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
123
0078-Virtio-wait-virtio-device-reset-done.patch
Normal file
123
0078-Virtio-wait-virtio-device-reset-done.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 05de598734e741c596394bfbe42b1ab7af8316e1 Mon Sep 17 00:00:00 2001
|
||||
From: Adttil <2429917001@qq.com>
|
||||
Date: Fri, 29 Nov 2024 08:46:00 +0800
|
||||
Subject: [PATCH 2/3] Virtio: wait virtio device reset done.
|
||||
|
||||
The Virtio 1.0 driver performs subsequent negotiation operations
|
||||
only after the device reset operation is complete.
|
||||
|
||||
Implement this in the VirtioScsiDxe and VirtioBlkDxe.
|
||||
|
||||
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
||||
---
|
||||
OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 21 +++++++++++++++++++++
|
||||
OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 21 +++++++++++++++++++++
|
||||
2 files changed, 42 insertions(+)
|
||||
|
||||
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||
index 74ed52f9..eed56994 100644
|
||||
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||
@@ -28,6 +28,9 @@
|
||||
|
||||
#include "VirtioBlk.h"
|
||||
|
||||
+#define MAX_RETRY_TIMES 1000
|
||||
+#define DEVICE_WAIT_INTVL 1000
|
||||
+
|
||||
/**
|
||||
|
||||
Convenience macros to read and write region 0 IO space elements of the
|
||||
@@ -721,6 +724,10 @@ VirtioBlkInit (
|
||||
UINT32 OptIoSize;
|
||||
UINT16 QueueSize;
|
||||
UINT64 RingBaseShift;
|
||||
+ UINT8 DevStat;
|
||||
+ UINT16 RetryTimes;
|
||||
+
|
||||
+ RetryTimes = MAX_RETRY_TIMES;
|
||||
|
||||
PhysicalBlockExp = 0;
|
||||
AlignmentOffset = 0;
|
||||
@@ -735,12 +742,26 @@ VirtioBlkInit (
|
||||
goto Failed;
|
||||
}
|
||||
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ RetryTimes--;
|
||||
+ }
|
||||
+
|
||||
NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
|
||||
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Failed;
|
||||
}
|
||||
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ RetryTimes--;
|
||||
+ }
|
||||
+
|
||||
NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
|
||||
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||
if (EFI_ERROR (Status)) {
|
||||
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
|
||||
index 3705f5fc..580fe731 100644
|
||||
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
|
||||
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
|
||||
@@ -43,6 +43,9 @@
|
||||
|
||||
#include "VirtioScsi.h"
|
||||
|
||||
+#define MAX_RETRY_TIMES 1000
|
||||
+#define DEVICE_WAIT_INTVL 1000
|
||||
+
|
||||
/**
|
||||
|
||||
Convenience macros to read and write configuration elements of the
|
||||
@@ -932,6 +935,10 @@ VirtioScsiInit (
|
||||
UINT16 MaxChannel; // for validation only
|
||||
UINT32 NumQueues; // for validation only
|
||||
UINT16 QueueSize;
|
||||
+ UINT8 DevStat;
|
||||
+ UINT16 RetryTimes;
|
||||
+
|
||||
+ RetryTimes = MAX_RETRY_TIMES;
|
||||
|
||||
//
|
||||
// Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
|
||||
@@ -942,12 +949,26 @@ VirtioScsiInit (
|
||||
goto Failed;
|
||||
}
|
||||
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ RetryTimes--;
|
||||
+ }
|
||||
+
|
||||
NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
|
||||
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Failed;
|
||||
}
|
||||
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||
+ RetryTimes--;
|
||||
+ }
|
||||
+
|
||||
NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
|
||||
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||
if (EFI_ERROR (Status)) {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
250
0079-VirtioBlk-split-large-IO-according-to-segment_size_m.patch
Normal file
250
0079-VirtioBlk-split-large-IO-according-to-segment_size_m.patch
Normal file
@ -0,0 +1,250 @@
|
||||
From 734457162d02f6b4d66b8eb82da0717765fceebe Mon Sep 17 00:00:00 2001
|
||||
From: Adttil <2429917001@qq.com>
|
||||
Date: Fri, 29 Nov 2024 09:04:13 +0800
|
||||
Subject: [PATCH 3/3] VirtioBlk: split large IO according to segment_size_max
|
||||
|
||||
When the VirtioBlk device is initialized, the value of SegmentSizeMax
|
||||
is obtained based on the feature capability. Then delivere the requests
|
||||
based on the value of SegmentSizeMax.
|
||||
|
||||
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
||||
---
|
||||
MdePkg/Include/Protocol/BlockIo.h | 10 ++
|
||||
OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 148 +++++++++++++++++++++---------
|
||||
2 files changed, 117 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/MdePkg/Include/Protocol/BlockIo.h b/MdePkg/Include/Protocol/BlockIo.h
|
||||
index ac9adf7a..ac5e1c2a 100644
|
||||
--- a/MdePkg/Include/Protocol/BlockIo.h
|
||||
+++ b/MdePkg/Include/Protocol/BlockIo.h
|
||||
@@ -197,6 +197,16 @@ typedef struct {
|
||||
/// granularity as a number of logical blocks.
|
||||
///
|
||||
UINT32 OptimalTransferLengthGranularity;
|
||||
+
|
||||
+ ///
|
||||
+ /// Maximum size of any single segment
|
||||
+ ///
|
||||
+ UINT32 MaxSegmentSize;
|
||||
+
|
||||
+ ///
|
||||
+ /// Maximum number of segments in a request
|
||||
+ ///
|
||||
+ UINT32 MaxSegments;
|
||||
} EFI_BLOCK_IO_MEDIA;
|
||||
|
||||
#define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000
|
||||
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||
index eed56994..6d7c7aef 100644
|
||||
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||
@@ -31,6 +31,8 @@
|
||||
#define MAX_RETRY_TIMES 1000
|
||||
#define DEVICE_WAIT_INTVL 1000
|
||||
|
||||
+#define DEFAULT_MAX_SEGMENTS 32
|
||||
+
|
||||
/**
|
||||
|
||||
Convenience macros to read and write region 0 IO space elements of the
|
||||
@@ -460,6 +462,68 @@ FreeHostStatusBuffer:
|
||||
return Status;
|
||||
}
|
||||
|
||||
+STATIC
|
||||
+EFI_STATUS
|
||||
+EFIAPI
|
||||
+VirtioBlkReadWriteBlocks (
|
||||
+ IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
+ IN UINT32 MediaId,
|
||||
+ IN EFI_LBA Lba,
|
||||
+ IN UINTN BufferSize,
|
||||
+ IN OUT VOID *Buffer,
|
||||
+ IN BOOLEAN RequestIsWrite
|
||||
+ )
|
||||
+{
|
||||
+ VBLK_DEV *Dev;
|
||||
+ EFI_STATUS Status;
|
||||
+ UINT32 SizeMax;
|
||||
+
|
||||
+ if (BufferSize == 0) {
|
||||
+ return EFI_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
|
||||
+ Status = VerifyReadWriteRequest (
|
||||
+ &Dev->BlockIoMedia,
|
||||
+ Lba,
|
||||
+ BufferSize,
|
||||
+ RequestIsWrite
|
||||
+ );
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ SizeMax = Dev->BlockIoMedia.MaxSegmentSize;
|
||||
+ while (BufferSize >= SizeMax) {
|
||||
+ Status = SynchronousRequest (
|
||||
+ Dev,
|
||||
+ Lba,
|
||||
+ SizeMax,
|
||||
+ Buffer,
|
||||
+ RequestIsWrite
|
||||
+ );
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ Lba += SizeMax / Dev->BlockIoMedia.BlockSize;
|
||||
+ BufferSize -= SizeMax;
|
||||
+ Buffer = (CHAR8 *)Buffer + SizeMax;
|
||||
+ }
|
||||
+
|
||||
+ if (BufferSize == 0) {
|
||||
+ return EFI_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ return SynchronousRequest (
|
||||
+ Dev,
|
||||
+ Lba,
|
||||
+ BufferSize,
|
||||
+ Buffer,
|
||||
+ RequestIsWrite
|
||||
+ );
|
||||
+}
|
||||
+
|
||||
/**
|
||||
|
||||
ReadBlocks() operation for virtio-blk.
|
||||
@@ -487,30 +551,13 @@ VirtioBlkReadBlocks (
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
- VBLK_DEV *Dev;
|
||||
- EFI_STATUS Status;
|
||||
-
|
||||
- if (BufferSize == 0) {
|
||||
- return EFI_SUCCESS;
|
||||
- }
|
||||
-
|
||||
- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
|
||||
- Status = VerifyReadWriteRequest (
|
||||
- &Dev->BlockIoMedia,
|
||||
- Lba,
|
||||
- BufferSize,
|
||||
- FALSE // RequestIsWrite
|
||||
- );
|
||||
- if (EFI_ERROR (Status)) {
|
||||
- return Status;
|
||||
- }
|
||||
-
|
||||
- return SynchronousRequest (
|
||||
- Dev,
|
||||
+ return VirtioBlkReadWriteBlocks(
|
||||
+ This,
|
||||
+ MediaId,
|
||||
Lba,
|
||||
BufferSize,
|
||||
Buffer,
|
||||
- FALSE // RequestIsWrite
|
||||
+ FALSE // RequestIsRead
|
||||
);
|
||||
}
|
||||
|
||||
@@ -541,26 +588,9 @@ VirtioBlkWriteBlocks (
|
||||
IN VOID *Buffer
|
||||
)
|
||||
{
|
||||
- VBLK_DEV *Dev;
|
||||
- EFI_STATUS Status;
|
||||
-
|
||||
- if (BufferSize == 0) {
|
||||
- return EFI_SUCCESS;
|
||||
- }
|
||||
-
|
||||
- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
|
||||
- Status = VerifyReadWriteRequest (
|
||||
- &Dev->BlockIoMedia,
|
||||
- Lba,
|
||||
- BufferSize,
|
||||
- TRUE // RequestIsWrite
|
||||
- );
|
||||
- if (EFI_ERROR (Status)) {
|
||||
- return Status;
|
||||
- }
|
||||
-
|
||||
- return SynchronousRequest (
|
||||
- Dev,
|
||||
+ return VirtioBlkReadWriteBlocks(
|
||||
+ This,
|
||||
+ MediaId,
|
||||
Lba,
|
||||
BufferSize,
|
||||
Buffer,
|
||||
@@ -716,6 +746,8 @@ VirtioBlkInit (
|
||||
UINT8 NextDevStat;
|
||||
EFI_STATUS Status;
|
||||
|
||||
+ UINT32 MaxSegmentSize;
|
||||
+ UINT32 MaxSegments;
|
||||
UINT64 Features;
|
||||
UINT64 NumSectors;
|
||||
UINT32 BlockSize;
|
||||
@@ -814,6 +846,36 @@ VirtioBlkInit (
|
||||
BlockSize = 512;
|
||||
}
|
||||
|
||||
+ if (Features & VIRTIO_BLK_F_SIZE_MAX) {
|
||||
+ Status = VIRTIO_CFG_READ (Dev, SizeMax, &MaxSegmentSize);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ goto Failed;
|
||||
+ }
|
||||
+ if (MaxSegmentSize == 0) {
|
||||
+ //
|
||||
+ // We need at least one 4KB page.
|
||||
+ //
|
||||
+ MaxSegmentSize = SIZE_4KB;
|
||||
+ }
|
||||
+ } else {
|
||||
+ MaxSegmentSize = SIZE_512KB;
|
||||
+ }
|
||||
+
|
||||
+ if (Features & VIRTIO_BLK_F_SEG_MAX) {
|
||||
+ Status = VIRTIO_CFG_READ (Dev, SegMax, &MaxSegments);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ goto Failed;
|
||||
+ }
|
||||
+ if (MaxSegments == 0) {
|
||||
+ //
|
||||
+ // We need at least one SG element, whatever they say.
|
||||
+ //
|
||||
+ MaxSegments = 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ MaxSegments = DEFAULT_MAX_SEGMENTS;
|
||||
+ }
|
||||
+
|
||||
if (Features & VIRTIO_BLK_F_TOPOLOGY) {
|
||||
Status = VIRTIO_CFG_READ (
|
||||
Dev,
|
||||
@@ -955,6 +1017,8 @@ VirtioBlkInit (
|
||||
Dev->BlockIoMedia.ReadOnly = (BOOLEAN)((Features & VIRTIO_BLK_F_RO) != 0);
|
||||
Dev->BlockIoMedia.WriteCaching = (BOOLEAN)((Features & VIRTIO_BLK_F_FLUSH) != 0);
|
||||
Dev->BlockIoMedia.BlockSize = BlockSize;
|
||||
+ Dev->BlockIoMedia.MaxSegments = MaxSegments;
|
||||
+ Dev->BlockIoMedia.MaxSegmentSize = MaxSegmentSize;
|
||||
Dev->BlockIoMedia.IoAlign = 0;
|
||||
Dev->BlockIoMedia.LastBlock = DivU64x32 (
|
||||
NumSectors,
|
||||
@@ -968,6 +1032,8 @@ VirtioBlkInit (
|
||||
Dev->BlockIoMedia.BlockSize,
|
||||
Dev->BlockIoMedia.LastBlock + 1
|
||||
));
|
||||
+ DEBUG ((DEBUG_INFO, "%a: MaxSegments=0x%x[B] MaxSegmentSize=0x%x[B]\n",
|
||||
+ __FUNCTION__, Dev->BlockIoMedia.MaxSegments, Dev->BlockIoMedia.MaxSegmentSize));
|
||||
|
||||
if (Features & VIRTIO_BLK_F_TOPOLOGY) {
|
||||
Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
122
0080-Platform-Loongson-Remove-minimium-memory-size-limita.patch
Normal file
122
0080-Platform-Loongson-Remove-minimium-memory-size-limita.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From ff113b5d376dd9054aefc8452e7ff04459489a44 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Mon, 25 Mar 2024 10:50:28 +0800
|
||||
Subject: [PATCH 1/2] Platform/Loongson: Remove minimium memory size limitation
|
||||
|
||||
Temparory stack memory on PEI is hardcoded now, also minimium memory
|
||||
size 256M is hardcoded now. Here memory map table from fw cfg can be
|
||||
parsed. If there is memory map entry contains pei stack, it can be
|
||||
published as usable memory at PEI stage.
|
||||
|
||||
Cc: Bibo Mao <maobibo@loongson.cn>
|
||||
Cc: Chao Li <lichao@loongson.cn>
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Reviewed-by: Chao Li <lichao@loongson.cn>
|
||||
---
|
||||
.../Loongson/LoongArchQemuPkg/Loongson.dec | 2 -
|
||||
.../Loongson/LoongArchQemuPkg/Loongson.dsc | 6 ---
|
||||
.../LoongArchQemuPkg/PlatformPei/MemDetect.c | 38 ++++++++++++++++++-
|
||||
.../PlatformPei/PlatformPei.inf | 2 -
|
||||
4 files changed, 37 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec b/Platform/Loongson/LoongArchQemuPkg/Loongson.dec
|
||||
index e638b835e4..c2c6cc9596 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dec
|
||||
@@ -48,8 +48,6 @@
|
||||
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase|0|UINT64|0x0000000b
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize|0|UINT32|0x0000000c
|
||||
- gLoongArchQemuPkgTokenSpaceGuid.PcdUefiRamTop|0x0|UINT64|0x0000000d
|
||||
- gLoongArchQemuPkgTokenSpaceGuid.PcdRamRegionsBottom|0x0|UINT64|0x0000000e
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase|0x0|UINT64|0x0000000f
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize|0x0|UINT32|0x00000010
|
||||
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
|
||||
index 58aa16d3a9..aab2ca9b28 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
|
||||
@@ -356,12 +356,6 @@
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase | 0x10000
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize | 0x10000
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreeBase | 0x100000
|
||||
- #
|
||||
- # minimal memory for uefi bios should be 512M
|
||||
- # 0x00000000 - 0x10000000
|
||||
- # 0x90000000 - 0xA0000000
|
||||
- #
|
||||
- gLoongArchQemuPkgTokenSpaceGuid.PcdUefiRamTop | 0x10000000
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions | 0x06
|
||||
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile | { 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetect.c b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetect.c
|
||||
index 7e6a4a3aa9..7aa6fdc175 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetect.c
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetect.c
|
||||
@@ -40,12 +40,48 @@ PublishPeiMemory (
|
||||
UINT64 Base;
|
||||
UINT64 Size;
|
||||
UINT64 RamTop;
|
||||
+ FIRMWARE_CONFIG_ITEM FwCfgItem;
|
||||
+ UINTN FwCfgSize;
|
||||
+ UINTN Processed;
|
||||
+ LOONGARCH_MEMMAP_ENTRY MemoryMapEntry;
|
||||
|
||||
//
|
||||
// Determine the range of memory to use during PEI
|
||||
//
|
||||
Base = PcdGet64 (PcdSecPeiTempRamBase) + PcdGet32 (PcdSecPeiTempRamSize);
|
||||
- RamTop = PcdGet64 (PcdUefiRamTop);
|
||||
+ RamTop = 0;
|
||||
+
|
||||
+ Status = QemuFwCfgFindFile ("etc/memmap", &FwCfgItem, &FwCfgSize);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ if (FwCfgSize % sizeof MemoryMapEntry != 0) {
|
||||
+ return EFI_PROTOCOL_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ QemuFwCfgSelectItem (FwCfgItem);
|
||||
+ for (Processed = 0; Processed < FwCfgSize; Processed += sizeof MemoryMapEntry) {
|
||||
+ QemuFwCfgReadBytes (sizeof MemoryMapEntry, &MemoryMapEntry);
|
||||
+ if (MemoryMapEntry.Type != EfiAcpiAddressRangeMemory) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Find memory map entry where PEI temp stack is located
|
||||
+ */
|
||||
+ if ((MemoryMapEntry.BaseAddr <= Base) &&
|
||||
+ (Base < (MemoryMapEntry.BaseAddr + MemoryMapEntry.Length))) {
|
||||
+ RamTop = MemoryMapEntry.BaseAddr + MemoryMapEntry.Length;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (RamTop == 0) {
|
||||
+ DEBUG ((DEBUG_ERROR, "ERROR: No memory map entry contains temp stack \n"));
|
||||
+ ASSERT (FALSE);
|
||||
+ }
|
||||
+
|
||||
Size = RamTop - Base;
|
||||
|
||||
//
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf
|
||||
index 6cc3513b63..65591a4d7b 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf
|
||||
@@ -64,8 +64,6 @@
|
||||
[FixedPcd]
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvBase
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvSize
|
||||
- gLoongArchQemuPkgTokenSpaceGuid.PcdRamRegionsBottom
|
||||
- gLoongArchQemuPkgTokenSpaceGuid.PcdUefiRamTop
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase
|
||||
gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize
|
||||
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
|
||||
--
|
||||
2.46.0
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
From c9cb2611ae34a79c28671a703368e88267d6cc24 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaotian Wu <wuxiaotian@loongson.cn>
|
||||
Date: Tue, 19 Nov 2024 19:05:49 +0800
|
||||
Subject: [PATCH 2/2] Platform/Loongson: Modify loongarch uefi firmware size
|
||||
|
||||
After the loongarch flash block size is changed from 128K to 256K,
|
||||
qemu requires that the UEFI firmware size be aligned with the flash block size(256K).
|
||||
Otherwise, the firmware cannot be loaded,
|
||||
Use the following code to resolve the old firmware loading problem:
|
||||
mv QEMU_EFI.fd QEMU_EFI.fd-bak
|
||||
cat QEMU_EFI.fd-bak /dev/zero | head -c 16m > ./QEMU_EFI.fd
|
||||
mv QEMU_VARS.fd QEMU_VARS.fd-bak
|
||||
cat QEMU_VARS.fd-bak /dev/zero | head -c 16m > ./QEMU_VARS.fd
|
||||
|
||||
For the new firmware, we refer to other architecture UEFI and
|
||||
set the UEFI firmware size to align with the flash block size(256K).
|
||||
|
||||
So for this patch, we set the UEFI firmware size to 256K alignment.
|
||||
---
|
||||
Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc | 8 ++++----
|
||||
Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc | 4 ++--
|
||||
2 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc
|
||||
index e30c4629f7..c31909ca9a 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc
|
||||
@@ -18,12 +18,12 @@ DEFINE FD_SIZE = 0x400000
|
||||
#flash code layout
|
||||
#Set Sec base address and size in flash
|
||||
DEFINE SECFV_OFFSET = 0x00000000
|
||||
-DEFINE SECFV_SIZE = 0x00010000
|
||||
+DEFINE SECFV_SIZE = 0x00040000
|
||||
|
||||
#Set Pei base address and size in flash
|
||||
-DEFINE PEIFV_OFFSET = 0x00010000
|
||||
+DEFINE PEIFV_OFFSET = 0x00040000
|
||||
DEFINE PEIFV_SIZE = 0x00040000
|
||||
|
||||
#Set Dxe base address and size in flash
|
||||
-DEFINE DXEFV_OFFSET = 0x00050000
|
||||
-DEFINE DXEFV_SIZE = 0x00350000
|
||||
+DEFINE DXEFV_OFFSET = 0x00080000
|
||||
+DEFINE DXEFV_SIZE = 0x00380000
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc b/Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc
|
||||
index 83ce3d8008..f34901950d 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc
|
||||
@@ -10,8 +10,8 @@
|
||||
BaseAddress = 0x0
|
||||
Size = 0x1000000
|
||||
ErasePolarity = 1
|
||||
-BlockSize = 0x20000
|
||||
-NumBlocks = 128
|
||||
+BlockSize = 0x40000
|
||||
+NumBlocks = 64
|
||||
|
||||
0x00000000|0x00040000
|
||||
#NV_VARIABLE_STORE
|
||||
--
|
||||
2.46.0
|
||||
|
||||
40
0082-fixup-fdt-parse-error.patch
Normal file
40
0082-fixup-fdt-parse-error.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From bdbeb6e653d7bbaa5eb4ad104119abfc7030c285 Mon Sep 17 00:00:00 2001
|
||||
From: Xianglai Li <lixianglai@loongson.cn>
|
||||
Date: Mon, 25 Nov 2024 16:16:39 +0800
|
||||
Subject: [PATCH] fixup fdt parse error
|
||||
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
.../Library/SerialPortLib/EarlySerialPortLib16550.c | 2 +-
|
||||
Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/EarlySerialPortLib16550.c b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/EarlySerialPortLib16550.c
|
||||
index c713c6e9..dd64a000 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/EarlySerialPortLib16550.c
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/EarlySerialPortLib16550.c
|
||||
@@ -155,7 +155,7 @@ GetSerialConsolePortAddress (
|
||||
}
|
||||
|
||||
// Determine the actual path length, as a colon terminates the path.
|
||||
- Path = ScanMem8 (Prop, ':', PropSize);
|
||||
+ Path = ScanMem8 (Prop, PropSize, (UINT8)":");
|
||||
if (Path == NULL) {
|
||||
PathLen = AsciiStrLen (Prop);
|
||||
} else {
|
||||
diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c
|
||||
index 84bb8e8a..02982cd0 100644
|
||||
--- a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c
|
||||
+++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c
|
||||
@@ -193,7 +193,7 @@ GetSerialConsolePortAddress (
|
||||
}
|
||||
|
||||
// Determine the actual path length, as a colon terminates the path.
|
||||
- Path = ScanMem8 (Prop, ':', PropSize);
|
||||
+ Path = ScanMem8 (Prop, PropSize, (UINT8)":");
|
||||
if (Path == NULL) {
|
||||
PathLen = AsciiStrLen (Prop);
|
||||
} else {
|
||||
--
|
||||
2.41.0
|
||||
|
||||
65
edk2.spec
65
edk2.spec
@ -7,7 +7,7 @@
|
||||
|
||||
Name: edk2
|
||||
Version: %{stable_date}
|
||||
Release: 11
|
||||
Release: 17
|
||||
Summary: EFI Development Kit II
|
||||
License: BSD-2-Clause-Patent and OpenSSL and MIT
|
||||
URL: https://github.com/tianocore/edk2
|
||||
@ -90,6 +90,48 @@ patch52: 0052-Revert-LoongArchQemuPkg-auto-gen-fix-SEC-ProcessLibr.patch
|
||||
# Fix edk2 build errror with gcc-14
|
||||
patch53: 0053-relax_edk2_gcc14.patch
|
||||
|
||||
# Fix CVE-2024-38796
|
||||
patch54: 0054-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch
|
||||
|
||||
# Fix CVE-2023-45236、CVE-2023-45237
|
||||
patch55: 0055-NetworkPkg-SECURITY-PATCH-CVE-2023-45237.patch
|
||||
patch56: 0056-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236.patch
|
||||
|
||||
# Support Hygon CSV3
|
||||
patch57: 0057-MdePkg-Add-StandardSignatureIsHygonGenuine-in-BaseCp.patch
|
||||
patch58: 0058-UefiCpuPkg-LocalApicLib-Exclude-second-SendIpi-seque.patch
|
||||
patch59: 0059-OvmfPkg-Add-CSV-secure-call-library-on-Hygon-CPU.patch
|
||||
patch60: 0060-OvmfPkg-ResetVector-Support-CSV-in-ResetVector-phase.patch
|
||||
patch61: 0061-OvmfPkg-PlatformPei-Initialize-CSV-VM-s-memory.patch
|
||||
patch62: 0062-OvmfPkg-BaseMemcryptSevLib-update-page-status-to-Sec.patch
|
||||
patch63: 0063-OvmfPkg-Tcg-Add-CsvLib-for-TpmMmioSevDecryptPei.patch
|
||||
patch64: 0064-OvmfPkg-Add-CsvDxe-driver.patch
|
||||
patch65: 0065-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch
|
||||
patch66: 0066-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-guest.patch
|
||||
patch67: 0067-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch
|
||||
|
||||
# Support live migrate Hygon CSV/CSV2/CSV3 guest
|
||||
patch68: 0068-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch
|
||||
patch69: 0069-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch
|
||||
patch70: 0070-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch
|
||||
patch71: 0071-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch
|
||||
patch72: 0072-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch
|
||||
patch73: 0073-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch
|
||||
patch74: 0074-OvmfPkg-BaseMemcryptSevLib-Correct-the-calculation-o.patch
|
||||
patch75: 0075-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-not-supp.patch
|
||||
# Fix nesting #VC in mmio check
|
||||
patch76: 0076-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt-status.patch
|
||||
|
||||
# Support vdpa blk/scsi device boot
|
||||
patch77: 0077-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch
|
||||
patch78: 0078-Virtio-wait-virtio-device-reset-done.patch
|
||||
patch79: 0079-VirtioBlk-split-large-IO-according-to-segment_size_m.patch
|
||||
|
||||
# Support Loongarch firmware size
|
||||
patch80: 0080-Platform-Loongson-Remove-minimium-memory-size-limita.patch
|
||||
patch81: 0081-Platform-Loongson-Modify-loongarch-uefi-firmware-siz.patch
|
||||
patch82: 0082-fixup-fdt-parse-error.patch
|
||||
|
||||
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl
|
||||
|
||||
%description
|
||||
@ -359,6 +401,27 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Dec 17 2024 Xiaotian Wu <wuxiaotian@loongson.cn> - 202308-17
|
||||
- Update LoongArch virtual machine
|
||||
- 0080-Platform-Loongson-Remove-minimium-memory-size-limita.patch
|
||||
- 0081-Platform-Loongson-Modify-loongarch-uefi-firmware-siz.patch
|
||||
- 0082-fixup-fdt-parse-error.patch
|
||||
|
||||
* Fri Nov 29 2024 adttil<2429917001@qq.com> - 202308-16
|
||||
- vdpa: support vdpa blk/scsi device boot
|
||||
|
||||
* Wed Oct 23 2024 hanliyang<hanliyang@hygon.cn> - 202308-15
|
||||
- Add support for live migration of Hygon CSV1/2/3 guests, fix nesting #VC
|
||||
|
||||
* Tue Nov 12 2024 hanliyang<hanliyang@hygon.cn> - 202308-14
|
||||
- Add support for running in Hygon CSV3 guest
|
||||
|
||||
* Mon Oct 14 2024 shenyage<shenyage1@huawei.com> - 202308-13
|
||||
- fix CVE-2023-45236、CVE-2023-45237
|
||||
|
||||
* Wed Oct 09 2024 zhangxianting <zhangxianting@uniontech.com> - 202308-12
|
||||
- fix CVE-2024-38796
|
||||
|
||||
* Fri Sep 13 2024 Xiaotian Wu <wuxiaotian@loongson.cn> - 202308-11
|
||||
- add LoongArch support
|
||||
- backport edk2-platform to build with edk2-2308
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user