Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb647644 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Johannes Berg
Browse files

iwlwifi: protect use_ict with irq_lock



This variable was accessed without taking the lock.

Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent ae8baec2
Loading
Loading
Loading
Loading
+14 −16
Original line number Original line Diff line number Diff line
@@ -867,24 +867,23 @@ void iwl_disable_ict(struct iwl_trans *trans)
	spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
	spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
}
}


/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */
static irqreturn_t iwl_isr(int irq, void *data)
static irqreturn_t iwl_isr(int irq, void *data)
{
{
	struct iwl_trans *trans = data;
	struct iwl_trans *trans = data;
	struct iwl_trans_pcie *trans_pcie;
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	u32 inta, inta_mask;
	u32 inta, inta_mask;
	unsigned long flags;
#ifdef CONFIG_IWLWIFI_DEBUG
#ifdef CONFIG_IWLWIFI_DEBUG
	u32 inta_fh;
	u32 inta_fh;
#endif
#endif

	lockdep_assert_held(&trans_pcie->irq_lock);

	if (!trans)
	if (!trans)
		return IRQ_NONE;
		return IRQ_NONE;


	trace_iwlwifi_dev_irq(trans->dev);
	trace_iwlwifi_dev_irq(trans->dev);


	trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

	spin_lock_irqsave(&trans_pcie->irq_lock, flags);

	/* Disable (but don't clear!) interrupts here to avoid
	/* Disable (but don't clear!) interrupts here to avoid
	 *    back-to-back ISRs and sporadic interrupts from our NIC.
	 *    back-to-back ISRs and sporadic interrupts from our NIC.
	 * If we have something to service, the tasklet will re-enable ints.
	 * If we have something to service, the tasklet will re-enable ints.
@@ -907,7 +906,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
		/* Hardware disappeared. It might have already raised
		/* Hardware disappeared. It might have already raised
		 * an interrupt */
		 * an interrupt */
		IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
		IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
		goto unplugged;
		return IRQ_HANDLED;
	}
	}


#ifdef CONFIG_IWLWIFI_DEBUG
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -926,10 +925,6 @@ static irqreturn_t iwl_isr(int irq, void *data)
		 !trans_pcie->inta)
		 !trans_pcie->inta)
		iwl_enable_interrupts(trans);
		iwl_enable_interrupts(trans);


 unplugged:
	spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
	return IRQ_HANDLED;

none:
none:
	/* re-enable interrupts here since we don't have anything to service. */
	/* re-enable interrupts here since we don't have anything to service. */
	/* only Re-enable if disabled by irq  and no schedules tasklet. */
	/* only Re-enable if disabled by irq  and no schedules tasklet. */
@@ -937,7 +932,6 @@ static irqreturn_t iwl_isr(int irq, void *data)
	    !trans_pcie->inta)
	    !trans_pcie->inta)
		iwl_enable_interrupts(trans);
		iwl_enable_interrupts(trans);


	spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
	return IRQ_NONE;
	return IRQ_NONE;
}
}


@@ -963,15 +957,19 @@ irqreturn_t iwl_isr_ict(int irq, void *data)


	trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);


	spin_lock_irqsave(&trans_pcie->irq_lock, flags);

	/* dram interrupt table not set yet,
	/* dram interrupt table not set yet,
	 * use legacy interrupt.
	 * use legacy interrupt.
	 */
	 */
	if (!trans_pcie->use_ict)
	if (unlikely(!trans_pcie->use_ict)) {
		return iwl_isr(irq, data);
		irqreturn_t ret = iwl_isr(irq, data);
		spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
		return ret;
	}


	trace_iwlwifi_dev_irq(trans->dev);
	trace_iwlwifi_dev_irq(trans->dev);


	spin_lock_irqsave(&trans_pcie->irq_lock, flags);


	/* Disable (but don't clear!) interrupts here to avoid
	/* Disable (but don't clear!) interrupts here to avoid
	 * back-to-back ISRs and sporadic interrupts from our NIC.
	 * back-to-back ISRs and sporadic interrupts from our NIC.