* [edk2-devel] [PATCH 1/7] OvmfPkg: add IndustryStandard/QemuUefiVars.h
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
@ 2023-11-23 15:02 ` Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 2/7] OvmfPkg: add new VirtMmCommunicationDxe driver Gerd Hoffmann
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2023-11-23 15:02 UTC (permalink / raw)
To: devel; +Cc: Oliver Steffen, László Érsek, Gerd Hoffmann
Add header file for the qemu uefi variable service device.
This defines the registers of the device, the location
in io address space (x86) and the device tree name (arm).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
.../Include/IndustryStandard/QemuUefiVars.h | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 OvmfPkg/Include/IndustryStandard/QemuUefiVars.h
diff --git a/OvmfPkg/Include/IndustryStandard/QemuUefiVars.h b/OvmfPkg/Include/IndustryStandard/QemuUefiVars.h
new file mode 100644
index 000000000000..64ca5628ca58
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/QemuUefiVars.h
@@ -0,0 +1,41 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ * uefi-vars device - API of the virtual device for guest/host communication.
+ *
+ * copied from qemu.git (include/hw/uefi/var-service-api.h)
+ */
+
+#ifndef QEMU_UEFI_VAR_SERVICE_API_H
+#define QEMU_UEFI_VAR_SERVICE_API_H
+
+/* isa: io range */
+#define UEFI_VARS_IO_BASE 0x520
+
+/* sysbus: fdt node path */
+#define UEFI_VARS_FDT_NODE "qemu-uefi-vars"
+#define UEFI_VARS_FDT_COMPAT "qemu,uefi-vars"
+
+/* registers */
+#define UEFI_VARS_REG_MAGIC 0x00 /* 16 bit */
+#define UEFI_VARS_REG_CMD_STS 0x02 /* 16 bit */
+#define UEFI_VARS_REG_BUFFER_SIZE 0x04 /* 32 bit */
+#define UEFI_VARS_REG_BUFFER_ADDR_LO 0x08 /* 32 bit */
+#define UEFI_VARS_REG_BUFFER_ADDR_HI 0x0c /* 32 bit */
+#define UEFI_VARS_REGS_SIZE 0x10
+
+/* magic value */
+#define UEFI_VARS_MAGIC_VALUE 0xef1
+
+/* command values */
+#define UEFI_VARS_CMD_RESET 0x01
+#define UEFI_VARS_CMD_MM 0x02
+
+/* status values */
+#define UEFI_VARS_STS_SUCCESS 0x00
+#define UEFI_VARS_STS_BUSY 0x01
+#define UEFI_VARS_STS_ERR_UNKNOWN 0x10
+#define UEFI_VARS_STS_ERR_NOT_SUPPORTED 0x11
+#define UEFI_VARS_STS_ERR_BAD_BUFFER_SIZE 0x12
+
+#endif /* QEMU_UEFI_VAR_SERVICE_API_H */
--
2.42.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111677): https://edk2.groups.io/g/devel/message/111677
Mute This Topic: https://groups.io/mt/102767934/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [edk2-devel] [PATCH 2/7] OvmfPkg: add new VirtMmCommunicationDxe driver
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 1/7] OvmfPkg: add IndustryStandard/QemuUefiVars.h Gerd Hoffmann
@ 2023-11-23 15:02 ` Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 3/7] OvmfPkg/OvmfPkgX64: add QEMU_VARS option Gerd Hoffmann
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2023-11-23 15:02 UTC (permalink / raw)
To: devel; +Cc: Oliver Steffen, László Érsek, Gerd Hoffmann
EFI driver implementing the MmCommunication2Protocol,
but instead of trapping to MM mode (SMM on x86, el3 on arm)
trap to the host, using a virtual device.
Moving the efi variable management to the host allows to have
persistent efi variables without flash storage, and it also
allows to have secure boot support without requiring MM mode
to protect variable storage in flash.
This patch brings the core code, and the x64 bits
which talk to 'qemu -device uefi-vars-isa'.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
.../VirtMmCommunication.inf | 50 +++
.../VirtMmCommunication.h | 37 ++
OvmfPkg/VirtMmCommunicationDxe/QemuX64.c | 106 +++++
.../VirtMmCommunication.c | 380 ++++++++++++++++++
4 files changed, 573 insertions(+)
create mode 100644 OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
create mode 100644 OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.h
create mode 100644 OvmfPkg/VirtMmCommunicationDxe/QemuX64.c
create mode 100644 OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c
diff --git a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
new file mode 100644
index 000000000000..a9998f3db8cd
--- /dev/null
+++ b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
@@ -0,0 +1,50 @@
+#/** @file
+#
+# Virt MM Communicate driver
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = VirtMmCommunication
+ FILE_GUID = 0B807404-2D1C-4066-95F4-F28A58800185
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = VirtMmCommunication2Initialize
+
+[Sources]
+ VirtMmCommunication.c
+
+[Sources.X64]
+ QemuX64.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DxeServicesTableLib
+ HobLib
+ MemoryAllocationLib
+ UefiDriverEntryPoint
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES
+
+[Protocols]
+ gEfiMmCommunication2ProtocolGuid ## PRODUCES
+ gEfiSmmVariableProtocolGuid ## PRODUCES
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+ gEfiEventExitBootServicesGuid
+ gEfiEventReadyToBootGuid
+ gSmmVariableWriteGuid
+
+[Depex]
+ gEfiCpuArchProtocolGuid
diff --git a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.h b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.h
new file mode 100644
index 000000000000..32f9d16c42e3
--- /dev/null
+++ b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.h
@@ -0,0 +1,37 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _VIRT_MM_COMM_DXE_H_
+#define _VIRT_MM_COMM_DXE_H_
+
+/* communication buffer */
+
+#define MAX_BUFFER_SIZE (64 * 1024)
+
+extern VOID *mCommunicateBuffer;
+extern EFI_PHYSICAL_ADDRESS mCommunicateBufferPhys;
+
+/* arch specific hooks */
+
+EFI_STATUS
+EFIAPI
+VirtMmHwInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+VirtMmHwComm (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+VirtMmHwVirtMap (
+ VOID
+ );
+
+#endif /* _VIRT_MM_COMM_DXE_H_ */
diff --git a/OvmfPkg/VirtMmCommunicationDxe/QemuX64.c b/OvmfPkg/VirtMmCommunicationDxe/QemuX64.c
new file mode 100644
index 000000000000..6470cfc7f73b
--- /dev/null
+++ b/OvmfPkg/VirtMmCommunicationDxe/QemuX64.c
@@ -0,0 +1,106 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/QemuUefiVars.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+#include "VirtMmCommunication.h"
+
+STATIC
+EFI_STATUS
+EFIAPI
+VirtMmHwCommand (
+ UINT32 Cmd
+ )
+{
+ UINT32 Count;
+ UINT32 Sts;
+
+ IoWrite16 (UEFI_VARS_IO_BASE + UEFI_VARS_REG_CMD_STS, Cmd);
+ for (Count = 0; Count < 100; Count++) {
+ Sts = IoRead16 (UEFI_VARS_IO_BASE + UEFI_VARS_REG_CMD_STS);
+ DEBUG ((DEBUG_VERBOSE, "%a: Sts: 0x%x\n", __func__, Sts));
+ switch (Sts) {
+ case UEFI_VARS_STS_SUCCESS:
+ return RETURN_SUCCESS;
+ case UEFI_VARS_STS_BUSY:
+ CpuPause ();
+ break;
+ case UEFI_VARS_STS_ERR_NOT_SUPPORTED:
+ return RETURN_UNSUPPORTED;
+ case UEFI_VARS_STS_ERR_BAD_BUFFER_SIZE:
+ return RETURN_BAD_BUFFER_SIZE;
+ default:
+ return RETURN_DEVICE_ERROR;
+ }
+ }
+
+ return RETURN_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+VirtMmHwInit (
+ VOID
+ )
+{
+ UINT32 Magic, AddrLo, AddrHi;
+ EFI_STATUS Status;
+
+ Magic = IoRead16 (UEFI_VARS_IO_BASE + UEFI_VARS_REG_MAGIC);
+ if (Magic != UEFI_VARS_MAGIC_VALUE) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Magic value mismatch (0x%x != 0x%x)\n",
+ __func__,
+ Magic,
+ UEFI_VARS_MAGIC_VALUE
+ ));
+ return RETURN_DEVICE_ERROR;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: Magic 0x%x, good\n", __func__, Magic));
+
+ Status = VirtMmHwCommand (UEFI_VARS_CMD_RESET);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Reset failed: %d\n", __func__, Status));
+ return Status;
+ }
+
+ AddrLo = (UINT32)mCommunicateBufferPhys;
+ AddrHi = (UINT32)RShiftU64 (mCommunicateBufferPhys, 32);
+ IoWrite32 (UEFI_VARS_IO_BASE + UEFI_VARS_REG_BUFFER_ADDR_LO, AddrLo);
+ IoWrite32 (UEFI_VARS_IO_BASE + UEFI_VARS_REG_BUFFER_ADDR_HI, AddrHi);
+ IoWrite32 (UEFI_VARS_IO_BASE + UEFI_VARS_REG_BUFFER_SIZE, MAX_BUFFER_SIZE);
+
+ return RETURN_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VirtMmHwVirtMap (
+ VOID
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VirtMmHwComm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = VirtMmHwCommand (UEFI_VARS_CMD_MM);
+ DEBUG ((DEBUG_VERBOSE, "%a: Status: %r\n", __func__, Status));
+
+ return Status;
+}
diff --git a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c
new file mode 100644
index 000000000000..7b4ebe1257c6
--- /dev/null
+++ b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c
@@ -0,0 +1,380 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Protocol/MmCommunication2.h>
+
+#include "VirtMmCommunication.h"
+
+VOID *mCommunicateBuffer;
+EFI_PHYSICAL_ADDRESS mCommunicateBufferPhys;
+
+// Notification event when virtual address map is set.
+STATIC EFI_EVENT mSetVirtualAddressMapEvent;
+
+// Handle to install the MM Communication Protocol
+STATIC EFI_HANDLE mMmCommunicateHandle;
+
+// Handle to install the EfiSmmVariableProtocol
+STATIC EFI_HANDLE mSmmVariableHandle;
+
+// Handle to install the SmmVariableWrite
+STATIC EFI_HANDLE mSmmVariableWriteHandle;
+
+/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer
+ @param[in, out] CommSize The size of the data buffer being passed in. On input,
+ when not omitted, the buffer should cover EFI_MM_COMMUNICATE_HEADER
+ and the value of MessageLength field. On exit, the size
+ of data being returned. Zero if the handler does not
+ wish to reply with any data. This parameter is optional
+ and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER CommBufferPhysical or CommBufferVirtual was NULL, or
+ integer value pointed by CommSize does not cover
+ EFI_MM_COMMUNICATE_HEADER and the value of MessageLength
+ field.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+VirtMmCommunication2Communicate (
+ IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual,
+ IN OUT UINTN *CommSize OPTIONAL
+ )
+{
+ EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+ EFI_STATUS Status;
+ UINTN BufferSize;
+
+ //
+ // Check parameters
+ //
+ if ((CommBufferVirtual == NULL) || (CommBufferPhysical == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_SUCCESS;
+ CommunicateHeader = CommBufferVirtual;
+ // CommBuffer is a mandatory parameter. Hence, Rely on
+ // MessageLength + Header to ascertain the
+ // total size of the communication payload rather than
+ // rely on optional CommSize parameter
+ BufferSize = CommunicateHeader->MessageLength +
+ sizeof (CommunicateHeader->HeaderGuid) +
+ sizeof (CommunicateHeader->MessageLength);
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: %g msglen %ld, BufferSize %ld, CommSize %ld\n",
+ __func__,
+ &CommunicateHeader->HeaderGuid,
+ CommunicateHeader->MessageLength,
+ BufferSize,
+ *CommSize
+ ));
+
+ // If CommSize is not omitted, perform size inspection before proceeding.
+ if (CommSize != NULL) {
+ // This case can be used by the consumer of this driver to find out the
+ // max size that can be used for allocating CommBuffer.
+ if ((*CommSize == 0) ||
+ (*CommSize > MAX_BUFFER_SIZE))
+ {
+ *CommSize = MAX_BUFFER_SIZE;
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
+ // CommSize should cover at least MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
+ //
+ if (*CommSize < BufferSize) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // If the message length is 0 or greater than what can be tolerated by the MM
+ // environment then return the expected size.
+ //
+ if ((CommunicateHeader->MessageLength == 0) ||
+ (BufferSize > MAX_BUFFER_SIZE))
+ {
+ CommunicateHeader->MessageLength = MAX_BUFFER_SIZE -
+ sizeof (CommunicateHeader->HeaderGuid) -
+ sizeof (CommunicateHeader->MessageLength);
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+
+ // MessageLength or CommSize check has failed, return here.
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a: check error: %r\n", __func__, Status));
+ return Status;
+ }
+
+ // Copy Communication Payload
+ CopyMem (mCommunicateBuffer, CommBufferVirtual, BufferSize);
+
+ Status = VirtMmHwComm ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a: comm error: %r\n", __func__, Status));
+ return Status;
+ }
+
+ CopyMem (CommBufferVirtual, mCommunicateBuffer, BufferSize);
+
+ DEBUG ((DEBUG_VERBOSE, "%a: success (%d)\n", __func__, BufferSize));
+ return EFI_SUCCESS;
+}
+
+//
+// MM Communication Protocol instance
+//
+STATIC EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
+ VirtMmCommunication2Communicate
+};
+
+/**
+ Notification callback on SetVirtualAddressMap event.
+
+ This function notifies the MM communication protocol interface on
+ SetVirtualAddressMap event and converts pointers used in this driver
+ from physical to virtual address.
+
+ @param Event SetVirtualAddressMap event.
+ @param Context A context when the SetVirtualAddressMap triggered.
+
+ @retval EFI_SUCCESS The function executed successfully.
+ @retval Other Some error occurred when executing this function.
+
+**/
+STATIC
+VOID
+EFIAPI
+VirtMmNotifySetVirtualAddressMap (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: << %p\n", __func__, mCommunicateBuffer));
+ Status = gRT->ConvertPointer (EFI_OPTIONAL_PTR, &mCommunicateBuffer);
+ DEBUG ((DEBUG_VERBOSE, "%a: >> %p\n", __func__, mCommunicateBuffer));
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Unable to convert MM runtime pointer. Status: %r\n",
+ __func__,
+ Status
+ ));
+ }
+
+ Status = VirtMmHwVirtMap ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: VirtMmHwVirtMap failed. Status: %r\n",
+ __func__,
+ Status
+ ));
+ }
+}
+
+STATIC EFI_GUID *CONST mGuidedEventGuid[] = {
+ &gEfiEndOfDxeEventGroupGuid,
+ &gEfiEventExitBootServicesGuid,
+ &gEfiEventReadyToBootGuid,
+};
+
+STATIC EFI_EVENT mGuidedEvent[ARRAY_SIZE (mGuidedEventGuid)];
+
+/**
+ Event notification that is fired when GUIDed Event Group is signaled.
+
+ @param Event The Event that is being processed, not used.
+ @param Context Event Context, not used.
+
+**/
+STATIC
+VOID
+EFIAPI
+VirtMmGuidedEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_MM_COMMUNICATE_HEADER Header;
+ UINTN Size;
+
+ //
+ // Use Guid to initialize EFI_SMM_COMMUNICATE_HEADER structure
+ //
+ CopyGuid (&Header.HeaderGuid, Context);
+ Header.MessageLength = 1;
+ Header.Data[0] = 0;
+
+ Size = sizeof (Header);
+ VirtMmCommunication2Communicate (&mMmCommunication2, &Header, &Header, &Size);
+}
+
+/**
+ The Entry Point for MM Communication
+
+ This function installs the MM communication protocol interface and finds out
+ what type of buffer management will be required prior to invoking the
+ communication SMC.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Other Some error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+VirtMmCommunication2Initialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+
+ if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) {
+ ASSERT (!"Variable driver runtime cache is not supported.\n");
+ CpuDeadLoop ();
+ }
+
+ if (FeaturePcdGet (PcdVariableCollectStatistics)) {
+ ASSERT (!"Variable driver statistics are not supported.\n");
+ CpuDeadLoop ();
+ }
+
+ mCommunicateBuffer = AllocateRuntimePages (EFI_SIZE_TO_PAGES (MAX_BUFFER_SIZE));
+ if (!mCommunicateBuffer) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ReturnErrorStatus;
+ }
+
+ mCommunicateBufferPhys = (EFI_PHYSICAL_ADDRESS)(UINTN)(mCommunicateBuffer);
+ Status = VirtMmHwInit ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Failed to init HW: %r\n",
+ __func__,
+ Status
+ ));
+ goto FreeBufferPages;
+ }
+
+ // Install the communication protocol
+ Status = gBS->InstallProtocolInterface (
+ &mMmCommunicateHandle,
+ &gEfiMmCommunication2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mMmCommunication2
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Failed to install MM communication protocol\n",
+ __func__
+ ));
+ goto FreeBufferPages;
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &mSmmVariableHandle,
+ &gEfiSmmVariableProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallProtocolInterface (
+ &mSmmVariableWriteHandle,
+ &gSmmVariableWriteGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Register notification callback when virtual address is associated
+ // with the physical address.
+ // Create a Set Virtual Address Map event.
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+ TPL_NOTIFY,
+ VirtMmNotifySetVirtualAddressMap,
+ NULL,
+ &mSetVirtualAddressMapEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ for (Index = 0; Index < ARRAY_SIZE (mGuidedEventGuid); Index++) {
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ VirtMmGuidedEventNotify,
+ mGuidedEventGuid[Index],
+ mGuidedEventGuid[Index],
+ &mGuidedEvent[Index]
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ while (Index-- > 0) {
+ gBS->CloseEvent (mGuidedEvent[Index]);
+ }
+
+ goto UninstallProtocol;
+ }
+ }
+
+ return EFI_SUCCESS;
+
+UninstallProtocol:
+ gBS->UninstallProtocolInterface (
+ mMmCommunicateHandle,
+ &gEfiMmCommunication2ProtocolGuid,
+ &mMmCommunication2
+ );
+
+FreeBufferPages:
+ FreePages (mCommunicateBuffer, EFI_SIZE_TO_PAGES (MAX_BUFFER_SIZE));
+
+ReturnErrorStatus:
+ return EFI_INVALID_PARAMETER;
+}
--
2.42.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111679): https://edk2.groups.io/g/devel/message/111679
Mute This Topic: https://groups.io/mt/102767936/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [edk2-devel] [PATCH 3/7] OvmfPkg/OvmfPkgX64: add QEMU_VARS option
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 1/7] OvmfPkg: add IndustryStandard/QemuUefiVars.h Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 2/7] OvmfPkg: add new VirtMmCommunicationDxe driver Gerd Hoffmann
@ 2023-11-23 15:02 ` Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 4/7] OvmfPkg: add PcdQemuVarsRequire Gerd Hoffmann
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2023-11-23 15:02 UTC (permalink / raw)
To: devel; +Cc: Oliver Steffen, László Érsek, Gerd Hoffmann
Add config option to use qemu variable service,
via VirtMmCommunicationDxe. Default is FALSE,
build using '-D QEMU_VARS=TRUE' to enable.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
OvmfPkg/OvmfPkgX64.dsc | 15 ++++++++++++++-
OvmfPkg/OvmfPkgX64.fdf | 12 +++++++++++-
.../VirtMmCommunication.inf | 1 +
3 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index dc1a0942aa8b..4b044321e31b 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -378,7 +378,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
-!if $(SMM_REQUIRE) == TRUE
+!if $(SMM_REQUIRE) == TRUE || $(QEMU_VARS) == TRUE
MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
!endif
@@ -504,6 +504,9 @@ [PcdsFeatureFlag]
gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE
!endif
+!if $(QEMU_VARS) == TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE
+!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootSupported|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdRequireSelfSignedPk|TRUE
@@ -1095,6 +1098,15 @@ [Components]
}
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+!else
+!if $(QEMU_VARS) == TRUE
+
+ #
+ # Variable driver stack (qemu -device uefi-vars)
+ #
+ OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+
!else
#
@@ -1110,6 +1122,7 @@ [Components]
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
}
+!endif
!endif
#
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 9c35b6e848a2..20cc6a49c72f 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -223,7 +223,7 @@ [FV.DXEFV]
# encrypted region (Since the range has not been marked shared/unencrypted).
INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf
INF OvmfPkg/TdxDxe/TdxDxe.inf
-!if $(SMM_REQUIRE) == FALSE
+!if $(SMM_REQUIRE) == FALSE && $(QEMU_VARS) == FALSE
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
!endif
}
@@ -392,6 +392,15 @@ [FV.DXEFV]
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+!else
+!if $(QEMU_VARS) == TRUE
+
+ #
+ # Variable driver stack (qemu -device uefi-vars)
+ #
+INF OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+
!else
#
@@ -402,6 +411,7 @@ [FV.DXEFV]
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
!endif
+!endif
#
# EFI_CC_MEASUREMENT_PROTOCOL
diff --git a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
index a9998f3db8cd..1403e92e1d6d 100644
--- a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+++ b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
@@ -23,6 +23,7 @@ [Sources.X64]
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseMemoryLib
--
2.42.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111678): https://edk2.groups.io/g/devel/message/111678
Mute This Topic: https://groups.io/mt/102767935/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [edk2-devel] [PATCH 4/7] OvmfPkg: add PcdQemuVarsRequire
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
` (2 preceding siblings ...)
2023-11-23 15:02 ` [edk2-devel] [PATCH 3/7] OvmfPkg/OvmfPkgX64: add QEMU_VARS option Gerd Hoffmann
@ 2023-11-23 15:02 ` Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 5/7] OvmfPkg/VirtMmCommunicationDxe: stop on init failure Gerd Hoffmann
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2023-11-23 15:02 UTC (permalink / raw)
To: devel; +Cc: Oliver Steffen, László Érsek, Gerd Hoffmann
Add PcdQemuVarsRequire FeaturePcd, so firmware code can figure whenever
the given build is supposed to use the qemu uefi variable service.
Skip the emulated variable store setup in case PcdQemuVarsRequire is
true. This is needed to make secure boot work.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
OvmfPkg/OvmfPkg.dec | 3 +++
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/PlatformPei/PlatformPei.inf | 1 +
OvmfPkg/PlatformPei/Platform.c | 4 ++++
4 files changed, 9 insertions(+)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index e3861e5c1b39..7fa7ee5e99e3 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -502,3 +502,6 @@ [PcdsFeatureFlag]
# firmware contains a CSM (Compatibility Support Module).
#
gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable|FALSE|BOOLEAN|0x35
+
+ ## This feature flag indicates the firmware build needs the qemu variable service.
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuVarsRequire|FALSE|BOOLEAN|0x6e
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 4b044321e31b..a27ea95dedc5 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -505,6 +505,7 @@ [PcdsFeatureFlag]
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE
!endif
!if $(QEMU_VARS) == TRUE
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuVarsRequire|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE
!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 3934aeed9514..0794e605ef4c 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -135,6 +135,7 @@ [FixedPcd]
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable
gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuVarsRequire
[Ppis]
gEfiPeiMasterBootModePpiGuid
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index f5dc41c3a8c4..31922a91fbfd 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -219,6 +219,10 @@ ReserveEmuVariableNvStore (
EFI_PHYSICAL_ADDRESS VariableStore;
RETURN_STATUS PcdStatus;
+ if (FeaturePcdGet (PcdQemuVarsRequire)) {
+ return;
+ }
+
VariableStore = (EFI_PHYSICAL_ADDRESS)(UINTN)PlatformReserveEmuVariableNvStore ();
PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
--
2.42.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111683): https://edk2.groups.io/g/devel/message/111683
Mute This Topic: https://groups.io/mt/102767941/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [edk2-devel] [PATCH 5/7] OvmfPkg/VirtMmCommunicationDxe: stop on init failure
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
` (3 preceding siblings ...)
2023-11-23 15:02 ` [edk2-devel] [PATCH 4/7] OvmfPkg: add PcdQemuVarsRequire Gerd Hoffmann
@ 2023-11-23 15:02 ` Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 6/7] OvmfPkg/VirtMmCommunicationDxe: add arm support Gerd Hoffmann
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2023-11-23 15:02 UTC (permalink / raw)
To: devel; +Cc: Oliver Steffen, László Érsek, Gerd Hoffmann
Print an error and stop in case VirtMmCommunicationDxe
initialization fails.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf | 1 +
OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
index 1403e92e1d6d..08fadefa5275 100644
--- a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+++ b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
@@ -36,6 +36,7 @@ [LibraryClasses]
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuVarsRequire ## CONSUMES
[Protocols]
gEfiMmCommunication2ProtocolGuid ## PRODUCES
diff --git a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c
index 7b4ebe1257c6..c33561b39f9b 100644
--- a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c
+++ b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c
@@ -376,5 +376,15 @@ VirtMmCommunication2Initialize (
FreePages (mCommunicateBuffer, EFI_SIZE_TO_PAGES (MAX_BUFFER_SIZE));
ReturnErrorStatus:
+ if (FeaturePcdGet (PcdQemuVarsRequire)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: qemu uefi variable service is not available, use \n"
+ " 'qemu-system-x86_64 -device uefi-vars-isa' or\n"
+ " 'qemu-system-aarch64 -machine virt,x-uefi-vars=on'\n"
+ ));
+ CpuDeadLoop ();
+ }
+
return EFI_INVALID_PARAMETER;
}
--
2.42.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111680): https://edk2.groups.io/g/devel/message/111680
Mute This Topic: https://groups.io/mt/102767937/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [edk2-devel] [PATCH 6/7] OvmfPkg/VirtMmCommunicationDxe: add arm support
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
` (4 preceding siblings ...)
2023-11-23 15:02 ` [edk2-devel] [PATCH 5/7] OvmfPkg/VirtMmCommunicationDxe: stop on init failure Gerd Hoffmann
@ 2023-11-23 15:02 ` Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 7/7] ArmVirtPkg/ArmVirtQemu: add QEMU_VARS option Gerd Hoffmann
2023-11-28 8:33 ` [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Ard Biesheuvel
7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2023-11-23 15:02 UTC (permalink / raw)
To: devel; +Cc: Oliver Steffen, László Érsek, Gerd Hoffmann
Add support for arm. Lookup the "qemu-uefi-vars" device in the device
tree, talk to it via mmio, otherwise identical to the x64 variant.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
.../VirtMmCommunication.inf | 15 ++
OvmfPkg/VirtMmCommunicationDxe/QemuFdt.c | 208 ++++++++++++++++++
2 files changed, 223 insertions(+)
create mode 100644 OvmfPkg/VirtMmCommunicationDxe/QemuFdt.c
diff --git a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
index 08fadefa5275..48184207d909 100644
--- a/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+++ b/OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
@@ -20,11 +20,17 @@ [Sources]
[Sources.X64]
QemuX64.c
+[Sources.AARCH64, Sources.ARM]
+ QemuFdt.c
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
+[Packages.AARCH64, Packages.ARM]
+ EmbeddedPkg/EmbeddedPkg.dec
+
[LibraryClasses]
BaseMemoryLib
DebugLib
@@ -33,6 +39,9 @@ [LibraryClasses]
MemoryAllocationLib
UefiDriverEntryPoint
+[LibraryClasses.AARCH64, LibraryClasses.ARM]
+ FdtLib
+
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES
@@ -42,6 +51,9 @@ [Protocols]
gEfiMmCommunication2ProtocolGuid ## PRODUCES
gEfiSmmVariableProtocolGuid ## PRODUCES
+[Protocols.AARCH64, Protocols.ARM]
+ gFdtClientProtocolGuid
+
[Guids]
gEfiEndOfDxeEventGroupGuid
gEfiEventExitBootServicesGuid
@@ -50,3 +62,6 @@ [Guids]
[Depex]
gEfiCpuArchProtocolGuid
+
+[Depex.AARCH64, Depex.ARM]
+ gFdtClientProtocolGuid
diff --git a/OvmfPkg/VirtMmCommunicationDxe/QemuFdt.c b/OvmfPkg/VirtMmCommunicationDxe/QemuFdt.c
new file mode 100644
index 000000000000..ae42d9671bea
--- /dev/null
+++ b/OvmfPkg/VirtMmCommunicationDxe/QemuFdt.c
@@ -0,0 +1,208 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/QemuUefiVars.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Protocol/FdtClient.h>
+
+#include "VirtMmCommunication.h"
+
+STATIC UINT64 mUefiVarsAddr;
+
+STATIC
+EFI_STATUS
+EFIAPI
+VirtMmHwFind (
+ VOID
+ )
+{
+ FDT_CLIENT_PROTOCOL *FdtClient;
+ EFI_STATUS Status;
+ CONST UINT64 *Reg;
+ UINT32 RegSize;
+ UINTN AddressCells, SizeCells;
+
+ Status = gBS->LocateProtocol (
+ &gFdtClientProtocolGuid,
+ NULL,
+ (VOID **)&FdtClient
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtClient->FindCompatibleNodeReg (
+ FdtClient,
+ UEFI_VARS_FDT_COMPAT,
+ (CONST VOID **)&Reg,
+ &AddressCells,
+ &SizeCells,
+ &RegSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: node compatible=%a not found (%r)\n",
+ __func__,
+ UEFI_VARS_FDT_NODE,
+ Status
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ ASSERT (AddressCells == 2);
+ ASSERT (SizeCells == 2);
+ ASSERT (RegSize == 2 * sizeof (UINT64));
+
+ mUefiVarsAddr = SwapBytes64 (Reg[0]);
+ DEBUG ((DEBUG_VERBOSE, "%a: address: 0x%lx\n", __func__, mUefiVarsAddr));
+
+ return RETURN_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+VirtMmHwMemAttr (
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ mUefiVarsAddr,
+ EFI_PAGE_SIZE,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: AddMemorySpace failed: %r\n", __func__, Status));
+ return RETURN_UNSUPPORTED;
+ }
+
+ Status = gDS->SetMemorySpaceAttributes (
+ mUefiVarsAddr,
+ EFI_PAGE_SIZE,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: SetMemorySpaceAttributes failed: %r\n", __func__, Status));
+ return RETURN_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+VirtMmHwCommand (
+ UINT32 Cmd
+ )
+{
+ UINT32 Count;
+ UINT32 Sts;
+
+ MmioWrite16 (mUefiVarsAddr + UEFI_VARS_REG_CMD_STS, Cmd);
+ for (Count = 0; Count < 100; Count++) {
+ Sts = MmioRead16 (mUefiVarsAddr + UEFI_VARS_REG_CMD_STS);
+ DEBUG ((DEBUG_VERBOSE, "%a: Sts: 0x%x\n", __func__, Sts));
+ switch (Sts) {
+ case UEFI_VARS_STS_SUCCESS:
+ return RETURN_SUCCESS;
+ case UEFI_VARS_STS_BUSY:
+ CpuPause ();
+ break;
+ case UEFI_VARS_STS_ERR_NOT_SUPPORTED:
+ return RETURN_UNSUPPORTED;
+ case UEFI_VARS_STS_ERR_BAD_BUFFER_SIZE:
+ return RETURN_BAD_BUFFER_SIZE;
+ default:
+ return RETURN_DEVICE_ERROR;
+ }
+ }
+
+ return RETURN_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+VirtMmHwInit (
+ VOID
+ )
+{
+ UINT32 Magic, AddrLo, AddrHi;
+ EFI_STATUS Status;
+
+ Status = VirtMmHwFind ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: VirtMmHwFind() failed: %d\n", __func__, Status));
+ return Status;
+ }
+
+ VirtMmHwMemAttr ();
+
+ Magic = MmioRead16 (mUefiVarsAddr + UEFI_VARS_REG_MAGIC);
+ if (Magic != UEFI_VARS_MAGIC_VALUE) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Magic value mismatch (0x%x != 0x%x)\n",
+ __func__,
+ Magic,
+ UEFI_VARS_MAGIC_VALUE
+ ));
+ return RETURN_DEVICE_ERROR;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: Magic 0x%x, good\n", __func__, Magic));
+
+ Status = VirtMmHwCommand (UEFI_VARS_CMD_RESET);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Reset failed: %d\n", __func__, Status));
+ return Status;
+ }
+
+ AddrLo = (UINT32)mCommunicateBufferPhys;
+ AddrHi = (UINT32)RShiftU64 (mCommunicateBufferPhys, 32);
+ MmioWrite32 (mUefiVarsAddr + UEFI_VARS_REG_BUFFER_ADDR_LO, AddrLo);
+ MmioWrite32 (mUefiVarsAddr + UEFI_VARS_REG_BUFFER_ADDR_HI, AddrHi);
+ MmioWrite32 (mUefiVarsAddr + UEFI_VARS_REG_BUFFER_SIZE, MAX_BUFFER_SIZE);
+
+ return RETURN_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VirtMmHwVirtMap (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: << %lx\n", __func__, mUefiVarsAddr));
+ Status = gRT->ConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mUefiVarsAddr);
+ DEBUG ((DEBUG_VERBOSE, "%a: >> %lx\n", __func__, mUefiVarsAddr));
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+VirtMmHwComm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = VirtMmHwCommand (UEFI_VARS_CMD_MM);
+ DEBUG ((DEBUG_VERBOSE, "%a: Status: %r\n", __func__, Status));
+
+ return Status;
+}
--
2.42.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111681): https://edk2.groups.io/g/devel/message/111681
Mute This Topic: https://groups.io/mt/102767939/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [edk2-devel] [PATCH 7/7] ArmVirtPkg/ArmVirtQemu: add QEMU_VARS option
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
` (5 preceding siblings ...)
2023-11-23 15:02 ` [edk2-devel] [PATCH 6/7] OvmfPkg/VirtMmCommunicationDxe: add arm support Gerd Hoffmann
@ 2023-11-23 15:02 ` Gerd Hoffmann
2023-11-28 8:33 ` [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Ard Biesheuvel
7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2023-11-23 15:02 UTC (permalink / raw)
To: devel; +Cc: Oliver Steffen, László Érsek, Gerd Hoffmann
Add config option to use qemu variable service,
via VirtMmCommunicationDxe. Default is FALSE,
build using '-D QEMU_VARS=TRUE' to enable.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ArmVirtPkg/ArmVirt.dsc.inc | 3 +++
ArmVirtPkg/ArmVirtQemu.dsc | 11 +++++++++++
ArmVirtPkg/ArmVirtQemuKernel.dsc | 11 +++++++++++
OvmfPkg/OvmfPkgX64.dsc | 1 +
ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 5 +++++
5 files changed, 31 insertions(+)
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index fe6488ee9910..077abc36ff42 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -175,6 +175,9 @@ [LibraryClasses.common]
VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+!if $(QEMU_VARS) == TRUE
+ MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
+!endif
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 30e3cfc8b9cc..bb1fd6324783 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -29,6 +29,7 @@ [Defines]
#
DEFINE TTY_TERMINAL = FALSE
DEFINE SECURE_BOOT_ENABLE = FALSE
+ DEFINE QEMU_VARS = FALSE
DEFINE TPM2_ENABLE = FALSE
DEFINE TPM2_CONFIG_ENABLE = FALSE
DEFINE CAVIUM_ERRATUM_27456 = FALSE
@@ -149,6 +150,11 @@ [PcdsFeatureFlag.common]
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|$(TPM2_ENABLE)
+!if $(QEMU_VARS) == TRUE
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuVarsRequire|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE
+!endif
+
[PcdsFixedAtBuild.common]
!if $(ARCH) == AARCH64
gArmTokenSpaceGuid.PcdVFPEnabled|1
@@ -385,6 +391,10 @@ [Components.common]
#
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+!if $(QEMU_VARS) == TRUE
+ OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+!else
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
@@ -392,6 +402,7 @@ [Components.common]
# don't use unaligned CopyMem () on the UEFI varstore NOR flash region
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}
+!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
<LibraryClasses>
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index b50f8e84a39a..0cc81f46431a 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -29,6 +29,7 @@ [Defines]
#
DEFINE TTY_TERMINAL = FALSE
DEFINE SECURE_BOOT_ENABLE = FALSE
+ DEFINE QEMU_VARS = FALSE
#
# Network definition
@@ -115,6 +116,11 @@ [PcdsFeatureFlag.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+!if $(QEMU_VARS) == TRUE
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuVarsRequire|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE
+!endif
+
[PcdsFixedAtBuild.common]
!if $(ARCH) == AARCH64
gArmTokenSpaceGuid.PcdVFPEnabled|1
@@ -293,6 +299,10 @@ [Components.common]
#
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+!if $(QEMU_VARS) == TRUE
+ OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+!else
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
@@ -300,6 +310,7 @@ [Components.common]
# don't use unaligned CopyMem () on the UEFI varstore NOR flash region
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}
+!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
<LibraryClasses>
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a27ea95dedc5..c7690279be3e 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -31,6 +31,7 @@ [Defines]
#
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE SMM_REQUIRE = FALSE
+ DEFINE QEMU_VARS = FALSE
DEFINE SOURCE_DEBUG_ENABLE = FALSE
DEFINE CC_MEASUREMENT_ENABLE = FALSE
diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
index 9b3e37d5c998..61850eb2be9e 100644
--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
@@ -52,7 +52,12 @@ [FV.FvMain]
INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+!if $(QEMU_VARS) == TRUE
+ INF OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+!else
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
!endif
--
2.42.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111682): https://edk2.groups.io/g/devel/message/111682
Mute This Topic: https://groups.io/mt/102767940/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt.
2023-11-23 15:02 [edk2-devel] [PATCH 0/7] Add VirtMmCommunication driver, enable for OVMF and ArmVirt Gerd Hoffmann
` (6 preceding siblings ...)
2023-11-23 15:02 ` [edk2-devel] [PATCH 7/7] ArmVirtPkg/ArmVirtQemu: add QEMU_VARS option Gerd Hoffmann
@ 2023-11-28 8:33 ` Ard Biesheuvel
7 siblings, 0 replies; 9+ messages in thread
From: Ard Biesheuvel @ 2023-11-28 8:33 UTC (permalink / raw)
To: devel, kraxel; +Cc: Oliver Steffen, László Érsek
On Thu, 23 Nov 2023 at 16:02, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> This is the edk2 side of the qemu patch series posted last week to
> qemu-devel:
> https://lists.gnu.org/archive/html/qemu-devel/2023-11/msg03714.html
>
> The driver forwards MM calls to the virtualization host instead of the
> MM code running in SMM (x64) or el3 (arm) mode. The functionality
> traditionally implemented by the SMM code is provided by qemu instead.
>
> This allows to provide persistent variable support without an
> (virtual) flash device and it also allows to support secure
> boot without depending on SMM or el3 emulation support in the
> hypervisor.
>
I like this a lot - not only for QEMU + OVMF/ArmVirt, but also for
other VM firmware projects (I am working on a minimal UEFI
implementation in Rust for ArmVirt, and variable support is much
easier to implement using this paravirt interface)
> Gerd Hoffmann (7):
> OvmfPkg: add IndustryStandard/QemuUefiVars.h
> OvmfPkg: add new VirtMmCommunicationDxe driver
> OvmfPkg/OvmfPkgX64: add QEMU_VARS option
> OvmfPkg: add PcdQemuVarsRequire
> OvmfPkg/VirtMmCommunicationDxe: stop on init failure
> OvmfPkg/VirtMmCommunicationDxe: add arm support
> ArmVirtPkg/ArmVirtQemu: add QEMU_VARS option
>
> OvmfPkg/OvmfPkg.dec | 3 +
> ArmVirtPkg/ArmVirt.dsc.inc | 3 +
> ArmVirtPkg/ArmVirtQemu.dsc | 11 +
> ArmVirtPkg/ArmVirtQemuKernel.dsc | 11 +
> OvmfPkg/OvmfPkgX64.dsc | 17 +-
> OvmfPkg/OvmfPkgX64.fdf | 12 +-
> OvmfPkg/PlatformPei/PlatformPei.inf | 1 +
> .../VirtMmCommunication.inf | 67 +++
> .../Include/IndustryStandard/QemuUefiVars.h | 41 ++
> .../VirtMmCommunication.h | 37 ++
> OvmfPkg/PlatformPei/Platform.c | 4 +
> OvmfPkg/VirtMmCommunicationDxe/QemuFdt.c | 208 ++++++++++
> OvmfPkg/VirtMmCommunicationDxe/QemuX64.c | 106 +++++
> .../VirtMmCommunication.c | 390 ++++++++++++++++++
> ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 5 +
> 15 files changed, 914 insertions(+), 2 deletions(-)
> create mode 100644 OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.inf
> create mode 100644 OvmfPkg/Include/IndustryStandard/QemuUefiVars.h
> create mode 100644 OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.h
> create mode 100644 OvmfPkg/VirtMmCommunicationDxe/QemuFdt.c
> create mode 100644 OvmfPkg/VirtMmCommunicationDxe/QemuX64.c
> create mode 100644 OvmfPkg/VirtMmCommunicationDxe/VirtMmCommunication.c
>
> --
> 2.42.0
>
>
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111800): https://edk2.groups.io/g/devel/message/111800
Mute This Topic: https://groups.io/mt/102767943/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 9+ messages in thread