@@ -309,6 +309,8 @@ XenPvBlockFrontInitialization (
Dev->MediaInfo.Sectors, Dev->MediaInfo.SectorSize));
*DevPtr = Dev;
+
+ XenBusIo->RegisterExitCallback (XenBusIo, XenPvBlockFrontReset, Dev);
return EFI_SUCCESS;
Error2:
@@ -326,13 +328,16 @@ XenPvBlockFrontInitialization (
VOID
XenPvBlockFrontShutdown (
- IN XEN_BLOCK_FRONT_DEVICE *Dev
+ IN XEN_BLOCK_FRONT_DEVICE *Dev,
+ IN BOOLEAN ResetOnly
)
{
XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
XENSTORE_STATUS Status;
UINT64 Value;
+ XenBusIo->RegisterExitCallback (XenBusIo, NULL, NULL);
+
XenPvBlockSync (Dev);
Status = XenBusIo->SetState (XenBusIo, XST_NIL, XenbusStateClosing);
@@ -393,12 +398,38 @@ XenPvBlockFrontShutdown (
}
Close:
- XenBusIo->UnregisterWatch (XenBusIo, Dev->StateWatchToken);
+ if (!ResetOnly) {
+ XenBusIo->UnregisterWatch (XenBusIo, Dev->StateWatchToken);
+ }
XenBusIo->XsRemove (XenBusIo, XST_NIL, "ring-ref");
XenBusIo->XsRemove (XenBusIo, XST_NIL, "event-channel");
XenBusIo->XsRemove (XenBusIo, XST_NIL, "protocol");
- XenPvBlockFree (Dev);
+ if (ResetOnly) {
+ XenBusIo->GrantEndAccess (XenBusIo, Dev->RingRef);
+ XenBusIo->EventChannelClose (XenBusIo, Dev->EventChannel);
+ } else {
+ XenPvBlockFree (Dev);
+ }
+}
+
+/**
+ To be called when ExitBootServices has been called.
+
+ This should reset the PV backend without using memory allocation
+ services.
+**/
+VOID
+EFIAPI
+XenPvBlockFrontReset (
+ IN VOID *Context
+ )
+{
+ XEN_BLOCK_FRONT_DEVICE *Dev;
+
+ Dev = Context;
+
+ XenPvBlockFrontShutdown (Dev, TRUE);
}
STATIC
@@ -67,9 +67,19 @@ XenPvBlockFrontInitialization (
OUT XEN_BLOCK_FRONT_DEVICE **DevPtr
);
+/**
+ @param ResetOnly Set to TRUE when called during the ExitBootServices.
+**/
VOID
XenPvBlockFrontShutdown (
- IN XEN_BLOCK_FRONT_DEVICE *Dev
+ IN XEN_BLOCK_FRONT_DEVICE *Dev,
+ IN BOOLEAN ResetOnly
+ );
+
+VOID
+EFIAPI
+XenPvBlockFrontReset (
+ IN VOID *Context
);
VOID
@@ -312,7 +312,7 @@ XenPvBlkDxeDriverBindingStart (
UninitBlockFront:
FreePool (Media);
- XenPvBlockFrontShutdown (Dev);
+ XenPvBlockFrontShutdown (Dev, FALSE);
CloseProtocol:
gBS->CloseProtocol (ControllerHandle, &gXenBusProtocolGuid,
This->DriverBindingHandle, ControllerHandle);
@@ -377,7 +377,7 @@ XenPvBlkDxeDriverBindingStop (
Media = BlockIo->Media;
Dev = XEN_BLOCK_FRONT_FROM_BLOCK_IO (BlockIo);
- XenPvBlockFrontShutdown (Dev);
+ XenPvBlockFrontShutdown (Dev, FALSE);
FreePool (Media);
In order to be able to reset the backend before handing it to the next operating system, it should be reset properly. This patch register a callback function to be called by XenBusDxe during the ExitBootServices event. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2190 Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- OvmfPkg/XenPvBlkDxe/BlockFront.c | 37 ++++++++++++++++++++++++++++--- OvmfPkg/XenPvBlkDxe/BlockFront.h | 12 +++++++++- OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.c | 4 ++-- 3 files changed, 47 insertions(+), 6 deletions(-)