Files
system76-edk2/OvmfPkg/VirtioNetDxe/Events.c
Laszlo Ersek 19c2a92805 OvmfPkg/VirtioNetDxe: fix SignalEvent() call
The SignalEvent() boot service takes an EFI_EVENT, not an (EFI_EVENT*).
Fix the call in the notification function of
"EFI_SIMPLE_NETWORK_PROTOCOL.WaitForPacket".

This is an actual bug. The reason it's never been triggered is likely that
the "SNP.WaitForPacket" event is rarely waited for by applications -- edk2
itself has zero instances of that, for example.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2019-10-09 09:40:10 +02:00

87 lines
2.1 KiB
C

/** @file
Implements
- the SNM.WaitForPacket EVT_NOTIFY_WAIT event,
- the EVT_SIGNAL_EXIT_BOOT_SERVICES event
for the virtio-net driver.
Copyright (C) 2013, Red Hat, Inc.
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "VirtioNet.h"
/**
Invoke a notification event
@param Event Event whose notification function is being
invoked.
@param Context The pointer to the notification function's
context, which is implementation-dependent.
**/
VOID
EFIAPI
VirtioNetIsPacketAvailable (
IN EFI_EVENT Event,
IN VOID *Context
)
{
//
// This callback has been enqueued by an external application and is
// running at TPL_CALLBACK already.
//
// The WaitForPacket logic is similar to that of WaitForKey. The former has
// almost no documentation in either the UEFI-2.3.1+errC spec or the
// DWG-2.3.1, but WaitForKey does have some.
//
VNET_DEV *Dev;
UINT16 RxCurUsed;
Dev = Context;
if (Dev->Snm.State != EfiSimpleNetworkInitialized) {
return;
}
//
// virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device
//
MemoryFence ();
RxCurUsed = *Dev->RxRing.Used.Idx;
MemoryFence ();
if (Dev->RxLastUsed != RxCurUsed) {
gBS->SignalEvent (Dev->Snp.WaitForPacket);
}
}
VOID
EFIAPI
VirtioNetExitBoot (
IN EFI_EVENT Event,
IN VOID *Context
)
{
//
// This callback has been enqueued by ExitBootServices() and is running at
// TPL_CALLBACK already.
//
// Shut down pending transfers according to DWG-2.3.1, "25.5.1 Exit Boot
// Services Event".
//
VNET_DEV *Dev;
DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));
Dev = Context;
if (Dev->Snm.State == EfiSimpleNetworkInitialized) {
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
}
}