]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[gve] Run startup process only while device is open 1354/head
authorMichael Brown <mcb30@ipxe.org>
Tue, 3 Dec 2024 13:55:18 +0000 (13:55 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 3 Dec 2024 13:57:06 +0000 (13:57 +0000)
The startup process is scheduled to run when the device is opened and
terminated (if still running) when the device is closed.  It assumes
that the resource allocation performed in gve_open() has taken place,
and that the admin and transmit/receive data structure pointers are
therefore valid.

The process initialisation in gve_probe() erroneously calls
process_init() rather than process_init_stopped() and will therefore
schedule the startup process immediately, before the relevant
resources have been allocated.

This bug is masked in the typical use case of a Google Cloud instance
with a single NIC built with the config/cloud/gce.ipxe embedded
script, since the embedded script will immediately open the NIC (and
therefore allocate the required resources) before the scheduled
process is allowed to run for the first time.  In a multi-NIC
instance, undefined behaviour will arise as soon as the startup
process for the second NIC is allowed to run.

Fix by using process_init_stopped() to avoid implicitly scheduling the
startup process during gve_probe().

Originally-fixed-by: Kal Cutter Conley <kalcutterc@nvidia.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/gve.c

index df10a94c64f2782971a45d1a79315710ae331359..efc38dd21daf67cd6f9b3f1d76a8e7b397ec69cb 100644 (file)
@@ -1543,7 +1543,8 @@ static int gve_probe ( struct pci_device *pci ) {
        gve->netdev = netdev;
        gve->tx.type = &gve_tx_type;
        gve->rx.type = &gve_rx_type;
-       process_init ( &gve->startup, &gve_startup_desc, &netdev->refcnt );
+       process_init_stopped ( &gve->startup, &gve_startup_desc,
+                              &netdev->refcnt );
        timer_init ( &gve->watchdog, gve_watchdog, &netdev->refcnt );
 
        /* Fix up PCI device */