git: e0e12405285b - main - netmap: fix LOR in iflib_netmap_register

From: Vincenzo Maffione <vmaffione_at_FreeBSD.org>
Date: Fri, 14 Jan 2022 21:09:11 UTC
The branch main has been updated by vmaffione:

URL: https://cgit.FreeBSD.org/src/commit/?id=e0e12405285b61a724c646b8f8e99e3ec775291e

commit e0e12405285b61a724c646b8f8e99e3ec775291e
Author:     Vincenzo Maffione <vmaffione@FreeBSD.org>
AuthorDate: 2022-01-14 21:09:04 +0000
Commit:     Vincenzo Maffione <vmaffione@FreeBSD.org>
CommitDate: 2022-01-14 21:09:04 +0000

    netmap: fix LOR in iflib_netmap_register
    
    In iflib_device_register(), the CTX_LOCK is acquired first and then
    IFNET_WLOCK is acquired by ether_ifattach(). However, in netmap_hw_reg()
    we do the opposite: IFNET_RLOCK is acquired first, and then CTX_LOCK
    is acquired by iflib_netmap_register(). Fix this LOR issue by wrapping
    the CTX_LOCK/UNLOCK calls in iflib_device_register with an additional
    IFNET_WLOCK. This is safe since the IFNET_WLOCK is recursive.
    
    MFC after:      1 month
---
 sys/net/iflib.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 3fcab699f9e0..88027a6dc283 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -5057,6 +5057,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
 	ifp = ctx->ifc_ifp;
 
 	iflib_reset_qvalues(ctx);
+	IFNET_WLOCK();
 	CTX_LOCK(ctx);
 	if ((err = IFDI_ATTACH_PRE(ctx)) != 0) {
 		device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err);
@@ -5250,6 +5251,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
 	iflib_add_pfil(ctx);
 	ctx->ifc_flags |= IFC_INIT_DONE;
 	CTX_UNLOCK(ctx);
+	IFNET_WUNLOCK();
 
 	return (0);
 
@@ -5265,6 +5267,7 @@ fail_intr_free:
 	iflib_free_intr_mem(ctx);
 fail_unlock:
 	CTX_UNLOCK(ctx);
+	IFNET_WUNLOCK();
 	iflib_deregister(ctx);
 fail_ctx_free:
 	device_set_softc(ctx->ifc_dev, NULL);