scsi: qla2xxx: Fix NULL pointer dereference in target mode
authorGleb Chesnokov <gleb.chesnokov@scst.dev>
Wed, 17 May 2023 08:22:35 +0000 (11:22 +0300)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 22 May 2023 22:00:16 +0000 (18:00 -0400)
When target mode is enabled, the pci_irq_get_affinity() function may return
a NULL value in qla_mapq_init_qp_cpu_map() due to the qla24xx_enable_msix()
code that handles IRQ settings for target mode. This leads to a crash due
to a NULL pointer dereference.

This patch fixes the issue by adding a check for the NULL value returned by
pci_irq_get_affinity() and introducing a 'cpu_mapped' boolean flag to the
qla_qpair structure, ensuring that the qpair's CPU affinity is updated when
it has not been mapped to a CPU.

Fixes: 1d201c81d4cc ("scsi: qla2xxx: Select qpair depending on which CPU post_cmd() gets called")
Signed-off-by: Gleb Chesnokov <gleb.chesnokov@scst.dev>
Link: https://lore.kernel.org/r/56b416f2-4e0f-b6cf-d6d5-b7c372e3c6a2@scst.dev
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_isr.c

index df5e5b7fdcfe73accb080e412f43372c44974cbe..84aa3571be6d4de1f8e7cf7e2e0a011a6c4b6fd1 100644 (file)
@@ -3796,6 +3796,7 @@ struct qla_qpair {
        uint64_t retry_term_jiff;
        struct qla_tgt_counters tgt_counters;
        uint16_t cpuid;
+       bool cpu_mapped;
        struct qla_fw_resources fwres ____cacheline_aligned;
        struct  qla_buf_pool buf_pool;
        u32     cmd_cnt;
index ec0423ec66817c1a54ea00d508aeaccc02def258..1a955c3ff3d6ce2732e3fd03e65203a5162dbc9a 100644 (file)
@@ -9426,6 +9426,9 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
                qpair->rsp->req = qpair->req;
                qpair->rsp->qpair = qpair;
 
+               if (!qpair->cpu_mapped)
+                       qla_cpu_update(qpair, raw_smp_processor_id());
+
                if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
                        if (ha->fw_attributes & BIT_4)
                                qpair->difdix_supported = 1;
index cce6e425c1214a9aabaf9fe2677ba1ef0419cdb9..7b42558a8839ad51e0b92ede49c89656a16b03f7 100644 (file)
@@ -539,11 +539,14 @@ qla_mapq_init_qp_cpu_map(struct qla_hw_data *ha,
        if (!ha->qp_cpu_map)
                return;
        mask = pci_irq_get_affinity(ha->pdev, msix->vector_base0);
+       if (!mask)
+               return;
        qpair->cpuid = cpumask_first(mask);
        for_each_cpu(cpu, mask) {
                ha->qp_cpu_map[cpu] = qpair;
        }
        msix->cpuid = qpair->cpuid;
+       qpair->cpu_mapped = true;
 }
 
 static inline void
index 71feda2cdb63046a713c5018ae64948abed1084f..245e3a5d81fd33b3040df3000712d5d961ec9d6e 100644 (file)
@@ -3770,6 +3770,9 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 
        if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) {
                rsp->qpair->rcv_intr = 1;
+
+               if (!rsp->qpair->cpu_mapped)
+                       qla_cpu_update(rsp->qpair, raw_smp_processor_id());
        }
 
 #define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in)                 \