diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Commands.c index 595a3717d9..db5bdbca4b 100644 --- a/OvmfPkg/VirtioGpuDxe/Commands.c +++ b/OvmfPkg/VirtioGpuDxe/Commands.c @@ -355,6 +355,27 @@ VirtioGpuExitBoot ( VgpuDev = Context; VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, 0); + + // + // If VirtioGpuDriverBindingStart() and VirtioGpuDriverBindingStop() have + // been called thus far in such a sequence that right now our (sole) child + // handle exists -- with the GOP on it standing for head (scanout) #0 --, + // then we have to unmap the current video mode's backing store. + // + if (VgpuDev->Child != NULL) { + // + // The current video mode is guaranteed to have a valid and mapped backing + // store, due to the first Gop.SetMode() call, made internally in + // InitVgpuGop(). + // + ASSERT (VgpuDev->Child->BackingStore != NULL); + + VgpuDev->VirtIo->UnmapSharedBuffer ( + VgpuDev->VirtIo, + VgpuDev->Child->BackingStoreMap + ); + } + VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, VgpuDev->RingMap); } diff --git a/OvmfPkg/VirtioGpuDxe/Gop.c b/OvmfPkg/VirtioGpuDxe/Gop.c index 507e1a770d..936e181e8a 100644 --- a/OvmfPkg/VirtioGpuDxe/Gop.c +++ b/OvmfPkg/VirtioGpuDxe/Gop.c @@ -114,11 +114,17 @@ ReleaseGopResources ( } // - // Release backing pages. + // Unmap and release backing pages. // - FreePages (VgpuGop->BackingStore, VgpuGop->NumberOfPages); + VirtioGpuUnmapAndFreeBackingStore ( + VgpuGop->ParentBus, // VgpuDev + VgpuGop->NumberOfPages, // NumberOfPages + VgpuGop->BackingStore, // HostAddress + VgpuGop->BackingStoreMap // Mapping + ); VgpuGop->BackingStore = NULL; VgpuGop->NumberOfPages = 0; + VgpuGop->BackingStoreMap = NULL; // // Destroy the currently used 2D host resource. @@ -230,11 +236,14 @@ GopSetMode ( IN UINT32 ModeNumber ) { - VGPU_GOP *VgpuGop; - UINT32 NewResourceId; - UINTN NewNumberOfBytes; - UINTN NewNumberOfPages; - VOID *NewBackingStore; + VGPU_GOP *VgpuGop; + UINT32 NewResourceId; + UINTN NewNumberOfBytes; + UINTN NewNumberOfPages; + VOID *NewBackingStore; + EFI_PHYSICAL_ADDRESS NewBackingStoreDeviceAddress; + VOID *NewBackingStoreMap; + EFI_STATUS Status; EFI_STATUS Status2; @@ -293,20 +302,22 @@ GopSetMode ( } // - // Allocate guest backing store. + // Allocate, zero and map guest backing store, for bus master common buffer + // operation. // NewNumberOfBytes = mGopResolutions[ModeNumber].Width * mGopResolutions[ModeNumber].Height * sizeof (UINT32); NewNumberOfPages = EFI_SIZE_TO_PAGES (NewNumberOfBytes); - NewBackingStore = AllocatePages (NewNumberOfPages); - if (NewBackingStore == NULL) { - Status = EFI_OUT_OF_RESOURCES; + Status = VirtioGpuAllocateZeroAndMapBackingStore ( + VgpuGop->ParentBus, // VgpuDev + NewNumberOfPages, // NumberOfPages + &NewBackingStore, // HostAddress + &NewBackingStoreDeviceAddress, // DeviceAddress + &NewBackingStoreMap // Mapping + ); + if (EFI_ERROR (Status)) { goto DestroyHostResource; } - // - // Fill visible part of backing store with black. - // - ZeroMem (NewBackingStore, NewNumberOfBytes); // // Attach backing store to the host resource. @@ -314,11 +325,11 @@ GopSetMode ( Status = VirtioGpuResourceAttachBacking ( VgpuGop->ParentBus, // VgpuDev NewResourceId, // ResourceId - (UINTN)NewBackingStore, // BackingStoreDeviceAddress + NewBackingStoreDeviceAddress, // BackingStoreDeviceAddress NewNumberOfPages // NumberOfPages ); if (EFI_ERROR (Status)) { - goto FreeBackingStore; + goto UnmapAndFreeBackingStore; } // @@ -391,6 +402,7 @@ GopSetMode ( VgpuGop->ResourceId = NewResourceId; VgpuGop->BackingStore = NewBackingStore; VgpuGop->NumberOfPages = NewNumberOfPages; + VgpuGop->BackingStoreMap = NewBackingStoreMap; // // Populate Mode and ModeInfo (mutable fields only). @@ -409,8 +421,13 @@ DetachBackingStore: CpuDeadLoop (); } -FreeBackingStore: - FreePages (NewBackingStore, NewNumberOfPages); +UnmapAndFreeBackingStore: + VirtioGpuUnmapAndFreeBackingStore ( + VgpuGop->ParentBus, // VgpuDev + NewNumberOfPages, // NumberOfPages + NewBackingStore, // HostAddress + NewBackingStoreMap // Mapping + ); DestroyHostResource: Status2 = VirtioGpuResourceUnref (VgpuGop->ParentBus, NewResourceId); diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h index 65b1bd6088..73893ccb56 100644 --- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h +++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h @@ -150,6 +150,13 @@ struct VGPU_GOP_STRUCT { // UINT32 *BackingStore; UINTN NumberOfPages; + + // + // Token associated with BackingStore's mapping for bus master common + // buffer operation. BackingStoreMap is valid if, and only if, + // BackingStore is non-NULL. + // + VOID *BackingStoreMap; }; //