mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
iwlwifi: pcie: compare with number of IRQs requested for, not number of CPUs
[ Upstream commitab1068d686] When there are 16 or more logical CPUs, we request for `IWL_MAX_RX_HW_QUEUES` (16) IRQs only as we limit to that number of IRQs, but later on we compare the number of IRQs returned to nr_online_cpus+2 instead of max_irqs, the latter being what we actually asked for. This ends up setting num_rx_queues to 17 which causes lots of out-of-bounds array accesses later on. Compare to max_irqs instead, and also add an assertion in case num_rx_queues > IWM_MAX_RX_HW_QUEUES. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=199551 Fixes:2e5d4a8f61("iwlwifi: pcie: Add new configuration to enable MSIX") Signed-off-by: Hao Wei Tee <angelsl@in04.sg> Tested-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
4abab5dca7
commit
3ee6bd9411
@@ -1499,14 +1499,13 @@ static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
|
||||
struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int max_irqs, num_irqs, i, ret, nr_online_cpus;
|
||||
int max_irqs, num_irqs, i, ret;
|
||||
u16 pci_cmd;
|
||||
|
||||
if (!trans->cfg->mq_rx_supported)
|
||||
goto enable_msi;
|
||||
|
||||
nr_online_cpus = num_online_cpus();
|
||||
max_irqs = min_t(u32, nr_online_cpus + 2, IWL_MAX_RX_HW_QUEUES);
|
||||
max_irqs = min_t(u32, num_online_cpus() + 2, IWL_MAX_RX_HW_QUEUES);
|
||||
for (i = 0; i < max_irqs; i++)
|
||||
trans_pcie->msix_entries[i].entry = i;
|
||||
|
||||
@@ -1532,16 +1531,17 @@ static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
|
||||
* Two interrupts less: non rx causes shared with FBQ and RSS.
|
||||
* More than two interrupts: we will use fewer RSS queues.
|
||||
*/
|
||||
if (num_irqs <= nr_online_cpus) {
|
||||
if (num_irqs <= max_irqs - 2) {
|
||||
trans_pcie->trans->num_rx_queues = num_irqs + 1;
|
||||
trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX |
|
||||
IWL_SHARED_IRQ_FIRST_RSS;
|
||||
} else if (num_irqs == nr_online_cpus + 1) {
|
||||
} else if (num_irqs == max_irqs - 1) {
|
||||
trans_pcie->trans->num_rx_queues = num_irqs;
|
||||
trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX;
|
||||
} else {
|
||||
trans_pcie->trans->num_rx_queues = num_irqs - 1;
|
||||
}
|
||||
WARN_ON(trans_pcie->trans->num_rx_queues > IWL_MAX_RX_HW_QUEUES);
|
||||
|
||||
trans_pcie->alloc_vecs = num_irqs;
|
||||
trans_pcie->msix_enabled = true;
|
||||
|
||||
Reference in New Issue
Block a user