The Tx and Rx rings are accessed by both guest and hypervisor, allocate the rings using newly added VirtIo->AllocateSharedPages() and map it with BusMasterCommonBuffer so that it can be accessed by both guest and hypervisor.
Cc: Ard Biesheuvel <[email protected]> Cc: Jordan Justen <[email protected]> Cc: Tom Lendacky <[email protected]> Cc: Laszlo Ersek <[email protected]> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Brijesh Singh <[email protected]> --- OvmfPkg/VirtioNetDxe/VirtioNet.h | 2 ++ OvmfPkg/VirtioNetDxe/Events.c | 7 +++++ OvmfPkg/VirtioNetDxe/SnpInitialize.c | 28 +++++++++++++++----- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h index 710859bc6115..2964c946e26e 100644 --- a/OvmfPkg/VirtioNetDxe/VirtioNet.h +++ b/OvmfPkg/VirtioNetDxe/VirtioNet.h @@ -82,10 +82,12 @@ typedef struct { EFI_HANDLE MacHandle; // VirtioNetDriverBindingStart VRING RxRing; // VirtioNetInitRing + VOID *RxRingMap; // VirtioNetInitRing UINT8 *RxBuf; // VirtioNetInitRx UINT16 RxLastUsed; // VirtioNetInitRx VRING TxRing; // VirtioNetInitRing + VOID *TxRingMap; // VirtioNetInitRing UINT16 TxMaxPending; // VirtioNetInitTx UINT16 TxCurPending; // VirtioNetInitTx UINT16 *TxFreeStack; // VirtioNetInitTx diff --git a/OvmfPkg/VirtioNetDxe/Events.c b/OvmfPkg/VirtioNetDxe/Events.c index 5be1af6ffbee..e832d40f7be4 100644 --- a/OvmfPkg/VirtioNetDxe/Events.c +++ b/OvmfPkg/VirtioNetDxe/Events.c @@ -88,4 +88,11 @@ VirtioNetExitBoot ( if (Dev->Snm.State == EfiSimpleNetworkInitialized) { Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0); } + + // + // Unmap Tx and Rx rings so that hypervisor can not get readable data + // after device is reset. + // + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxRingMap); + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxRingMap); } diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c index 0ecfe044a977..be2761d3d068 100644 --- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c +++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c @@ -35,6 +35,7 @@ the network device. @param[out] Ring The virtio-ring inside the VNET_DEV structure, corresponding to Selector. + @param[out] Mapping A token return from the Map. @retval EFI_UNSUPPORTED The queue size reported by the virtio-net device is too small. @@ -49,11 +50,13 @@ EFIAPI VirtioNetInitRing ( IN OUT VNET_DEV *Dev, IN UINT16 Selector, - OUT VRING *Ring + OUT VRING *Ring, + OUT VOID **Mapping ) { EFI_STATUS Status; UINT16 QueueSize; + UINT64 RingBaseShift; // // step 4b -- allocate selected queue @@ -79,30 +82,37 @@ VirtioNetInitRing ( return Status; } + Status = VirtioRingMap (Dev->VirtIo, Ring, &RingBaseShift, Mapping); + if (EFI_ERROR (Status)) { + goto ReleaseQueue; + } + // // Additional steps for MMIO: align the queue appropriately, and set the // size. If anything fails from here on, we must release the ring resources. // Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize); if (EFI_ERROR (Status)) { - goto ReleaseQueue; + goto UnmapQueue; } Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE); if (EFI_ERROR (Status)) { - goto ReleaseQueue; + goto UnmapQueue; } // // step 4c -- report GPFN (guest-physical frame number) of queue // - Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, 0); + Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, RingBaseShift); if (EFI_ERROR (Status)) { - goto ReleaseQueue; + goto UnmapQueue; } return EFI_SUCCESS; +UnmapQueue: + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping); ReleaseQueue: VirtioRingUninit (Dev->VirtIo, Ring); @@ -456,12 +466,14 @@ VirtioNetInitialize ( // // step 4b, 4c -- allocate and report virtqueues // - Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_RX, &Dev->RxRing); + Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_RX, &Dev->RxRing, + &Dev->RxRingMap); if (EFI_ERROR (Status)) { goto DeviceFailed; } - Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_TX, &Dev->TxRing); + Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_TX, &Dev->TxRing, + &Dev->TxRingMap); if (EFI_ERROR (Status)) { goto ReleaseRxRing; } @@ -510,9 +522,11 @@ AbortDevice: Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0); ReleaseTxRing: + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxRingMap); VirtioRingUninit (Dev->VirtIo, &Dev->TxRing); ReleaseRxRing: + Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxRingMap); VirtioRingUninit (Dev->VirtIo, &Dev->RxRing); DeviceFailed: -- 2.7.4 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

