OvmfPkg/VirtioNetDxe: map VRINGs using VirtioRingMap()

When device is behind the IOMMU then driver need to pass the device
address when programing the bus master. The patch uses VirtioRingMap() to
map the VRING system physical address[es] to device address[es].

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
Brijesh Singh
2017-09-14 16:22:41 -05:00
committed by Laszlo Ersek
parent 55dd5a673b
commit 940baec09c
5 changed files with 58 additions and 20 deletions

View File

@@ -35,11 +35,13 @@
the network device.
@param[out] Ring The virtio-ring inside the VNET_DEV structure,
corresponding to Selector.
@param[out] Mapping A resulting token to pass to VirtioNetUninitRing()
@retval EFI_UNSUPPORTED The queue size reported by the virtio-net device is
too small.
@return Status codes from VIRTIO_CFG_WRITE(),
VIRTIO_CFG_READ() and VirtioRingInit().
VIRTIO_CFG_READ(), VirtioRingInit() and
VirtioRingMap().
@retval EFI_SUCCESS Ring initialized.
*/
@@ -49,11 +51,14 @@ 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;
VOID *MapInfo;
//
// step 4b -- allocate selected queue
@@ -80,29 +85,42 @@ VirtioNetInitRing (
}
//
// Additional steps for MMIO: align the queue appropriately, and set the
// size. If anything fails from here on, we must release the ring resources.
// If anything fails from here on, we must release the ring resources.
//
Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
Status = VirtioRingMap (Dev->VirtIo, Ring, &RingBaseShift, &MapInfo);
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 unmap the ring resources.
//
Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
if (EFI_ERROR (Status)) {
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;
}
*Mapping = MapInfo;
return EFI_SUCCESS;
UnmapQueue:
Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, MapInfo);
ReleaseQueue:
VirtioRingUninit (Dev->VirtIo, Ring);
@@ -456,12 +474,22 @@ 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,10 +538,10 @@ AbortDevice:
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
ReleaseTxRing:
VirtioNetUninitRing (Dev, &Dev->TxRing);
VirtioNetUninitRing (Dev, &Dev->TxRing, Dev->TxRingMap);
ReleaseRxRing:
VirtioNetUninitRing (Dev, &Dev->RxRing);
VirtioNetUninitRing (Dev, &Dev->RxRing, Dev->RxRingMap);
DeviceFailed:
//