Skip to content

Commit 3d1cb6b

Browse files
Ping-Ke Shihsmb49
authored andcommitted
wifi: rtw89: fix potential race condition between napi_init and napi_enable
BugLink: https://bugs.launchpad.net/bugs/2025067 commit 4751566 upstream. A race condition can happen if netdev is registered, but NAPI isn't initialized yet, and meanwhile user space starts the netdev that will enable NAPI. Then, it hits BUG_ON(): kernel BUG at net/core/dev.c:6423! invalid opcode: 0000 [#1] PREEMPT SMP NOPTI CPU: 0 PID: 417 Comm: iwd Not tainted 6.2.7-slab-dirty #3 eb0f5a8a9d91 Hardware name: LENOVO 21DL/LNVNB161216, BIOS JPCN20WW(V1.06) 09/20/2022 RIP: 0010:napi_enable+0x3f/0x50 Code: 48 89 c2 48 83 e2 f6 f6 81 89 08 00 00 02 74 0d 48 83 ... RSP: 0018:ffffada1414f3548 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffa01425802080 RCX: 0000000000000000 RDX: 00000000000002ff RSI: ffffada14e50c614 RDI: ffffa01425808dc0 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000100 R12: ffffa01425808f58 R13: 0000000000000000 R14: ffffa01423498940 R15: 0000000000000001 FS: 00007f5577c0a740(0000) GS:ffffa0169fc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f5577a19972 CR3: 0000000125a7a000 CR4: 0000000000750ef0 PKRU: 55555554 Call Trace: <TASK> rtw89_pci_ops_start+0x1c/0x70 [rtw89_pci 6cbc75429515c181cbc386478d5cfb32ffc5a0f8] rtw89_core_start+0xbe/0x160 [rtw89_core fe07ecb874820b6d778370d4acb6ef8a37847f22] rtw89_ops_start+0x26/0x40 [rtw89_core fe07ecb874820b6d778370d4acb6ef8a37847f22] drv_start+0x42/0x100 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] ieee80211_do_open+0x311/0x7d0 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] ieee80211_open+0x6a/0x90 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] __dev_open+0xe0/0x180 __dev_change_flags+0x1da/0x250 dev_change_flags+0x26/0x70 do_setlink+0x37c/0x12c0 ? ep_poll_callback+0x246/0x290 ? __nla_validate_parse+0x61/0xd00 ? __wake_up_common_lock+0x8f/0xd0 To fix this, follow Jonas' suggestion to switch the order of these functions and move register netdev to be the last step of PCI probe. Also, correct the error handling of rtw89_core_register_hw(). Fixes: e3ec701 ("rtw89: add Realtek 802.11ax driver") Cc: [email protected] Reported-by: Hyeonggon Yoo <[email protected]> Link: https://lore.kernel.org/linux-wireless/CAOiHx=n7EwK2B9CnBR07FVA=sEzFagb8TkS4XC_qBNq8OwcYUg@mail.gmail.com/T/#t Suggested-by: Jonas Gorski <[email protected]> Tested-by: Larry Finger<[email protected]> Reviewed-by: Larry Finger<[email protected]> Signed-off-by: Ping-Ke Shih <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Kamal Mostafa <[email protected]> Signed-off-by: Stefan Bader <[email protected]>
1 parent c6a7be6 commit 3d1cb6b

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

drivers/net/wireless/realtek/rtw89/core.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,18 +3374,22 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
33743374
ret = ieee80211_register_hw(hw);
33753375
if (ret) {
33763376
rtw89_err(rtwdev, "failed to register hw\n");
3377-
goto err;
3377+
goto err_free_supported_band;
33783378
}
33793379

33803380
ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier);
33813381
if (ret) {
33823382
rtw89_err(rtwdev, "failed to init regd\n");
3383-
goto err;
3383+
goto err_unregister_hw;
33843384
}
33853385

33863386
return 0;
33873387

3388-
err:
3388+
err_unregister_hw:
3389+
ieee80211_unregister_hw(hw);
3390+
err_free_supported_band:
3391+
rtw89_core_clr_supported_band(rtwdev);
3392+
33893393
return ret;
33903394
}
33913395

drivers/net/wireless/realtek/rtw89/pci.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3874,25 +3874,26 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
38743874
rtw89_pci_link_cfg(rtwdev);
38753875
rtw89_pci_l1ss_cfg(rtwdev);
38763876

3877-
ret = rtw89_core_register(rtwdev);
3878-
if (ret) {
3879-
rtw89_err(rtwdev, "failed to register core\n");
3880-
goto err_clear_resource;
3881-
}
3882-
38833877
rtw89_core_napi_init(rtwdev);
38843878

38853879
ret = rtw89_pci_request_irq(rtwdev, pdev);
38863880
if (ret) {
38873881
rtw89_err(rtwdev, "failed to request pci irq\n");
3888-
goto err_unregister;
3882+
goto err_deinit_napi;
3883+
}
3884+
3885+
ret = rtw89_core_register(rtwdev);
3886+
if (ret) {
3887+
rtw89_err(rtwdev, "failed to register core\n");
3888+
goto err_free_irq;
38893889
}
38903890

38913891
return 0;
38923892

3893-
err_unregister:
3893+
err_free_irq:
3894+
rtw89_pci_free_irq(rtwdev, pdev);
3895+
err_deinit_napi:
38943896
rtw89_core_napi_deinit(rtwdev);
3895-
rtw89_core_unregister(rtwdev);
38963897
err_clear_resource:
38973898
rtw89_pci_clear_resource(rtwdev, pdev);
38983899
err_declaim_pci:

0 commit comments

Comments
 (0)