aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-12-03 13:55:18 +0000
committerMichael Brown <mcb30@ipxe.org>2024-12-03 13:57:06 +0000
commit24db39fb2983ca83ab5c6ee37cb57a4f7f6f94e6 (patch)
tree26ff66dac071e30c39fb9a8bbfcd428c01d04fd0
parent5202f83345e17c56da4935205f0a97bd4aa20714 (diff)
downloadipxe-24db39fb2983ca83ab5c6ee37cb57a4f7f6f94e6.zip
ipxe-24db39fb2983ca83ab5c6ee37cb57a4f7f6f94e6.tar.gz
ipxe-24db39fb2983ca83ab5c6ee37cb57a4f7f6f94e6.tar.bz2
[gve] Run startup process only while device is opengve-startup-fix
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>
-rw-r--r--src/drivers/net/gve.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/drivers/net/gve.c b/src/drivers/net/gve.c
index df10a94..efc38dd 100644
--- a/src/drivers/net/gve.c
+++ b/src/drivers/net/gve.c
@@ -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 */