public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/3] OvmfXen: Fix machine shutdown in PVH guest
@ 2022-11-11 15:27 Anthony PERARD
  2022-11-11 15:27 ` [PATCH 1/3] OvmfPkg: Introduce runtime XenHypercallLib Anthony PERARD
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Anthony PERARD @ 2022-11-11 15:27 UTC (permalink / raw)
  To: devel
  Cc: Jiewen Yao, Julien Grall, Jordan Justen, Ard Biesheuvel,
	Gerd Hoffmann, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

Patch series available in this git branch:
https://xenbits.xen.org/git-http/people/aperard/ovmf.git br.fix-pvh-shutdown-v2-v1

From: Anthony PERARD <anthony.perard@citrix.com>

Hi,

This series instroduce a XenHypercallLib that can be used at runtime by a EFI
service. And then it introduce a modified ResetSystemLib for Xen so we can use
the hypercall interface to shutdown a machine when the ACPI interface isn't
available.

Thanks,

Anthony PERARD (3):
  OvmfPkg: Introduce runtime XenHypercallLib
  OvmfPkg/XenHypercallLib: Add SchedOp hypercall
  OvmfPkg/OvmfXen: Introduce Xen's ResetSystemLib, to use xen hypercall

 OvmfPkg/OvmfXen.dsc                           |  11 +-
 ...ystemLib.inf => BaseResetSystemLibXen.inf} |   9 +-
 ...SystemLib.inf => DxeResetSystemLibXen.inf} |  11 +-
 .../XenHypercallRuntimeLib.inf                |  46 ++++
 OvmfPkg/Include/IndustryStandard/Xen/sched.h  |  50 +++++
 OvmfPkg/Include/Library/XenHypercallLib.h     |   7 +
 ...ResetShutdown.c => BaseResetShutdownXen.c} |  19 +-
 ...eResetShutdown.c => DxeResetShutdownXen.c} |  26 ++-
 .../XenHypercallLib/X86RuntimeXenHypercall.c  | 210 ++++++++++++++++++
 .../Library/XenHypercallLib/XenHypercall.c    |  14 ++
 .../X64/RuntimeHypercallPage.nasm             |  24 ++
 11 files changed, 401 insertions(+), 26 deletions(-)
 copy OvmfPkg/Library/ResetSystemLib/{BaseResetSystemLib.inf => BaseResetSystemLibXen.inf} (73%)
 copy OvmfPkg/Library/ResetSystemLib/{DxeResetSystemLib.inf => DxeResetSystemLibXen.inf} (73%)
 create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallRuntimeLib.inf
 create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/sched.h
 copy OvmfPkg/Library/ResetSystemLib/{BaseResetShutdown.c => BaseResetShutdownXen.c} (72%)
 copy OvmfPkg/Library/ResetSystemLib/{DxeResetShutdown.c => DxeResetShutdownXen.c} (72%)
 create mode 100644 OvmfPkg/Library/XenHypercallLib/X86RuntimeXenHypercall.c
 create mode 100644 OvmfPkg/Library/XenHypercallLib/X64/RuntimeHypercallPage.nasm

-- 
Anthony PERARD


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] OvmfPkg: Introduce runtime XenHypercallLib
  2022-11-11 15:27 [PATCH 0/3] OvmfXen: Fix machine shutdown in PVH guest Anthony PERARD
@ 2022-11-11 15:27 ` Anthony PERARD
  2022-11-11 15:27 ` [PATCH 2/3] OvmfPkg/XenHypercallLib: Add SchedOp hypercall Anthony PERARD
  2022-11-11 15:27 ` [PATCH 3/3] OvmfPkg/OvmfXen: Introduce Xen's ResetSystemLib, to use xen hypercall Anthony PERARD
  2 siblings, 0 replies; 4+ messages in thread
From: Anthony PERARD @ 2022-11-11 15:27 UTC (permalink / raw)
  To: devel
  Cc: Jiewen Yao, Julien Grall, Jordan Justen, Ard Biesheuvel,
	Gerd Hoffmann, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

We need a way to execute instruction "generated" at runtime from the
runtime library.

This patch introduce XenHypercallRuntimeLib, which is mostly a copy of
XenHypercallLib with a few changes.

We reserved some code space with "XenHypercallPage", which we will
overwrite to put the xen hypercall code. Then we ask Xen to overwrite
the reserved space with the hypercall page via `wrmsr`.

Allocation doesn't work, because the memory allocated at run time is
always considered to be data instead of code, so once Linux takes
over, we can't execute from it.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---

Notes:
    I've been told that we don't need to ask Xen on how to make hypercall
    on x86, and that was just an helper to not have to figure out which
    instruction to use. That would mean that instead of doing write_msr,
    we would need a way to distinguish between AMD and Intel in order to
    find out which instruction to use. So if this patch is too weird, that
    another way to have hypercall in a runtime service.

 OvmfPkg/OvmfXen.dsc                           |   1 +
 .../XenHypercallRuntimeLib.inf                |  46 ++++
 .../XenHypercallLib/X86RuntimeXenHypercall.c  | 210 ++++++++++++++++++
 .../X64/RuntimeHypercallPage.nasm             |  24 ++
 4 files changed, 281 insertions(+)
 create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallRuntimeLib.inf
 create mode 100644 OvmfPkg/Library/XenHypercallLib/X86RuntimeXenHypercall.c
 create mode 100644 OvmfPkg/Library/XenHypercallLib/X64/RuntimeHypercallPage.nasm

diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 58a7c97cddf7..8df173a0ee84 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -312,6 +312,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
   VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallRuntimeLib.inf
 
 [LibraryClasses.common.UEFI_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallRuntimeLib.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallRuntimeLib.inf
new file mode 100644
index 000000000000..07fdeb612760
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallRuntimeLib.inf
@@ -0,0 +1,46 @@
+## @file
+#  Xen Hypercall abstraction lib for Intel for runtime services
+#
+#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+#  Copyright (c) 2022, Citrix Systems, Inc.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = XenHypercallRuntimeLib
+  FILE_GUID                      = f657a395-1d2c-40b5-bd34-eedc203899ab
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  CONSTRUCTOR                    = XenHypercallRuntimeLibConstruct
+
+[Defines.IA32, Defines.X64]
+  LIBRARY_CLASS                  = XenHypercallLib|DXE_RUNTIME_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources.X64]
+  X86RuntimeXenHypercall.c
+  X64/hypercall.nasm
+  X64/RuntimeHypercallPage.nasm
+
+[Sources]
+  XenHypercall.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  UefiRuntimeLib
+
+[Guids.X64]
+  gEfiEventVirtualAddressChangeGuid   # ALWAYS_CONSUMED
diff --git a/OvmfPkg/Library/XenHypercallLib/X86RuntimeXenHypercall.c b/OvmfPkg/Library/XenHypercallLib/X86RuntimeXenHypercall.c
new file mode 100644
index 000000000000..d1c097e00f3a
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/X86RuntimeXenHypercall.c
@@ -0,0 +1,210 @@
+/** @file
+  Xen Hypercall Library implementation for Intel architecture
+
+  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2022, Citrix Systems, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Guid/EventGroup.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/XenHypercallLib.h>
+
+STATIC VOID  *mHyperPage;
+
+//
+// Pointer to reserved page for Xen's hypercall page.
+//
+extern VOID  *XenHypercallPage;
+
+//
+// Virtual Address Change Event
+//
+// This is needed for runtime variable access.
+//
+EFI_EVENT  mXenHypercallLibAddrChangeEvent = NULL;
+
+RETURN_STATUS
+EFIAPI
+XenHypercallRuntimeLibConstruct (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  XenHypercallLibInit ();
+
+  //
+  // We don't fail library construction, since that has catastrophic
+  // consequences for client modules (whereas those modules may easily be
+  // running on a non-Xen platform). Instead, XenHypercallIsAvailable()
+  // will return FALSE.
+  //
+  return RETURN_SUCCESS;
+}
+
+/**
+  Check if the Xen Hypercall library is able to make calls to the Xen
+  hypervisor.
+
+  Client code should call further functions in this library only if, and after,
+  this function returns TRUE.
+
+  @retval TRUE   Hypercalls are available.
+  @retval FALSE  Hypercalls are not available.
+**/
+BOOLEAN
+EFIAPI
+XenHypercallIsAvailable (
+  VOID
+  )
+{
+  return mHyperPage != NULL;
+}
+
+//
+// Interface exposed by the ASM implementation of the core hypercall
+//
+INTN
+EFIAPI
+__XenHypercall2 (
+  IN     VOID  *HypercallAddr,
+  IN OUT INTN  Arg1,
+  IN OUT INTN  Arg2
+  );
+
+/**
+  Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+  It converts pointer to new virtual address.
+
+  @param  Event        Event whose notification function is being invoked.
+  @param  Context      Pointer to the notification function's context.
+
+**/
+STATIC
+VOID
+EFIAPI
+XenHypercallLibAddrChangeEvent (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = EfiConvertFunctionPointer (0, &mHyperPage);
+  ASSERT_EFI_ERROR (Status);
+}
+
+STATIC
+UINT32
+XenCpuidLeaf (
+  VOID
+  )
+{
+  UINT8   Signature[13];
+  UINT32  XenLeaf;
+
+  Signature[12] = '\0';
+  for (XenLeaf = 0x40000000; XenLeaf < 0x40010000; XenLeaf += 0x100) {
+    AsmCpuid (
+      XenLeaf,
+      NULL,
+      (UINT32 *)&Signature[0],
+      (UINT32 *)&Signature[4],
+      (UINT32 *)&Signature[8]
+      );
+
+    if (!AsciiStrCmp ((CHAR8 *)Signature, "XenVMMXenVMM")) {
+      return XenLeaf;
+    }
+  }
+
+  return 0;
+}
+
+/**
+  Library constructor: populate hypercall page.
+**/
+RETURN_STATUS
+EFIAPI
+XenHypercallLibInit (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TransferReg;
+  UINT32      TransferPages;
+  UINT32      XenLeaf;
+
+  XenLeaf = XenCpuidLeaf ();
+
+  if (XenLeaf == 0) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
+
+  //
+  // Only populate the first page of the hypercall even if there's more
+  // than one, that is even if TransferPages > 1.
+  // We don't use hypercall id > 127.
+  //
+  AsmWriteMsr64 (TransferReg, (UINTN)&XenHypercallPage);
+
+  mHyperPage = &XenHypercallPage;
+
+  //
+  // Register for the virtual address change event
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  XenHypercallLibAddrChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &mXenHypercallLibAddrChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  This function will put the two arguments in the right place (registers) and
+  invoke the hypercall identified by HypercallID.
+
+  @param HypercallID    The symbolic ID of the hypercall to be invoked
+  @param Arg1           First argument.
+  @param Arg2           Second argument.
+
+  @return   Return 0 if success otherwise it return an errno.
+**/
+INTN
+EFIAPI
+XenHypercall2 (
+  IN     UINTN  HypercallID,
+  IN OUT INTN   Arg1,
+  IN OUT INTN   Arg2
+  )
+{
+  ASSERT (mHyperPage != NULL);
+  //
+  // Hypercall must not use code beyong the first hypercall page.
+  // Only the first page is populated by XenHypercallLibInit ()
+  //
+  ASSERT (HypercallID < EFI_PAGE_SIZE / 32);
+  if (HypercallID >= EFI_PAGE_SIZE / 32) {
+    return -38; // -ENOSYS
+  }
+
+  return __XenHypercall2 ((UINT8 *)mHyperPage + HypercallID * 32, Arg1, Arg2);
+}
diff --git a/OvmfPkg/Library/XenHypercallLib/X64/RuntimeHypercallPage.nasm b/OvmfPkg/Library/XenHypercallLib/X64/RuntimeHypercallPage.nasm
new file mode 100644
index 000000000000..f0897c51b31c
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/X64/RuntimeHypercallPage.nasm
@@ -0,0 +1,24 @@
+;; @file
+;  Provide one page of code space to be overwritten at boot and to be used by
+;  runtime drivers to make Xen hypercall on x86.
+;
+;  Copyright (c) 2022, Citrix Systems, Inc.
+;
+;  SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+DEFAULT REL
+SECTION .text
+
+;
+; Align at page boundary as we need a pointer on a page without offset.
+;
+ALIGN EFI_PAGE_SIZE
+
+;
+; reserve some .text space to put-in Xen's hypercall instructions in at runtime.
+; Poisoned with `ret`
+;
+global ASM_PFX(XenHypercallPage)
+ASM_PFX(XenHypercallPage):
+  times EFI_PAGE_SIZE ret
-- 
Anthony PERARD


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] OvmfPkg/XenHypercallLib: Add SchedOp hypercall
  2022-11-11 15:27 [PATCH 0/3] OvmfXen: Fix machine shutdown in PVH guest Anthony PERARD
  2022-11-11 15:27 ` [PATCH 1/3] OvmfPkg: Introduce runtime XenHypercallLib Anthony PERARD
@ 2022-11-11 15:27 ` Anthony PERARD
  2022-11-11 15:27 ` [PATCH 3/3] OvmfPkg/OvmfXen: Introduce Xen's ResetSystemLib, to use xen hypercall Anthony PERARD
  2 siblings, 0 replies; 4+ messages in thread
From: Anthony PERARD @ 2022-11-11 15:27 UTC (permalink / raw)
  To: devel
  Cc: Jiewen Yao, Julien Grall, Jordan Justen, Ard Biesheuvel,
	Gerd Hoffmann, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

Add a new function to allow to make an hypercall to shutdown the
machine.

This import "sched.h" public header from Xen Project's repo. Some
changes have been made to be closer to EDK2's coding style.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/Include/IndustryStandard/Xen/sched.h  | 50 +++++++++++++++++++
 OvmfPkg/Include/Library/XenHypercallLib.h     |  7 +++
 .../Library/XenHypercallLib/XenHypercall.c    | 14 ++++++
 3 files changed, 71 insertions(+)
 create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/sched.h

diff --git a/OvmfPkg/Include/IndustryStandard/Xen/sched.h b/OvmfPkg/Include/IndustryStandard/Xen/sched.h
new file mode 100644
index 000000000000..b050354efe8d
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/Xen/sched.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ * sched.h
+ *
+ * Scheduler state interactions
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
+ */
+
+#ifndef __XEN_PUBLIC_SCHED_H__
+#define __XEN_PUBLIC_SCHED_H__
+
+#include "event_channel.h"
+
+/*
+ * Halt execution of this domain (all VCPUs) and notify the system controller.
+ * @arg == pointer to sched_shutdown_t structure.
+ *
+ * If the sched_shutdown_t reason is SHUTDOWN_suspend then
+ * x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN
+ * of the guest's start info page.  RDX/EDX is the third hypercall
+ * argument.
+ *
+ * In addition, which reason is SHUTDOWN_suspend this hypercall
+ * returns 1 if suspend was cancelled or the domain was merely
+ * checkpointed, and 0 if it is resuming in a new domain.
+ */
+#define XEN_SCHEDOP_SHUTDOWN  2
+
+struct _XEN_SCHED_SHUTDOWN {
+  unsigned int    Reason; /* SHUTDOWN_* => enum sched_shutdown_reason */
+};
+
+typedef struct _XEN_SCHED_SHUTDOWN XEN_SCHED_SHUTDOWN;
+DEFINE_XEN_GUEST_HANDLE (XEN_SCHED_SHUTDOWN);
+
+/*
+ * Reason codes for SCHEDOP_shutdown. These may be interpreted by control
+ * software to determine the appropriate action. For the most part, Xen does
+ * not care about the shutdown code.
+ */
+/* ` enum sched_shutdown_reason { */
+#define XEN_SHED_SHUTDOWN_POWEROFF  0  /* Domain exited normally. Clean up and kill. */
+#define XEN_SHED_SHUTDOWN_REBOOT    1  /* Clean up, kill, and then restart.          */
+#define XEN_SHED_SHUTDOWN_SUSPEND   2  /* Clean up, save suspend info, kill.         */
+#define XEN_SHED_SHUTDOWN_CRASH     3  /* Tell controller we've crashed.             */
+#define XEN_SHED_SHUTDOWN_WATCHDOG  4  /* Restart because watchdog time expired.     */
+
+#endif /* __XEN_PUBLIC_SCHED_H__ */
diff --git a/OvmfPkg/Include/Library/XenHypercallLib.h b/OvmfPkg/Include/Library/XenHypercallLib.h
index 28eee8ccac85..d7cf2c0c505b 100644
--- a/OvmfPkg/Include/Library/XenHypercallLib.h
+++ b/OvmfPkg/Include/Library/XenHypercallLib.h
@@ -101,4 +101,11 @@ XenHypercallEventChannelOp (
   IN OUT VOID  *Arguments
   );
 
+INTN
+EFIAPI
+XenHypercallSchedOp (
+  IN     INTN  Operation,
+  IN OUT VOID  *Arguments
+  );
+
 #endif
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
index 65b14a11f402..b1a129998fdc 100644
--- a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
@@ -87,3 +87,17 @@ XenHypercallEventChannelOp (
            (INTN)Arguments
            );
 }
+
+INTN
+EFIAPI
+XenHypercallSchedOp (
+  IN     INTN  Operation,
+  IN OUT VOID  *Arguments
+  )
+{
+  return XenHypercall2 (
+           __HYPERVISOR_sched_op,
+           Operation,
+           (INTN)Arguments
+           );
+}
-- 
Anthony PERARD


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] OvmfPkg/OvmfXen: Introduce Xen's ResetSystemLib, to use xen hypercall
  2022-11-11 15:27 [PATCH 0/3] OvmfXen: Fix machine shutdown in PVH guest Anthony PERARD
  2022-11-11 15:27 ` [PATCH 1/3] OvmfPkg: Introduce runtime XenHypercallLib Anthony PERARD
  2022-11-11 15:27 ` [PATCH 2/3] OvmfPkg/XenHypercallLib: Add SchedOp hypercall Anthony PERARD
@ 2022-11-11 15:27 ` Anthony PERARD
  2 siblings, 0 replies; 4+ messages in thread
From: Anthony PERARD @ 2022-11-11 15:27 UTC (permalink / raw)
  To: devel
  Cc: Jiewen Yao, Julien Grall, Jordan Justen, Ard Biesheuvel,
	Gerd Hoffmann, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

When booting OvmfXen, the ACPI interface for shutdown/reset might not
be available, instead use the hypercall interface.

While it's probably possible to use the hypercall in all cases, we
keep using the same interface while it still possible. That is ACPI on
HVM guest, and fallback to hypercall on PVH guest.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/OvmfXen.dsc                           | 10 +++----
 ...ystemLib.inf => BaseResetSystemLibXen.inf} |  9 ++++---
 ...SystemLib.inf => DxeResetSystemLibXen.inf} | 11 +++++---
 ...ResetShutdown.c => BaseResetShutdownXen.c} | 19 +++++++++++---
 ...eResetShutdown.c => DxeResetShutdownXen.c} | 26 ++++++++++++-------
 5 files changed, 49 insertions(+), 26 deletions(-)
 copy OvmfPkg/Library/ResetSystemLib/{BaseResetSystemLib.inf => BaseResetSystemLibXen.inf} (73%)
 copy OvmfPkg/Library/ResetSystemLib/{DxeResetSystemLib.inf => DxeResetSystemLibXen.inf} (73%)
 copy OvmfPkg/Library/ResetSystemLib/{BaseResetShutdown.c => BaseResetShutdownXen.c} (72%)
 copy OvmfPkg/Library/ResetSystemLib/{DxeResetShutdown.c => DxeResetShutdownXen.c} (72%)

diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 8df173a0ee84..18f7c0d76643 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -118,7 +118,7 @@ [SkuIds]
 [LibraryClasses]
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
   TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
-  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf
   PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
   BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
   BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
@@ -302,7 +302,7 @@ [LibraryClasses.common.DXE_CORE]
 
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -316,7 +316,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
 
 [LibraryClasses.common.UEFI_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -326,7 +326,7 @@ [LibraryClasses.common.UEFI_DRIVER]
 
 [LibraryClasses.common.DXE_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
   ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -345,7 +345,7 @@ [LibraryClasses.common.DXE_DRIVER]
 
 [LibraryClasses.common.UEFI_APPLICATION]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
   ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
diff --git a/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf
similarity index 73%
copy from OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf
copy to OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf
index 35d317f1e0b3..8d75dd565365 100644
--- a/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf
+++ b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf
@@ -1,7 +1,9 @@
 ## @file
-#  Base library instance for ResetSystem library class for OVMF
+#  Base library instance for ResetSystem library class for Xen
 #
 #  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2022, Citrix Systems, Inc.
+#
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -9,7 +11,7 @@
 [Defines]
   INF_VERSION                    = 0x00010005
   BASE_NAME                      = BaseResetSystemLib
-  FILE_GUID                      = 66564872-21d4-4d2a-a68b-1e844f980820
+  FILE_GUID                      = 9ef32aa1-9e82-4fb1-9c49-0eff538601f8
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
   LIBRARY_CLASS                  = ResetSystemLib|SEC PEI_CORE PEIM DXE_CORE
@@ -22,7 +24,7 @@ [Defines]
 #
 
 [Sources]
-  BaseResetShutdown.c
+  BaseResetShutdownXen.c
   ResetSystemLib.c
 
 [Packages]
@@ -36,3 +38,4 @@ [LibraryClasses]
   IoLib
   PciLib
   TimerLib
+  XenHypercallLib
diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
similarity index 73%
copy from OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
copy to OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
index a9b4ce90000a..ccee69e6e1fa 100644
--- a/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+++ b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
@@ -1,16 +1,18 @@
 ## @file
-#  DXE library instance for ResetSystem library class for OVMF
+#  DXE library instance for ResetSystem library class for Xen
 #
 #  Copyright (C) 2020, Red Hat, Inc.
 #  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2022, Citrix Systems, Inc.
+#
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
 
 [Defines]
   INF_VERSION                    = 1.29
-  BASE_NAME                      = DxeResetSystemLib
-  FILE_GUID                      = bc7835ea-4094-41fe-b770-bad9e6c479b2
+  BASE_NAME                      = DxeResetSystemLibXen
+  FILE_GUID                      = a5ac25e6-4dc5-4fd9-92cd-74e46bd2e72a
   MODULE_TYPE                    = DXE_DRIVER
   VERSION_STRING                 = 1.0
   LIBRARY_CLASS                  = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
@@ -24,7 +26,7 @@ [Defines]
 #
 
 [Sources]
-  DxeResetShutdown.c
+  DxeResetShutdownXen.c
   ResetSystemLib.c
 
 [Packages]
@@ -38,6 +40,7 @@ [LibraryClasses]
   IoLib
   PcdLib
   TimerLib
+  XenHypercallLib
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId ## CONSUMES
diff --git a/OvmfPkg/Library/ResetSystemLib/BaseResetShutdown.c b/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c
similarity index 72%
copy from OvmfPkg/Library/ResetSystemLib/BaseResetShutdown.c
copy to OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c
index c21d3c89cf95..f45d9125feb4 100644
--- a/OvmfPkg/Library/ResetSystemLib/BaseResetShutdown.c
+++ b/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c
@@ -3,6 +3,8 @@
 
   Copyright (C) 2020, Red Hat, Inc.
   Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2022, Citrix Systems, Inc.
+
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -13,6 +15,7 @@
 #include <Library/IoLib.h>          // IoOr16()
 #include <Library/PciLib.h>         // PciRead16()
 #include <Library/ResetSystemLib.h> // ResetShutdown()
+#include <Library/XenHypercallLib.h>
 #include <OvmfPlatforms.h>          // OVMF_HOSTBRIDGE_DID
 
 /**
@@ -40,12 +43,20 @@ ResetShutdown (
     case INTEL_Q35_MCH_DEVICE_ID:
       AcpiPmBaseAddress = ICH9_PMBASE_VALUE;
       break;
-    case CLOUDHV_DEVICE_ID:
-      IoWrite8 (CLOUDHV_ACPI_SHUTDOWN_IO_ADDRESS, 5 << 2 | 1 << 5);
-      CpuDeadLoop ();
     default:
-      ASSERT (FALSE);
+    {
+      //
+      // Fallback to using hypercall.
+      // Necessary for PVH guest, but should work for HVM guest.
+      //
+      INTN                ReturnCode;
+      XEN_SCHED_SHUTDOWN  ShutdownOp = {
+        .Reason = XEN_SHED_SHUTDOWN_POWEROFF,
+      };
+      ReturnCode = XenHypercallSchedOp (XEN_SCHEDOP_SHUTDOWN, ShutdownOp);
+      ASSERT (ReturnCode == 0);
       CpuDeadLoop ();
+    }
   }
 
   IoBitFieldWrite16 (AcpiPmBaseAddress + 4, 10, 13, 0);
diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetShutdown.c b/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c
similarity index 72%
copy from OvmfPkg/Library/ResetSystemLib/DxeResetShutdown.c
copy to OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c
index 31f01b82e4ee..f7f32765cfc9 100644
--- a/OvmfPkg/Library/ResetSystemLib/DxeResetShutdown.c
+++ b/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c
@@ -8,15 +8,16 @@
 
 #include <Base.h>                   // BIT13
 
+#include <IndustryStandard/Xen/sched.h>
 #include <Library/BaseLib.h>        // CpuDeadLoop()
 #include <Library/DebugLib.h>       // ASSERT()
 #include <Library/IoLib.h>          // IoOr16()
 #include <Library/PcdLib.h>         // PcdGet16()
 #include <Library/ResetSystemLib.h> // ResetShutdown()
+#include <Library/XenHypercallLib.h>
 #include <OvmfPlatforms.h>          // PIIX4_PMBA_VALUE
 
 STATIC UINT16  mAcpiPmBaseAddress;
-STATIC UINT16  mAcpiHwReducedSleepCtl;
 
 EFI_STATUS
 EFIAPI
@@ -35,13 +36,13 @@ DxeResetInit (
     case INTEL_Q35_MCH_DEVICE_ID:
       mAcpiPmBaseAddress = ICH9_PMBASE_VALUE;
       break;
-    case CLOUDHV_DEVICE_ID:
-      mAcpiHwReducedSleepCtl = CLOUDHV_ACPI_SHUTDOWN_IO_ADDRESS;
-      break;
     default:
-      ASSERT (FALSE);
-      CpuDeadLoop ();
-      return EFI_UNSUPPORTED;
+      //
+      // Fallback to using hypercall.
+      // Necessary for PVH guest, but should work for HVM guest.
+      //
+      mAcpiPmBaseAddress = 0xffff;
+      break;
   }
 
   return EFI_SUCCESS;
@@ -60,11 +61,16 @@ ResetShutdown (
   VOID
   )
 {
-  if (mAcpiHwReducedSleepCtl) {
-    IoWrite8 (mAcpiHwReducedSleepCtl, 5 << 2 | 1 << 5);
-  } else {
+  if (mAcpiPmBaseAddress != 0xffff) {
     IoBitFieldWrite16 (mAcpiPmBaseAddress + 4, 10, 13, 0);
     IoOr16 (mAcpiPmBaseAddress + 4, BIT13);
+  } else {
+    INTN                ReturnCode;
+    XEN_SCHED_SHUTDOWN  ShutdownOp = {
+      .Reason = XEN_SHED_SHUTDOWN_POWEROFF,
+    };
+    ReturnCode = XenHypercallSchedOp (XEN_SCHEDOP_SHUTDOWN, &ShutdownOp);
+    ASSERT (ReturnCode == 0);
   }
 
   CpuDeadLoop ();
-- 
Anthony PERARD


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-11-11 15:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-11 15:27 [PATCH 0/3] OvmfXen: Fix machine shutdown in PVH guest Anthony PERARD
2022-11-11 15:27 ` [PATCH 1/3] OvmfPkg: Introduce runtime XenHypercallLib Anthony PERARD
2022-11-11 15:27 ` [PATCH 2/3] OvmfPkg/XenHypercallLib: Add SchedOp hypercall Anthony PERARD
2022-11-11 15:27 ` [PATCH 3/3] OvmfPkg/OvmfXen: Introduce Xen's ResetSystemLib, to use xen hypercall Anthony PERARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox