iwlwifi: don't panic in error path on non-msix systems
The driver uses msix causes-register to handle both msix and non msix interrupts when performing sync nmi. On devices that do not support msix this register is unmapped and accessing it causes a kernel panic. Solve this by differentiating the two cases and accessing the proper causes-register in each case. Reported-by: Michal Hocko <mhocko@kernel.org> Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:

committed by
Luca Coelho

parent
614c70f35c
commit
1c6bca6d75
@@ -3644,20 +3644,27 @@ out_no_pci:
|
|||||||
|
|
||||||
void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
|
void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
|
unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
|
||||||
|
u32 inta_addr, sw_err_bit;
|
||||||
|
|
||||||
|
if (trans_pcie->msix_enabled) {
|
||||||
|
inta_addr = CSR_MSIX_HW_INT_CAUSES_AD;
|
||||||
|
sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
|
||||||
|
} else {
|
||||||
|
inta_addr = CSR_INT;
|
||||||
|
sw_err_bit = CSR_INT_BIT_SW_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
iwl_disable_interrupts(trans);
|
iwl_disable_interrupts(trans);
|
||||||
iwl_force_nmi(trans);
|
iwl_force_nmi(trans);
|
||||||
while (time_after(timeout, jiffies)) {
|
while (time_after(timeout, jiffies)) {
|
||||||
u32 inta_hw = iwl_read32(trans,
|
u32 inta_hw = iwl_read32(trans, inta_addr);
|
||||||
CSR_MSIX_HW_INT_CAUSES_AD);
|
|
||||||
|
|
||||||
/* Error detected by uCode */
|
/* Error detected by uCode */
|
||||||
if (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) {
|
if (inta_hw & sw_err_bit) {
|
||||||
/* Clear causes register */
|
/* Clear causes register */
|
||||||
iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD,
|
iwl_write32(trans, inta_addr, inta_hw & sw_err_bit);
|
||||||
inta_hw &
|
|
||||||
MSIX_HW_INT_CAUSES_REG_SW_ERR);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user