summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OvmfPkg/VirtioBlkDxe/VirtioBlk.c44
-rw-r--r--OvmfPkg/VirtioBlkDxe/VirtioBlk.h1
2 files changed, 44 insertions, 1 deletions
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 862957ce04..75f85ca6e0 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -843,6 +843,37 @@ VirtioBlkUninit (
/**
+ Event notification function enqueued by ExitBootServices().
+
+ @param[in] Event Event whose notification function is being invoked.
+
+ @param[in] Context Pointer to the VBLK_DEV structure.
+
+**/
+
+STATIC
+VOID
+EFIAPI
+VirtioBlkExitBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ VBLK_DEV *Dev;
+
+ //
+ // Reset the device. This causes the hypervisor to forget about the virtio
+ // ring.
+ //
+ // We allocated said ring in EfiBootServicesData type memory, and code
+ // executing after ExitBootServices() is permitted to overwrite it.
+ //
+ Dev = Context;
+ Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
+}
+
+/**
+
After we've pronounced support for a specific device in
DriverBindingSupported(), we start managing said device (passed in by the
Driver Exeuction Environment) with the following service.
@@ -901,6 +932,12 @@ VirtioBlkDriverBindingStart (
goto CloseVirtIo;
}
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
+ &VirtioBlkExitBoot, Dev, &Dev->ExitBoot);
+ if (EFI_ERROR (Status)) {
+ goto UninitDev;
+ }
+
//
// Setup complete, attempt to export the driver instance's BlockIo interface.
//
@@ -909,11 +946,14 @@ VirtioBlkDriverBindingStart (
&gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,
&Dev->BlockIo);
if (EFI_ERROR (Status)) {
- goto UninitDev;
+ goto CloseExitBoot;
}
return EFI_SUCCESS;
+CloseExitBoot:
+ gBS->CloseEvent (Dev->ExitBoot);
+
UninitDev:
VirtioBlkUninit (Dev);
@@ -987,6 +1027,8 @@ VirtioBlkDriverBindingStop (
return Status;
}
+ gBS->CloseEvent (Dev->ExitBoot);
+
VirtioBlkUninit (Dev);
gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.h b/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
index 789caf9a37..ca4b7a0ca6 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
@@ -37,6 +37,7 @@ typedef struct {
// --------------------- ------------------ ---------
UINT32 Signature; // DriverBindingStart 0
VIRTIO_DEVICE_PROTOCOL *VirtIo; // DriverBindingStart 0
+ EFI_EVENT ExitBoot; // DriverBindingStart 0
VRING Ring; // VirtioRingInit 2
EFI_BLOCK_IO_PROTOCOL BlockIo; // VirtioBlkInit 1
EFI_BLOCK_IO_MEDIA BlockIoMedia; // VirtioBlkInit 1