From: Mark Asselstine <asselsm@xxxxxxxxx> In iwl_pcie_tx_alloc() we only allocate 'num_of_queues' queues to iwl_trans_pcie.txq[] yet queue_info[] always has IWL_MAX_HW_QUEUES (ie. 32) entries. This gives us a range of queues from 0 to 31, however, on some devices we have a num_of_queues of 31 or even 20, thus a range of 0 to num_of_queues - 1 (or 0 - 30 on 8000 series devices). We need to therefor make some of the entries in queue_info[] unavailable to functions like iwl_mvm_find_free_queue() which otherwise will return invalid queue indexes. Without this we get the following Oops: kernel: BUG: kernel NULL pointer dereference, address: 00000000000000d8 kernel: #PF: supervisor write access in kernel mode kernel: #PF: error_code(0x0002) - not-present page kernel: PGD 0 P4D 0 kernel: Oops: 0002 [#1] SMP PTI kernel: CPU: 0 PID: 2086 Comm: kworker/0:0 Not tainted 5.6.0-0.rc4.git0.1.fc33.x86_64+debug #1 kernel: Hardware name: LENOVO 10A8S08P00/SHARKBAY, BIOS FBKTDBAUS 12/24/2019 kernel: Workqueue: events iwl_mvm_add_new_dqa_stream_wk [iwlmvm] kernel: RIP: 0010:iwl_trans_pcie_txq_enable+0x4d/0x460 [iwlwifi] kernel: Code: bc c7 80 19 00 00 66 89 14 24 f0 48 0f ab 87 80 29 00 00 73 0d 80 3d af 37 04 00 00 0f 84 c6 03 00 00 44 89 c7 e8 03 42 b0 d0 <49> 89 87 d8 00 00 00 4d 85 f6 0f 84 d1 02 00 00 41 0f b6 06 89 44 kernel: RSP: 0018:ffffac44c081fd08 EFLAGS: 00010202 kernel: RAX: 0000000000002710 RBX: 0000000000000000 RCX: 0000000000000000 kernel: RDX: 3ffffffffffffffe RSI: 000000000000001f RDI: 0000000000002710 kernel: RBP: ffff8ee008040028 R08: 0000000000002710 R09: 0000000000000001 kernel: R10: 0000000000000000 R11: 0000000000000000 R12: 000000000000001f kernel: R13: ffff8ee00567b3e8 R14: 0000000000000000 R15: 0000000000000000 kernel: FS: 0000000000000000(0000) GS:ffff8ee00e800000(0000) knlGS:0000000000000000 kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 kernel: CR2: 00000000000000d8 CR3: 0000000040612003 CR4: 00000000001606f0 kernel: Call Trace: kernel: iwl_mvm_enable_txq+0x1d8/0x2b0 [iwlmvm] kernel: iwl_mvm_add_new_dqa_stream_wk+0x203/0x910 [iwlmvm] kernel: process_one_work+0x25d/0x570 kernel: worker_thread+0x55/0x3d0 kernel: ? process_one_work+0x570/0x570 kernel: kthread+0x120/0x140 kernel: ? __kthread_bind_mask+0x60/0x60 kernel: ret_from_fork+0x3a/0x50 which logging shows happens when a queue index of 31 (txq_id) is used for trans_pcie->txq[txq_id]. Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=206765 Reported-by: Gabriel Ramirez <gabriello.ramirez@xxxxxxxxx> Signed-off-by: Mark Asselstine <asselsm@xxxxxxxxx> --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 54c094e88474..bb6234b13014 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -310,7 +310,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, struct iwl_notification_wait alive_wait; struct iwl_mvm_alive_data alive_data = {}; const struct fw_img *fw; - int ret; + int i, ret; enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img; static const u16 alive_cmd[] = { MVM_ALIVE }; bool run_in_rfkill = @@ -413,6 +413,16 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].tid_bitmap = BIT(IWL_MAX_TID_COUNT + 2); + /* + * Similarly prevent use of non-existing queues. The range + * is from 0 - (num_of_queues-1) or 0 - (IWL_MAX_HW_QUEUES-1) + * whichever is smaller. So we need to disable any queues + * from num_of_queues to IWL_MAX_HW_QUEUES. + */ + for (i = mvm->trans->trans_cfg->base_params->num_of_queues; + i < IWL_MAX_HW_QUEUES; i++) + mvm->queue_info[i].tid_bitmap = BIT(IWL_MAX_TID_COUNT + 2); + set_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); #ifdef CONFIG_IWLWIFI_DEBUGFS iwl_fw_set_dbg_rec_on(&mvm->fwrt); -- 2.20.1