OvmfPkg/VirtioNetDxe: map caller-supplied Tx packet to device-address

When device is behind the IOMMU, driver is require to pass the device
address of caller-supplied transmit buffer for the bus master operations.

The patch uses VirtioNetMapTxBuf() to map caller-supplied Tx packet to a
device-address and enqueue the device address in VRING for transfer and
perform the reverse mapping when transfer is completed so that we can
return the caller-supplied buffer.

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:46 -05:00
committed by Laszlo Ersek
parent bd114d9f77
commit 8fa54a8a94
2 changed files with 49 additions and 13 deletions

View File

@@ -61,11 +61,12 @@ VirtioNetGetStatus (
OUT VOID **TxBuf OPTIONAL
)
{
VNET_DEV *Dev;
EFI_TPL OldTpl;
EFI_STATUS Status;
UINT16 RxCurUsed;
UINT16 TxCurUsed;
VNET_DEV *Dev;
EFI_TPL OldTpl;
EFI_STATUS Status;
UINT16 RxCurUsed;
UINT16 TxCurUsed;
EFI_PHYSICAL_ADDRESS DeviceAddress;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
@@ -141,14 +142,34 @@ VirtioNetGetStatus (
ASSERT (DescIdx < (UINT32) (2 * Dev->TxMaxPending - 1));
//
// report buffer address to caller that has been enqueued by caller
// get the device address that has been enqueued for the caller's
// transmit buffer
//
*TxBuf = (VOID *)(UINTN) Dev->TxRing.Desc[DescIdx + 1].Addr;
DeviceAddress = Dev->TxRing.Desc[DescIdx + 1].Addr;
//
// now this descriptor can be used again to enqueue a transmit buffer
//
Dev->TxFreeStack[--Dev->TxCurPending] = (UINT16) DescIdx;
//
// Unmap the device address and perform the reverse mapping to find the
// caller buffer address.
//
Status = VirtioNetUnmapTxBuf (
Dev,
TxBuf,
DeviceAddress
);
if (EFI_ERROR (Status)) {
//
// VirtioNetUnmapTxBuf should never fail, if we have reached here
// that means our internal state has been corrupted
//
ASSERT (FALSE);
Status = EFI_DEVICE_ERROR;
goto Exit;
}
}
}