From 7411f1875a6055abe16e72fa5fc1b731cbfc7d76 Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Wed, 10 Dec 2025 15:45:53 +0530 Subject: [PATCH 01/12] scsi: qla2xxx: Add Speed in SFP print information Print additional information about the speed while displaying SFP information. Signed-off-by: Himanshu Madhani Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-2-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d395cbfe6802..29dabcaada33 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4074,6 +4074,20 @@ static void qla2xxx_print_sfp_info(struct scsi_qla_host *vha) u8 str[STR_LEN], *ptr, p; int leftover, len; + ql_dbg(ql_dbg_init, vha, 0x015a, + "SFP: %.*s -> %.*s ->%s%s%s%s%s%s\n", + (int)sizeof(a0->vendor_name), a0->vendor_name, + (int)sizeof(a0->vendor_pn), a0->vendor_pn, + a0->fc_sp_cc10 & FC_SP_32 ? " 32G" : "", + a0->fc_sp_cc10 & FC_SP_16 ? " 16G" : "", + a0->fc_sp_cc10 & FC_SP_8 ? " 8G" : "", + a0->fc_sp_cc10 & FC_SP_4 ? " 4G" : "", + a0->fc_sp_cc10 & FC_SP_2 ? " 2G" : "", + a0->fc_sp_cc10 & FC_SP_1 ? " 1G" : ""); + + if (!(ql2xextended_error_logging & ql_dbg_verbose)) + return; + memset(str, 0, STR_LEN); snprintf(str, SFF_VEN_NAME_LEN+1, a0->vendor_name); ql_dbg(ql_dbg_init, vha, 0x015a, From 21ab087cae5000dd084dfb21d0a4d6086f79c445 Mon Sep 17 00:00:00 2001 From: Manish Rangankar Date: Wed, 10 Dec 2025 15:45:54 +0530 Subject: [PATCH 02/12] scsi: qla2xxx: Add support for 64G SFP speed Incorrect speed info is shown in driver logs for 64G SFP. Add support for 64G SFP speed as per SFF-8472 specification. Signed-off-by: Manish Rangankar Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-3-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 6 ++++-- drivers/scsi/qla2xxx/qla_init.c | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b3265952c4be..e44b51c5a3eb 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -5368,7 +5368,7 @@ struct edif_sa_index_entry { struct list_head next; }; -/* Refer to SNIA SFF 8247 */ +/* Refer to SNIA SFF 8472 */ struct sff_8247_a0 { u8 txid; /* transceiver id */ u8 ext_txid; @@ -5412,6 +5412,7 @@ struct sff_8247_a0 { #define FC_SP_32 BIT_3 #define FC_SP_2 BIT_2 #define FC_SP_1 BIT_0 +#define FC_SPEED_2 BIT_1 u8 fc_sp_cc10; u8 encode; u8 bitrate; @@ -5430,7 +5431,8 @@ struct sff_8247_a0 { u8 vendor_pn[SFF_PART_NAME_LEN]; /* part number */ u8 vendor_rev[4]; u8 wavelength[2]; - u8 resv; +#define FC_SP_64 BIT_0 + u8 fiber_channel_speed2; u8 cc_base; u8 options[2]; /* offset 64 */ u8 br_max; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 29dabcaada33..3aba4e86618f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4075,9 +4075,11 @@ static void qla2xxx_print_sfp_info(struct scsi_qla_host *vha) int leftover, len; ql_dbg(ql_dbg_init, vha, 0x015a, - "SFP: %.*s -> %.*s ->%s%s%s%s%s%s\n", + "SFP: %.*s -> %.*s ->%s%s%s%s%s%s%s\n", (int)sizeof(a0->vendor_name), a0->vendor_name, (int)sizeof(a0->vendor_pn), a0->vendor_pn, + a0->fc_sp_cc10 & FC_SP_2 ? a0->fiber_channel_speed2 & FC_SP_64 ? + " 64G" : "" : "", a0->fc_sp_cc10 & FC_SP_32 ? " 32G" : "", a0->fc_sp_cc10 & FC_SP_16 ? " 16G" : "", a0->fc_sp_cc10 & FC_SP_8 ? " 8G" : "", From b99b04b12214ff5e4a01575c3c6612ae79bc5e76 Mon Sep 17 00:00:00 2001 From: Manish Rangankar Date: Wed, 10 Dec 2025 15:45:55 +0530 Subject: [PATCH 03/12] scsi: qla2xxx: Add load flash firmware mailbox support for 28xxx For 28xxx adaptor Load flash firmware mailbox load the operational firmware from flash, and also validate the checksum. Driver does not need to load the operational firmware anymore, but it still need to read fwdt from flash to build and allocate firmware dump template. Remove request_firmware() support for 28xxx adapter. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202512031128.XsuvzBv1-lkp@intel.com/ Signed-off-by: Manish Rangankar Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-4-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_gbl.h | 3 + drivers/scsi/qla2xxx/qla_init.c | 188 +++++++++++++++++++++++++++++++- drivers/scsi/qla2xxx/qla_mbx.c | 48 ++++++++ 4 files changed, 236 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index e44b51c5a3eb..04bc69bb11b1 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1270,6 +1270,7 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs) */ #define MBC_LOAD_RAM 1 /* Load RAM. */ #define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware. */ +#define MBC_LOAD_FLASH_FIRMWARE 3 /* Load flash firmware. */ #define MBC_READ_RAM_WORD 5 /* Read RAM word. */ #define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */ #define MBC_VERIFY_CHECKSUM 7 /* Verify checksum. */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 55d531c19e6b..f12b2689163d 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -344,6 +344,9 @@ qla2x00_dump_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); extern int qla2x00_execute_fw(scsi_qla_host_t *, uint32_t); +extern int +qla28xx_load_flash_firmware(scsi_qla_host_t *vha); + extern int qla2x00_get_fw_version(scsi_qla_host_t *); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3aba4e86618f..5183ff813487 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -8458,6 +8458,148 @@ bool qla24xx_risc_firmware_invalid(uint32_t *dword) !(~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]); } +static int +qla28xx_get_srisc_addr(scsi_qla_host_t *vha, uint32_t *srisc_addr, + uint32_t faddr) +{ + struct qla_hw_data *ha = vha->hw; + struct req_que *req = ha->req_q_map[0]; + uint32_t *dcode; + int rval; + + *srisc_addr = 0; + dcode = (uint32_t *)req->ring; + + rval = qla24xx_read_flash_data(vha, dcode, faddr, 10); + if (rval) { + ql_log(ql_log_fatal, vha, 0x01aa, + "-> Failed to read flash addr + size .\n"); + return QLA_FUNCTION_FAILED; + } + + *srisc_addr = be32_to_cpu((__force __be32)dcode[2]); + return QLA_SUCCESS; +} + +static int +qla28xx_load_fw_template(scsi_qla_host_t *vha, uint32_t faddr) +{ + struct qla_hw_data *ha = vha->hw; + struct fwdt *fwdt = ha->fwdt; + struct req_que *req = ha->req_q_map[0]; + uint32_t risc_size, risc_attr = 0; + uint templates, segments, fragment; + uint32_t *dcode; + ulong dlen; + int rval; + uint j; + + dcode = (uint32_t *)req->ring; + segments = FA_RISC_CODE_SEGMENTS; + + for (j = 0; j < segments; j++) { + rval = qla24xx_read_flash_data(vha, dcode, faddr, 10); + if (rval) { + ql_log(ql_log_fatal, vha, 0x01a1, + "-> Failed to read flash addr + size .\n"); + return QLA_FUNCTION_FAILED; + } + + risc_size = be32_to_cpu((__force __be32)dcode[3]); + + if (risc_attr == 0) + risc_attr = be32_to_cpu((__force __be32)dcode[9]); + + dlen = ha->fw_transfer_size >> 2; + for (fragment = 0; fragment < risc_size; fragment++) { + if (dlen > risc_size) + dlen = risc_size; + + faddr += dlen; + risc_size -= dlen; + } + } + + templates = (risc_attr & BIT_9) ? 2 : 1; + + ql_dbg(ql_dbg_init, vha, 0x01a1, "-> templates = %u\n", templates); + + for (j = 0; j < templates; j++, fwdt++) { + vfree(fwdt->template); + fwdt->template = NULL; + fwdt->length = 0; + + dcode = (uint32_t *)req->ring; + + rval = qla24xx_read_flash_data(vha, dcode, faddr, 7); + if (rval) { + ql_log(ql_log_fatal, vha, 0x01a2, + "-> Unable to read template size.\n"); + goto failed; + } + + risc_size = be32_to_cpu((__force __be32)dcode[2]); + ql_dbg(ql_dbg_init, vha, 0x01a3, + "-> fwdt%u template array at %#x (%#x dwords)\n", + j, faddr, risc_size); + if (!risc_size || !~risc_size) { + ql_dbg(ql_dbg_init, vha, 0x01a4, + "-> fwdt%u failed to read array\n", j); + goto failed; + } + + /* skip header and ignore checksum */ + faddr += 7; + risc_size -= 8; + + ql_dbg(ql_dbg_init, vha, 0x01a5, + "-> fwdt%u template allocate template %#x words...\n", + j, risc_size); + fwdt->template = vmalloc(risc_size * sizeof(*dcode)); + if (!fwdt->template) { + ql_log(ql_log_warn, vha, 0x01a6, + "-> fwdt%u failed allocate template.\n", j); + goto failed; + } + + dcode = fwdt->template; + rval = qla24xx_read_flash_data(vha, dcode, faddr, risc_size); + + if (rval || !qla27xx_fwdt_template_valid(dcode)) { + ql_log(ql_log_warn, vha, 0x01a7, + "-> fwdt%u failed template validate (rval %x)\n", + j, rval); + goto failed; + } + + dlen = qla27xx_fwdt_template_size(dcode); + ql_dbg(ql_dbg_init, vha, 0x01a7, + "-> fwdt%u template size %#lx bytes (%#lx words)\n", + j, dlen, dlen / sizeof(*dcode)); + if (dlen > risc_size * sizeof(*dcode)) { + ql_log(ql_log_warn, vha, 0x01a8, + "-> fwdt%u template exceeds array (%-lu bytes)\n", + j, dlen - risc_size * sizeof(*dcode)); + goto failed; + } + + fwdt->length = dlen; + ql_dbg(ql_dbg_init, vha, 0x01a9, + "-> fwdt%u loaded template ok\n", j); + + faddr += risc_size + 1; + } + + return QLA_SUCCESS; + +failed: + vfree(fwdt->template); + fwdt->template = NULL; + fwdt->length = 0; + + return QLA_SUCCESS; +} + static int qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, uint32_t faddr) @@ -8897,16 +9039,18 @@ int qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) { int rval; + uint32_t f_region = 0; struct qla_hw_data *ha = vha->hw; struct active_regions active_regions = { }; - if (ql2xfwloadbin == 2) + if (ql2xfwloadbin == 2 && !IS_QLA28XX(ha)) goto try_blob_fw; /* FW Load priority: - * 1) Firmware residing in flash. - * 2) Firmware via request-firmware interface (.bin file). - * 3) Golden-Firmware residing in flash -- (limited operation). + * 1) If 28xxx, ROM cmd to load flash firmware. + * 2) Firmware residing in flash. + * 3) Firmware via request-firmware interface (.bin file). + * 4) Golden-Firmware residing in flash -- (limited operation). */ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) @@ -8914,6 +9058,40 @@ qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) qla27xx_get_active_image(vha, &active_regions); + /* For 28XXX, always load the flash firmware using rom mbx */ + if (IS_QLA28XX(ha)) { + rval = qla28xx_load_flash_firmware(vha); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_fatal, vha, 0x019e, + "Failed to load flash firmware.\n"); + goto exit_load_risc; + } + + f_region = + (active_regions.global != QLA27XX_SECONDARY_IMAGE) ? + ha->flt_region_fw : ha->flt_region_fw_sec; + + ql_log(ql_log_info, vha, 0x019f, + "Load flash firmware successful (%s).\n", + ((active_regions.global != QLA27XX_SECONDARY_IMAGE) ? + "Primary" : "Secondary")); + + rval = qla28xx_get_srisc_addr(vha, srisc_addr, f_region); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x019f, + "failed to read srisc address\n"); + goto exit_load_risc; + } + + rval = qla28xx_load_fw_template(vha, f_region); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x01a0, + "failed to read firmware template\n"); + } + + goto exit_load_risc; + } + if (active_regions.global != QLA27XX_SECONDARY_IMAGE) goto try_primary_fw; @@ -8943,6 +9121,8 @@ try_blob_fw: ql_log(ql_log_info, vha, 0x009a, "Need firmware flash update.\n"); ha->flags.running_gold_fw = 1; + +exit_load_risc: return rval; } diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 1f01576f044b..28bb645ace67 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -43,6 +43,7 @@ static struct rom_cmd { } rom_cmds[] = { { MBC_LOAD_RAM }, { MBC_EXECUTE_FIRMWARE }, + { MBC_LOAD_FLASH_FIRMWARE }, { MBC_READ_RAM_WORD }, { MBC_MAILBOX_REGISTER_TEST }, { MBC_VERIFY_CHECKSUM }, @@ -824,6 +825,53 @@ done: return rval; } +/* + * qla2x00_load_flash_firmware + * Load firmware from flash. + * + * Input: + * vha = adapter block pointer. + * + * Returns: + * qla28xx local function return status code. + * + * Context: + * Kernel context. + */ +int +qla28xx_load_flash_firmware(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + int rval = QLA_COMMAND_ERROR; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + + if (!IS_QLA28XX(ha)) + return rval; + + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a6, + "Entered %s.\n", __func__); + + mcp->mb[0] = MBC_LOAD_FLASH_FIRMWARE; + mcp->out_mb = MBX_2 | MBX_1 | MBX_0; + mcp->in_mb = MBX_0; + mcp->tov = MBX_TOV_SECONDS; + mcp->flags = 0; + rval = qla2x00_mailbox_command(vha, mcp); + + if (rval != QLA_SUCCESS) { + ql_dbg(ql_log_info, vha, 0x11a7, + "Failed=%x cmd error=%x img error=%x.\n", + rval, mcp->mb[1], mcp->mb[2]); + } else { + ql_dbg(ql_log_info, vha, 0x11a8, + "Done %s.\n", __func__); + } + + return rval; +} + + /* * qla_get_exlogin_status * Get extended login status From 478b152ab309a3fb94f4955ac661a38c7f150101 Mon Sep 17 00:00:00 2001 From: Manish Rangankar Date: Wed, 10 Dec 2025 15:45:56 +0530 Subject: [PATCH 04/12] scsi: qla2xxx: Validate MCU signature before executing MBC 03h FC firmware does not come online during on-the-fly upgrade i.e. on soft reset. To limit Load flash firmware, i.e. MBC 3 changes, validate MCU signature before executing MBC 03h Signed-off-by: Manish Rangankar Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-5-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 3 +++ drivers/scsi/qla2xxx/qla_init.c | 2 +- drivers/scsi/qla2xxx/qla_nx.h | 1 + drivers/scsi/qla2xxx/qla_sup.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 04bc69bb11b1..7e693540c434 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -4150,6 +4150,7 @@ struct qla_hw_data { uint32_t eeh_flush:2; #define EEH_FLUSH_RDY 1 #define EEH_FLUSH_DONE 2 + uint32_t secure_mcu:1; } flags; uint16_t max_exchg; @@ -4415,6 +4416,8 @@ struct qla_hw_data { ((IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&\ (ha->zio_mode == QLA_ZIO_MODE_6)) +#define IS_QLA28XX_SECURED(ha) (IS_QLA28XX(ha) && ha->flags.secure_mcu) + /* HBA serial number */ uint8_t serial0; uint8_t serial1; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 5183ff813487..9729e32012aa 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -9059,7 +9059,7 @@ qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) qla27xx_get_active_image(vha, &active_regions); /* For 28XXX, always load the flash firmware using rom mbx */ - if (IS_QLA28XX(ha)) { + if (IS_QLA28XX_SECURED(ha)) { rval = qla28xx_load_flash_firmware(vha); if (rval != QLA_SUCCESS) { ql_log(ql_log_fatal, vha, 0x019e, diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h index 5d1bdc15b75c..8e7a7f5f0adb 100644 --- a/drivers/scsi/qla2xxx/qla_nx.h +++ b/drivers/scsi/qla2xxx/qla_nx.h @@ -892,6 +892,7 @@ struct ct6_dsd { #define FA_VPD_SIZE_82XX 0x400 #define FA_FLASH_LAYOUT_ADDR_82 0xFC400 +#define FA_FLASH_MCU_OFF 0x13000 /****************************************************************************** * diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 9e7a407ba1b9..b6c36a8a2d60 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -1084,6 +1084,32 @@ qla2xxx_get_idc_param(scsi_qla_host_t *vha) return; } +static int qla28xx_validate_mcu_signature(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct req_que *req = ha->req_q_map[0]; + uint32_t *dcode = (uint32_t *)req->ring; + uint32_t signature[2] = {0x000c0000, 0x00050000}; + int ret = QLA_SUCCESS; + + ret = qla24xx_read_flash_data(vha, dcode, FA_FLASH_MCU_OFF >> 2, 2); + if (ret) { + ql_log(ql_log_fatal, vha, 0x01ab, + "-> Failed to read flash mcu signature.\n"); + ret = QLA_FUNCTION_FAILED; + goto done; + } + + ql_dbg(ql_dbg_init, vha, 0x01ac, + "Flash data 0x%08x 0x%08x.\n", dcode[0], dcode[1]); + + if (!(dcode[0] == signature[0] && dcode[1] == signature[1])) + ret = QLA_FUNCTION_FAILED; + +done: + return ret; +} + int qla2xxx_get_flash_info(scsi_qla_host_t *vha) { @@ -1096,6 +1122,9 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha) !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) return QLA_SUCCESS; + if (IS_QLA28XX(ha) && !qla28xx_validate_mcu_signature(vha)) + ha->flags.secure_mcu = 1; + ret = qla2xxx_find_flt_start(vha, &flt_addr); if (ret != QLA_SUCCESS) return ret; From d74181ca110e3de9d7dc4fba7f9f6026033e2e5d Mon Sep 17 00:00:00 2001 From: Manish Rangankar Date: Wed, 10 Dec 2025 15:45:57 +0530 Subject: [PATCH 05/12] scsi: qla2xxx: Add bsg interface to support firmware img validation Add new bsg interface to issue MPI passthrough sub command to validate the new flash firmware image partition. Signed-off-by: Manish Rangankar Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-6-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 118 +++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_bsg.h | 12 ++++ drivers/scsi/qla2xxx/qla_def.h | 20 ++++++ drivers/scsi/qla2xxx/qla_gbl.h | 2 + drivers/scsi/qla2xxx/qla_mbx.c | 40 +++++++++++ 5 files changed, 192 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index ccfc2d26dd37..8afa8a4b8ccb 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -11,6 +11,8 @@ #include #include +static int qla28xx_validate_flash_image(struct bsg_job *bsg_job); + static void qla2xxx_free_fcport_work(struct work_struct *work) { struct fc_port *fcport = container_of(work, typeof(*fcport), @@ -2549,6 +2551,30 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job) return 0; } +static int +qla2x00_get_drv_attr(struct bsg_job *bsg_job) +{ + struct qla_drv_attr drv_attr; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + + memset(&drv_attr, 0, sizeof(struct qla_drv_attr)); + drv_attr.ext_attributes |= QLA_IMG_SET_VALID_SUPPORT; + + + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, &drv_attr, + sizeof(struct qla_drv_attr)); + + bsg_reply->reply_payload_rcv_len = sizeof(struct qla_drv_attr); + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK; + + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + bsg_reply->result = DID_OK << 16; + bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); + + return 0; +} + static int qla2x00_manage_host_stats(struct bsg_job *bsg_job) { @@ -2933,6 +2959,12 @@ qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_j case QL_VND_GET_FLASH_UPDATE_CAPS: return qla27xx_get_flash_upd_cap(bsg_job); + case QL_VND_GET_DRV_ATTR: + return qla2x00_get_drv_attr(bsg_job); + + case QL_VND_IMG_SET_VALID: + return qla28xx_validate_flash_image(bsg_job); + case QL_VND_SET_FLASH_UPDATE_CAPS: return qla27xx_set_flash_upd_cap(bsg_job); @@ -3246,3 +3278,89 @@ int qla2x00_mailbox_passthru(struct bsg_job *bsg_job) return ret; } + +static int +qla28xx_do_validate_flash_image(struct bsg_job *bsg_job, uint16_t *state) +{ + struct fc_bsg_request *bsg_request = bsg_job->request; + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); + uint16_t mstate[16]; + uint16_t mpi_state = 0; + uint16_t img_idx; + int rval = QLA_SUCCESS; + + memset(mstate, 0, sizeof(mstate)); + + rval = qla2x00_get_firmware_state(vha, mstate); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0xffff, + "MBC to get MPI state failed (%d)\n", rval); + rval = -EINVAL; + goto exit_flash_img; + } + + mpi_state = mstate[11]; + + if (!(mpi_state & BIT_9 && mpi_state & BIT_8 && mpi_state & BIT_15)) { + ql_log(ql_log_warn, vha, 0xffff, + "MPI firmware state failed (0x%02x)\n", mpi_state); + rval = -EINVAL; + goto exit_flash_img; + } + + rval = qla81xx_fac_semaphore_access(vha, FAC_SEMAPHORE_LOCK); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0xffff, + "Unable to lock flash semaphore."); + goto exit_flash_img; + } + + img_idx = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; + + rval = qla_mpipt_validate_fw(vha, img_idx, state); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0xffff, + "Failed to validate Firmware image index [0x%x].\n", + img_idx); + } + + qla81xx_fac_semaphore_access(vha, FAC_SEMAPHORE_UNLOCK); + +exit_flash_img: + return rval; +} + +static int qla28xx_validate_flash_image(struct bsg_job *bsg_job) +{ + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct qla_hw_data *ha = vha->hw; + uint16_t state = 0; + int rval = 0; + + if (!IS_QLA28XX(ha) || vha->vp_idx != 0) + return -EPERM; + + mutex_lock(&ha->optrom_mutex); + rval = qla28xx_do_validate_flash_image(bsg_job, &state); + if (rval) + rval = -EINVAL; + mutex_unlock(&ha->optrom_mutex); + + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + + if (rval) + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = + (state == 39) ? EXT_STATUS_IMG_SET_VALID_ERR : + EXT_STATUS_IMG_SET_CONFIG_ERR; + else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK; + + bsg_reply->result = DID_OK << 16; + bsg_reply->reply_payload_rcv_len = 0; + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); + + return QLA_SUCCESS; +} diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h index d38dab0a07e8..a920c8e482bc 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.h +++ b/drivers/scsi/qla2xxx/qla_bsg.h @@ -32,12 +32,14 @@ #define QL_VND_GET_PRIV_STATS_EX 0x1A #define QL_VND_SS_GET_FLASH_IMAGE_STATUS 0x1E #define QL_VND_EDIF_MGMT 0X1F +#define QL_VND_GET_DRV_ATTR 0x22 #define QL_VND_MANAGE_HOST_STATS 0x23 #define QL_VND_GET_HOST_STATS 0x24 #define QL_VND_GET_TGT_STATS 0x25 #define QL_VND_MANAGE_HOST_PORT 0x26 #define QL_VND_MBX_PASSTHRU 0x2B #define QL_VND_DPORT_DIAGNOSTICS_V2 0x2C +#define QL_VND_IMG_SET_VALID 0x30 /* BSG Vendor specific subcode returns */ #define EXT_STATUS_OK 0 @@ -50,6 +52,8 @@ #define EXT_STATUS_BUFFER_TOO_SMALL 16 #define EXT_STATUS_NO_MEMORY 17 #define EXT_STATUS_DEVICE_OFFLINE 22 +#define EXT_STATUS_IMG_SET_VALID_ERR 47 +#define EXT_STATUS_IMG_SET_CONFIG_ERR 48 /* * To support bidirectional iocb @@ -318,6 +322,14 @@ struct qla_active_regions { uint8_t reserved[31]; } __packed; +struct qla_drv_attr { + uint32_t attributes; + u32 ext_attributes; +#define QLA_IMG_SET_VALID_SUPPORT BIT_4 + u32 status_flags; + uint8_t reserved[20]; +} __packed; + #include "qla_edif_bsg.h" #endif diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7e693540c434..5593ad7fad27 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1386,6 +1386,26 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs) #define HCS_WRITE_SERDES 0x3 #define HCS_READ_SERDES 0x4 +/* + * ISP2[7|8]xx mailbox commands. + */ +#define MBC_MPI_PASSTHROUGH 0x200 + +/* MBC_MPI_PASSTHROUGH */ +#define MPIPT_REQ_V1 1 +enum { + MPIPT_SUBCMD_GET_SUP_CMD = 0x10, + MPIPT_SUBCMD_GET_SUP_FEATURE, + MPIPT_SUBCMD_GET_STATUS, + MPIPT_SUBCMD_VALIDATE_FW, +}; + +enum { + MPIPT_MPI_STATUS = 1, + MPIPT_FCORE_STATUS, + MPIPT_LOCKDOWN_STATUS, +}; + /* Firmware return data sizes */ #define FCAL_MAP_SIZE 128 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f12b2689163d..9e328c235e39 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -842,6 +842,8 @@ extern int qla82xx_write_optrom_data(struct scsi_qla_host *, void *, extern int qla82xx_abort_isp(scsi_qla_host_t *); extern int qla82xx_restart_isp(scsi_qla_host_t *); +extern int qla_mpipt_validate_fw(scsi_qla_host_t *vha, u16 img_idx, u16 *state); + /* IOCB related functions */ extern int qla82xx_start_scsi(srb_t *); extern void qla2x00_sp_free(srb_t *sp); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 28bb645ace67..0d598be6f3ea 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -7205,3 +7205,43 @@ int qla_mailbox_passthru(scsi_qla_host_t *vha, return rval; } + +int qla_mpipt_validate_fw(scsi_qla_host_t *vha, u16 img_idx, uint16_t *state) +{ + struct qla_hw_data *ha = vha->hw; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + int rval; + + if (!IS_QLA28XX(ha)) { + ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s %d\n", __func__, __LINE__); + return QLA_FUNCTION_FAILED; + } + + if (img_idx > 1) { + ql_log(ql_log_info, vha, 0xffff, + "%s %d Invalid flash image index [%d]\n", + __func__, __LINE__, img_idx); + return QLA_INVALID_COMMAND; + } + + memset(&mc, 0, sizeof(mc)); + mcp->mb[0] = MBC_MPI_PASSTHROUGH; + mcp->mb[1] = MPIPT_SUBCMD_VALIDATE_FW; + mcp->mb[2] = img_idx; + mcp->out_mb = MBX_1|MBX_0; + mcp->in_mb = MBX_2|MBX_1|MBX_0; + + /* send mb via iocb */ + rval = qla24xx_send_mb_cmd(vha, &mc); + if (rval) { + ql_log(ql_log_info, vha, 0xffff, "%s:Failed %x (mb=%x,%x)\n", + __func__, rval, mcp->mb[0], mcp->mb[1]); + *state = mcp->mb[1]; + } else { + ql_log(ql_log_info, vha, 0xffff, "%s: mb=%x,%x,%x\n", __func__, + mcp->mb[0], mcp->mb[1], mcp->mb[2]); + } + + return rval; +} From b0335ee4fb94832a4ef68774ca7e7b33b473c7a6 Mon Sep 17 00:00:00 2001 From: Shreyas Deodhar Date: Wed, 10 Dec 2025 15:45:58 +0530 Subject: [PATCH 06/12] scsi: qla2xxx: Allow recovery for tape devices Tape device doesn't show up after RSCNs. To fix this, remove tape device specific checks which allows recovery of tape devices. Fixes: 44c57f205876 ("scsi: qla2xxx: Changes to support FCP2 Target") Cc: stable@vger.kernel.org Signed-off-by: Shreyas Deodhar Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-7-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gs.c | 3 --- drivers/scsi/qla2xxx/qla_init.c | 9 --------- 2 files changed, 12 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 51c7cea71f90..02a52c215797 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3266,9 +3266,6 @@ login_logout: atomic_read(&fcport->state) == FCS_ONLINE) || do_delete) { if (fcport->loop_id != FC_NO_LOOP_ID) { - if (fcport->flags & FCF_FCP2_DEVICE) - continue; - ql_log(ql_log_warn, vha, 0x20f0, "%s %d %8phC post del sess\n", __func__, __LINE__, diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9729e32012aa..6ce3a492ad6f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1859,15 +1859,6 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) case RSCN_PORT_ADDR: fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1); if (fcport) { - if (ql2xfc2target && - fcport->flags & FCF_FCP2_DEVICE && - atomic_read(&fcport->state) == FCS_ONLINE) { - ql_dbg(ql_dbg_disc, vha, 0x2115, - "Delaying session delete for FCP2 portid=%06x %8phC ", - fcport->d_id.b24, fcport->port_name); - return; - } - if (vha->hw->flags.edif_enabled && DBELL_ACTIVE(vha)) { /* * On ipsec start by remote port, Target port From 8890bf450e0b6b283f48ac619fca5ac2f14ddd62 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 15:45:59 +0530 Subject: [PATCH 07/12] scsi: qla2xxx: Delay module unload while fabric scan in progress System crash seen during load/unload test in a loop. [105954.384919] RBP: ffff914589838dc0 R08: 0000000000000000 R09: 0000000000000086 [105954.384920] R10: 000000000000000f R11: ffffa31240904be5 R12: ffff914605f868e0 [105954.384921] R13: ffff914605f86910 R14: 0000000000008010 R15: 00000000ddb7c000 [105954.384923] FS: 0000000000000000(0000) GS:ffff9163fec40000(0000) knlGS:0000000000000000 [105954.384925] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [105954.384926] CR2: 000055d31ce1d6a0 CR3: 0000000119f5e001 CR4: 0000000000770ee0 [105954.384928] PKRU: 55555554 [105954.384929] Call Trace: [105954.384931] [105954.384934] qla24xx_sp_unmap+0x1f3/0x2a0 [qla2xxx] [105954.384962] ? qla_async_scan_sp_done+0x114/0x1f0 [qla2xxx] [105954.384980] ? qla24xx_els_ct_entry+0x4de/0x760 [qla2xxx] [105954.384999] ? __wake_up_common+0x80/0x190 [105954.385004] ? qla24xx_process_response_queue+0xc2/0xaa0 [qla2xxx] [105954.385023] ? qla24xx_msix_rsp_q+0x44/0xb0 [qla2xxx] [105954.385040] ? __handle_irq_event_percpu+0x3d/0x190 [105954.385044] ? handle_irq_event+0x58/0xb0 [105954.385046] ? handle_edge_irq+0x93/0x240 [105954.385050] ? __common_interrupt+0x41/0xa0 [105954.385055] ? common_interrupt+0x3e/0xa0 [105954.385060] ? asm_common_interrupt+0x22/0x40 The root cause of this was that there was a free (dma_free_attrs) in the interrupt context. There was a device discovery/fabric scan in progress. A module unload was issued which set the UNLOADING flag. As part of the discovery, after receiving an interrupt a work queue was scheduled (which involved a work to be queued). Since the UNLOADING flag is set, the work item was not allocated and the mapped memory had to be freed. The free occurred in interrupt context leading to system crash. Delay the driver unload until the fabric scan is complete to avoid the crash. Reported-by: kernel test robot Reported-by: Dan Carpenter Closes: https://lore.kernel.org/all/202512090414.07Waorz0-lkp@intel.com/ Fixes: 783e0dc4f66a ("qla2xxx: Check for device state before unloading the driver.") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-8-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 16a44c0917e1..c9aff70e7357 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1183,7 +1183,8 @@ qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha) while ((qla2x00_reset_active(vha) || ha->dpc_active || ha->flags.mbox_busy) || test_bit(FX00_RESET_RECOVERY, &vha->dpc_flags) || - test_bit(FX00_TARGET_SCAN, &vha->dpc_flags)) { + test_bit(FX00_TARGET_SCAN, &vha->dpc_flags) || + (vha->scan.scan_flags & SF_SCANNING)) { if (test_bit(UNLOADING, &base_vha->dpc_flags)) break; msleep(1000); From 7adbd2b7809066c75f0433e5e2a8e114b429f30f Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 15:46:00 +0530 Subject: [PATCH 08/12] scsi: qla2xxx: Free sp in error path to fix system crash System crash seen during load/unload test in a loop, [61110.449331] qla2xxx [0000:27:00.0]-0042:0: Disabled MSI-X. [61110.467494] ============================================================================= [61110.467498] BUG qla2xxx_srbs (Tainted: G OE -------- --- ): Objects remaining in qla2xxx_srbs on __kmem_cache_shutdown() [61110.467501] ----------------------------------------------------------------------------- [61110.467502] Slab 0x000000000ffc8162 objects=51 used=1 fp=0x00000000e25d3d85 flags=0x57ffffc0010200(slab|head|node=1|zone=2|lastcpupid=0x1fffff) [61110.467509] CPU: 53 PID: 455206 Comm: rmmod Kdump: loaded Tainted: G OE -------- --- 5.14.0-284.11.1.el9_2.x86_64 #1 [61110.467513] Hardware name: HPE ProLiant DL385 Gen10 Plus v2/ProLiant DL385 Gen10 Plus v2, BIOS A42 08/17/2023 [61110.467515] Call Trace: [61110.467516] [61110.467519] dump_stack_lvl+0x34/0x48 [61110.467526] slab_err.cold+0x53/0x67 [61110.467534] __kmem_cache_shutdown+0x16e/0x320 [61110.467540] kmem_cache_destroy+0x51/0x160 [61110.467544] qla2x00_module_exit+0x93/0x99 [qla2xxx] [61110.467607] ? __do_sys_delete_module.constprop.0+0x178/0x280 [61110.467613] ? syscall_trace_enter.constprop.0+0x145/0x1d0 [61110.467616] ? do_syscall_64+0x5c/0x90 [61110.467619] ? exc_page_fault+0x62/0x150 [61110.467622] ? entry_SYSCALL_64_after_hwframe+0x63/0xcd [61110.467626] [61110.467627] Disabling lock debugging due to kernel taint [61110.467635] Object 0x0000000026f7e6e6 @offset=16000 [61110.467639] ------------[ cut here ]------------ [61110.467639] kmem_cache_destroy qla2xxx_srbs: Slab cache still has objects when called from qla2x00_module_exit+0x93/0x99 [qla2xxx] [61110.467659] WARNING: CPU: 53 PID: 455206 at mm/slab_common.c:520 kmem_cache_destroy+0x14d/0x160 [61110.467718] CPU: 53 PID: 455206 Comm: rmmod Kdump: loaded Tainted: G B OE -------- --- 5.14.0-284.11.1.el9_2.x86_64 #1 [61110.467720] Hardware name: HPE ProLiant DL385 Gen10 Plus v2/ProLiant DL385 Gen10 Plus v2, BIOS A42 08/17/2023 [61110.467721] RIP: 0010:kmem_cache_destroy+0x14d/0x160 [61110.467724] Code: 99 7d 07 00 48 89 ef e8 e1 6a 07 00 eb b3 48 8b 55 60 48 8b 4c 24 20 48 c7 c6 70 fc 66 90 48 c7 c7 f8 ef a1 90 e8 e1 ed 7c 00 <0f> 0b eb 93 c3 cc cc cc cc 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 [61110.467725] RSP: 0018:ffffa304e489fe80 EFLAGS: 00010282 [61110.467727] RAX: 0000000000000000 RBX: ffffffffc0d9a860 RCX: 0000000000000027 [61110.467729] RDX: ffff8fd5ff9598a8 RSI: 0000000000000001 RDI: ffff8fd5ff9598a0 [61110.467730] RBP: ffff8fb6aaf78700 R08: 0000000000000000 R09: 0000000100d863b7 [61110.467731] R10: ffffa304e489fd20 R11: ffffffff913bef48 R12: 0000000040002000 [61110.467731] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [61110.467733] FS: 00007f64c89fb740(0000) GS:ffff8fd5ff940000(0000) knlGS:0000000000000000 [61110.467734] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [61110.467735] CR2: 00007f0f02bfe000 CR3: 00000020ad6dc005 CR4: 0000000000770ee0 [61110.467736] PKRU: 55555554 [61110.467737] Call Trace: [61110.467738] [61110.467739] qla2x00_module_exit+0x93/0x99 [qla2xxx] [61110.467755] ? __do_sys_delete_module.constprop.0+0x178/0x280 Free sp in the error path to fix the crash. Fixes: f352eeb75419 ("scsi: qla2xxx: Add ability to use GPNFT/GNNFT for RSCN handling") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-9-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 02a52c215797..e5ebb9c5b650 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3532,8 +3532,8 @@ int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp) if (vha->scan.scan_flags & SF_SCANNING) { spin_unlock_irqrestore(&vha->work_lock, flags); ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012, - "%s: scan active\n", __func__); - return rval; + "%s: scan active for sp:%p\n", __func__, sp); + goto done_free_sp; } vha->scan.scan_flags |= SF_SCANNING; if (!sp) From b6df15aec8c3441357d4da0eaf4339eb20f5999f Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 15:46:01 +0530 Subject: [PATCH 09/12] scsi: qla2xxx: Validate sp before freeing associated memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit System crash with the following signature [154563.214890] nvme nvme2: NVME-FC{1}: controller connect complete [154564.169363] qla2xxx [0000:b0:00.1]-3002:2: nvme: Sched: Set ZIO exchange threshold to 3. [154564.169405] qla2xxx [0000:b0:00.1]-ffffff:2: SET ZIO Activity exchange threshold to 5. [154565.539974] qla2xxx [0000:b0:00.1]-5013:2: RSCN database changed – 0078 0080 0000. [154565.545744] qla2xxx [0000:b0:00.1]-5013:2: RSCN database changed – 0078 00a0 0000. [154565.545857] qla2xxx [0000:b0:00.1]-11a2:2: FEC=enabled (data rate). [154565.552760] qla2xxx [0000:b0:00.1]-11a2:2: FEC=enabled (data rate). [154565.553079] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [154565.553080] #PF: supervisor read access in kernel mode [154565.553082] #PF: error_code(0x0000) - not-present page [154565.553084] PGD 80000010488ab067 P4D 80000010488ab067 PUD 104978a067 PMD 0 [154565.553089] Oops: 0000 1 PREEMPT SMP PTI [154565.553092] CPU: 10 PID: 858 Comm: qla2xxx_2_dpc Kdump: loaded Tainted: G OE ------- --- 5.14.0-503.11.1.el9_5.x86_64 #1 [154565.553096] Hardware name: HPE Synergy 660 Gen10/Synergy 660 Gen10 Compute Module, BIOS I43 09/30/2024 [154565.553097] RIP: 0010:qla_fab_async_scan.part.0+0x40b/0x870 [qla2xxx] [154565.553141] Code: 00 00 e8 58 a3 ec d4 49 89 e9 ba 12 20 00 00 4c 89 e6 49 c7 c0 00 ee a8 c0 48 c7 c1 66 c0 a9 c0 bf 00 80 00 10 e8 15 69 00 00 <4c> 8b 8d f8 00 00 00 4d 85 c9 74 35 49 8b 84 24 00 19 00 00 48 8b [154565.553143] RSP: 0018:ffffb4dbc8aebdd0 EFLAGS: 00010286 [154565.553145] RAX: 0000000000000000 RBX: ffff8ec2cf0908d0 RCX: 0000000000000002 [154565.553147] RDX: 0000000000000000 RSI: ffffffffc0a9c896 RDI: ffffb4dbc8aebd47 [154565.553148] RBP: 0000000000000000 R08: ffffb4dbc8aebd45 R09: 0000000000ffff0a [154565.553150] R10: 0000000000000000 R11: 000000000000000f R12: ffff8ec2cf0908d0 [154565.553151] R13: ffff8ec2cf090900 R14: 0000000000000102 R15: ffff8ec2cf084000 [154565.553152] FS: 0000000000000000(0000) GS:ffff8ed27f800000(0000) knlGS:0000000000000000 [154565.553154] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [154565.553155] CR2: 00000000000000f8 CR3: 000000113ae0a005 CR4: 00000000007706f0 [154565.553157] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [154565.553158] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [154565.553159] PKRU: 55555554 [154565.553160] Call Trace: [154565.553162] [154565.553165] ? show_trace_log_lvl+0x1c4/0x2df [154565.553172] ? show_trace_log_lvl+0x1c4/0x2df [154565.553177] ? qla_fab_async_scan.part.0+0x40b/0x870 [qla2xxx] [154565.553215] ? __die_body.cold+0x8/0xd [154565.553218] ? page_fault_oops+0x134/0x170 [154565.553223] ? snprintf+0x49/0x70 [154565.553229] ? exc_page_fault+0x62/0x150 [154565.553238] ? asm_exc_page_fault+0x22/0x30 Check for sp being non NULL before freeing any associated memory Fixes: a4239945b8ad ("scsi: qla2xxx: Add switch command to simplify fabric discovery") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-10-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gs.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index e5ebb9c5b650..880cd73feaca 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3698,23 +3698,25 @@ int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp) return rval; done_free_sp: - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.req_allocated_size, - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } + if (sp) { + if (sp->u.iocb_cmd.u.ctarg.req) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.req_allocated_size, + sp->u.iocb_cmd.u.ctarg.req, + sp->u.iocb_cmd.u.ctarg.req_dma); + sp->u.iocb_cmd.u.ctarg.req = NULL; + } + if (sp->u.iocb_cmd.u.ctarg.rsp) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, + sp->u.iocb_cmd.u.ctarg.rsp, + sp->u.iocb_cmd.u.ctarg.rsp_dma); + sp->u.iocb_cmd.u.ctarg.rsp = NULL; + } - /* ref: INIT */ - kref_put(&sp->cmd_kref, qla2x00_sp_release); + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); + } spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; From 42b2dab4340d39b71334151e10c6d7d9b0040ffa Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 15:46:02 +0530 Subject: [PATCH 10/12] scsi: qla2xxx: Query FW again before proceeding with login Issue occurred during a continuous reboot test of several thousand iterations specific to a fabric topo with dual mode target where it sends a PLOGI/PRLI and then sends a LOGO. The initiator was also in the process of discovery and sent a PLOGI to the switch. It then queried a list of ports logged in via mbx 75h and the GPDB response indicated that the target was logged in. This caused a mismatch in the states between the driver and FW. Requery the FW for the state and proceed with the rest of discovery process. Fixes: a4239945b8ad ("scsi: qla2xxx: Add switch command to simplify fabric discovery") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-11-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 19 +++++++++++++++++-- drivers/scsi/qla2xxx/qla_isr.c | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 6ce3a492ad6f..689f909943b4 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2462,8 +2462,23 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) ea->sp->gen1, fcport->rscn_gen, ea->data[0], ea->data[1], ea->iop[0], ea->iop[1]); - if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || - (fcport->fw_login_state == DSC_LS_PRLI_PEND)) { + if (fcport->fw_login_state == DSC_LS_PLOGI_PEND) { + ql_dbg(ql_dbg_disc, vha, 0x20ea, + "%s %d %8phC Remote is trying to login\n", + __func__, __LINE__, fcport->port_name); + /* + * If we get here, there is port thats already logged in, + * but it's state has not moved ahead. Recheck with FW on + * what state it is in and proceed ahead + */ + if (!N2N_TOPO(vha->hw)) { + fcport->fw_login_state = DSC_LS_PRLI_COMP; + qla24xx_post_gpdb_work(vha, fcport, 0); + } + return; + } + + if (fcport->fw_login_state == DSC_LS_PRLI_PEND) { ql_dbg(ql_dbg_disc, vha, 0x20ea, "%s %d %8phC Remote is trying to login\n", __func__, __LINE__, fcport->port_name); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index a3971afc2dd1..a4dda4fcb52c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1669,13 +1669,28 @@ skip_rio: /* Port logout */ fcport = qla2x00_find_fcport_by_loopid(vha, mb[1]); - if (!fcport) + if (!fcport) { + ql_dbg(ql_dbg_async, vha, 0x5011, + "Could not find fcport:%04x %04x %04x\n", + mb[1], mb[2], mb[3]); break; - if (atomic_read(&fcport->state) != FCS_ONLINE) + } + + if (atomic_read(&fcport->state) != FCS_ONLINE) { + ql_dbg(ql_dbg_async, vha, 0x5012, + "Port state is not online State:0x%x \n", + atomic_read(&fcport->state)); + ql_dbg(ql_dbg_async, vha, 0x5012, + "Scheduling session for deletion \n"); + fcport->logout_on_delete = 0; + qlt_schedule_sess_for_deletion(fcport); break; + } + ql_dbg(ql_dbg_async, vha, 0x508a, "Marking port lost loopid=%04x portid=%06x.\n", fcport->loop_id, fcport->d_id.b24); + if (qla_ini_mode_enabled(vha)) { fcport->logout_on_delete = 0; qlt_schedule_sess_for_deletion(fcport); From c2c68225b1456f4d0d393b5a8778d51bb0d5b1d0 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 15:46:03 +0530 Subject: [PATCH 11/12] scsi: qla2xxx: Fix bsg_done() causing double free Kernel panic observed on system, [5353358.825191] BUG: unable to handle page fault for address: ff5f5e897b024000 [5353358.825194] #PF: supervisor write access in kernel mode [5353358.825195] #PF: error_code(0x0002) - not-present page [5353358.825196] PGD 100006067 P4D 0 [5353358.825198] Oops: 0002 [#1] PREEMPT SMP NOPTI [5353358.825200] CPU: 5 PID: 2132085 Comm: qlafwupdate.sub Kdump: loaded Tainted: G W L ------- --- 5.14.0-503.34.1.el9_5.x86_64 #1 [5353358.825203] Hardware name: HPE ProLiant DL360 Gen11/ProLiant DL360 Gen11, BIOS 2.44 01/17/2025 [5353358.825204] RIP: 0010:memcpy_erms+0x6/0x10 [5353358.825211] RSP: 0018:ff591da8f4f6b710 EFLAGS: 00010246 [5353358.825212] RAX: ff5f5e897b024000 RBX: 0000000000007090 RCX: 0000000000001000 [5353358.825213] RDX: 0000000000001000 RSI: ff591da8f4fed090 RDI: ff5f5e897b024000 [5353358.825214] RBP: 0000000000010000 R08: ff5f5e897b024000 R09: 0000000000000000 [5353358.825215] R10: ff46cf8c40517000 R11: 0000000000000001 R12: 0000000000008090 [5353358.825216] R13: ff591da8f4f6b720 R14: 0000000000001000 R15: 0000000000000000 [5353358.825218] FS: 00007f1e88d47740(0000) GS:ff46cf935f940000(0000) knlGS:0000000000000000 [5353358.825219] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [5353358.825220] CR2: ff5f5e897b024000 CR3: 0000000231532004 CR4: 0000000000771ef0 [5353358.825221] PKRU: 55555554 [5353358.825222] Call Trace: [5353358.825223] [5353358.825224] ? show_trace_log_lvl+0x1c4/0x2df [5353358.825229] ? show_trace_log_lvl+0x1c4/0x2df [5353358.825232] ? sg_copy_buffer+0xc8/0x110 [5353358.825236] ? __die_body.cold+0x8/0xd [5353358.825238] ? page_fault_oops+0x134/0x170 [5353358.825242] ? kernelmode_fixup_or_oops+0x84/0x110 [5353358.825244] ? exc_page_fault+0xa8/0x150 [5353358.825247] ? asm_exc_page_fault+0x22/0x30 [5353358.825252] ? memcpy_erms+0x6/0x10 [5353358.825253] sg_copy_buffer+0xc8/0x110 [5353358.825259] qla2x00_process_vendor_specific+0x652/0x1320 [qla2xxx] [5353358.825317] qla24xx_bsg_request+0x1b2/0x2d0 [qla2xxx] Most routines in qla_bsg.c call bsg_done() only for success cases. However a few invoke it for failure case as well leading to a double free. Validate before calling bsg_done(). Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-12-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 8afa8a4b8ccb..2c44a379cb23 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -1548,8 +1548,9 @@ qla2x00_update_optrom(struct bsg_job *bsg_job) ha->optrom_buffer = NULL; ha->optrom_state = QLA_SWAITING; mutex_unlock(&ha->optrom_mutex); - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return rval; } @@ -2638,8 +2639,9 @@ qla2x00_manage_host_stats(struct bsg_job *bsg_job) sizeof(struct ql_vnd_mng_host_stats_resp)); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return ret; } @@ -2728,8 +2730,9 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, data, response_len); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); kfree(data); host_stat_out: @@ -2828,8 +2831,9 @@ reply: bsg_job->reply_payload.sg_cnt, data, response_len); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); tgt_stat_out: kfree(data); @@ -2890,8 +2894,9 @@ qla2x00_manage_host_port(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, &rsp_data, sizeof(struct ql_vnd_mng_host_port_resp)); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return ret; } @@ -3272,7 +3277,8 @@ int qla2x00_mailbox_passthru(struct bsg_job *bsg_job) bsg_job->reply_len = sizeof(*bsg_job->reply); bsg_reply->result = DID_OK << 16; - bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); kfree(req_data); @@ -3359,8 +3365,9 @@ static int qla28xx_validate_flash_image(struct bsg_job *bsg_job) bsg_reply->result = DID_OK << 16; bsg_reply->reply_payload_rcv_len = 0; bsg_job->reply_len = sizeof(struct fc_bsg_reply); - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return QLA_SUCCESS; } From 1732d10fa7edb611c8384ca0b841d6f79ddf5bed Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Wed, 10 Dec 2025 15:46:04 +0530 Subject: [PATCH 12/12] scsi: qla2xxx: Update version to 10.02.10.100-k Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-13-njavali@marvell.com Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_version.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index a491d6ee5c94..9564beafdab7 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.02.09.400-k" +#define QLA2XXX_VERSION "10.02.10.100-k" #define QLA_DRIVER_MAJOR_VER 10 -#define QLA_DRIVER_MINOR_VER 2 -#define QLA_DRIVER_PATCH_VER 9 -#define QLA_DRIVER_BETA_VER 400 +#define QLA_DRIVER_MINOR_VER 02 +#define QLA_DRIVER_PATCH_VER 10 +#define QLA_DRIVER_BETA_VER 100