public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Gerd Hoffmann" <kraxel@redhat.com>
To: devel@edk2.groups.io
Cc: "Oliver Steffen" <osteffen@redhat.com>,
	"László Érsek" <lersek@redhat.com>,
	"Gerd Hoffmann" <kraxel@redhat.com>
Subject: [edk2-devel] [PATCH 2/7] OvmfPkg: add new VirtMmCommunicationDxe driver
Date: Thu, 23 Nov 2023 16:02:29 +0100	[thread overview]
Message-ID: <20231123150234.117835-3-kraxel@redhat.com> (raw)
In-Reply-To: <20231123150234.117835-1-kraxel@redhat.com>

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]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2023-11-23 15:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2023-11-23 15:02 ` [edk2-devel] [PATCH 3/7] OvmfPkg/OvmfPkgX64: add QEMU_VARS option Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 4/7] OvmfPkg: add PcdQemuVarsRequire Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 5/7] OvmfPkg/VirtMmCommunicationDxe: stop on init failure Gerd Hoffmann
2023-11-23 15:02 ` [edk2-devel] [PATCH 6/7] OvmfPkg/VirtMmCommunicationDxe: add arm support 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231123150234.117835-3-kraxel@redhat.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox