|
|
3c6e85 |
From 3a61f8d532aa7935db27ef327af18d886a38d63f Mon Sep 17 00:00:00 2001
|
|
|
3c6e85 |
From: Himanshu Madhani <hmadhani@redhat.com>
|
|
|
3c6e85 |
Date: Thu, 1 Aug 2019 15:55:11 -0400
|
|
|
3c6e85 |
Subject: [PATCH 051/124] [scsi] scsi: qla2xxx: Fix fw dump corruption
|
|
|
3c6e85 |
|
|
|
3c6e85 |
Message-id: <20190801155618.12650-52-hmadhani@redhat.com>
|
|
|
3c6e85 |
Patchwork-id: 267828
|
|
|
3c6e85 |
O-Subject: [RHEL 7.8 e-stor PATCH 051/118] scsi: qla2xxx: Fix fw dump corruption
|
|
|
3c6e85 |
Bugzilla: 1729270
|
|
|
3c6e85 |
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
|
|
|
3c6e85 |
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
3c6e85 |
|
|
|
3c6e85 |
From: Quinn Tran <quinn.tran@cavium.com>
|
|
|
3c6e85 |
|
|
|
3c6e85 |
Bugzilla 1729270
|
|
|
3c6e85 |
|
|
|
3c6e85 |
If fw dump buffer size changes and there is an existing fw dump, then save
|
|
|
3c6e85 |
the old dump in the newly allocated buffer.
|
|
|
3c6e85 |
|
|
|
3c6e85 |
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
|
|
|
3c6e85 |
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
|
|
|
3c6e85 |
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
|
3c6e85 |
(cherry picked from commit a4226ec3ef1214b0973abdba64db66e10f6b0a1c)
|
|
|
3c6e85 |
Signed-off-by: Himanshu Madhani <hmadhani@redhat.com>
|
|
|
3c6e85 |
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
|
3c6e85 |
---
|
|
|
3c6e85 |
drivers/scsi/qla2xxx/qla_def.h | 1 +
|
|
|
3c6e85 |
drivers/scsi/qla2xxx/qla_init.c | 84 +++++++++++++++++++++++++----------------
|
|
|
3c6e85 |
2 files changed, 53 insertions(+), 32 deletions(-)
|
|
|
3c6e85 |
|
|
|
3c6e85 |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
|
|
|
3c6e85 |
index ead433fe0ff4..f2f388108dbf 100644
|
|
|
3c6e85 |
--- a/drivers/scsi/qla2xxx/qla_def.h
|
|
|
3c6e85 |
+++ b/drivers/scsi/qla2xxx/qla_def.h
|
|
|
3c6e85 |
@@ -4053,6 +4053,7 @@ struct qla_hw_data {
|
|
|
3c6e85 |
} fwdt[2];
|
|
|
3c6e85 |
struct qla2xxx_fw_dump *fw_dump;
|
|
|
3c6e85 |
uint32_t fw_dump_len;
|
|
|
3c6e85 |
+ u32 fw_dump_alloc_len;
|
|
|
3c6e85 |
bool fw_dumped;
|
|
|
3c6e85 |
bool fw_dump_mpi;
|
|
|
3c6e85 |
unsigned long fw_dump_cap_flags;
|
|
|
3c6e85 |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
|
|
|
3c6e85 |
index d4199cd560e2..3d06299ef65a 100644
|
|
|
3c6e85 |
--- a/drivers/scsi/qla2xxx/qla_init.c
|
|
|
3c6e85 |
+++ b/drivers/scsi/qla2xxx/qla_init.c
|
|
|
3c6e85 |
@@ -3141,12 +3141,12 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
|
|
|
3c6e85 |
!IS_QLA28XX(ha))
|
|
|
3c6e85 |
mq_size = sizeof(struct qla2xxx_mq_chain);
|
|
|
3c6e85 |
/*
|
|
|
3c6e85 |
- * Allocate maximum buffer size for all queues.
|
|
|
3c6e85 |
+ * Allocate maximum buffer size for all queues - Q0.
|
|
|
3c6e85 |
* Resizing must be done at end-of-dump processing.
|
|
|
3c6e85 |
*/
|
|
|
3c6e85 |
- mq_size += ha->max_req_queues *
|
|
|
3c6e85 |
+ mq_size += (ha->max_req_queues - 1) *
|
|
|
3c6e85 |
(req->length * sizeof(request_t));
|
|
|
3c6e85 |
- mq_size += ha->max_rsp_queues *
|
|
|
3c6e85 |
+ mq_size += (ha->max_rsp_queues - 1) *
|
|
|
3c6e85 |
(rsp->length * sizeof(response_t));
|
|
|
3c6e85 |
}
|
|
|
3c6e85 |
if (ha->tgt.atio_ring)
|
|
|
3c6e85 |
@@ -3221,42 +3221,62 @@ try_eft:
|
|
|
3c6e85 |
ha->exlogin_size;
|
|
|
3c6e85 |
|
|
|
3c6e85 |
allocate:
|
|
|
3c6e85 |
- if (!ha->fw_dump_len || dump_size != ha->fw_dump_len) {
|
|
|
3c6e85 |
+ if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) {
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
|
|
|
3c6e85 |
+ "%s dump_size %d fw_dump_len %d fw_dump_alloc_len %d\n",
|
|
|
3c6e85 |
+ __func__, dump_size, ha->fw_dump_len,
|
|
|
3c6e85 |
+ ha->fw_dump_alloc_len);
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
fw_dump = vmalloc(dump_size);
|
|
|
3c6e85 |
if (!fw_dump) {
|
|
|
3c6e85 |
ql_log(ql_log_warn, vha, 0x00c4,
|
|
|
3c6e85 |
"Unable to allocate (%d KB) for firmware dump.\n",
|
|
|
3c6e85 |
dump_size / 1024);
|
|
|
3c6e85 |
} else {
|
|
|
3c6e85 |
- if (ha->fw_dump)
|
|
|
3c6e85 |
+ if (ha->fw_dumped) {
|
|
|
3c6e85 |
+ memcpy(fw_dump, ha->fw_dump, ha->fw_dump_len);
|
|
|
3c6e85 |
vfree(ha->fw_dump);
|
|
|
3c6e85 |
- ha->fw_dump = fw_dump;
|
|
|
3c6e85 |
-
|
|
|
3c6e85 |
- ha->fw_dump_len = dump_size;
|
|
|
3c6e85 |
- ql_dbg(ql_dbg_init, vha, 0x00c5,
|
|
|
3c6e85 |
- "Allocated (%d KB) for firmware dump.\n",
|
|
|
3c6e85 |
- dump_size / 1024);
|
|
|
3c6e85 |
-
|
|
|
3c6e85 |
- if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
|
|
|
3c6e85 |
- return;
|
|
|
3c6e85 |
-
|
|
|
3c6e85 |
- ha->fw_dump->signature[0] = 'Q';
|
|
|
3c6e85 |
- ha->fw_dump->signature[1] = 'L';
|
|
|
3c6e85 |
- ha->fw_dump->signature[2] = 'G';
|
|
|
3c6e85 |
- ha->fw_dump->signature[3] = 'C';
|
|
|
3c6e85 |
- ha->fw_dump->version = htonl(1);
|
|
|
3c6e85 |
-
|
|
|
3c6e85 |
- ha->fw_dump->fixed_size = htonl(fixed_size);
|
|
|
3c6e85 |
- ha->fw_dump->mem_size = htonl(mem_size);
|
|
|
3c6e85 |
- ha->fw_dump->req_q_size = htonl(req_q_size);
|
|
|
3c6e85 |
- ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
|
|
|
3c6e85 |
-
|
|
|
3c6e85 |
- ha->fw_dump->eft_size = htonl(eft_size);
|
|
|
3c6e85 |
- ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma));
|
|
|
3c6e85 |
- ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma));
|
|
|
3c6e85 |
-
|
|
|
3c6e85 |
- ha->fw_dump->header_size =
|
|
|
3c6e85 |
- htonl(offsetof(struct qla2xxx_fw_dump, isp));
|
|
|
3c6e85 |
+ ha->fw_dump = fw_dump;
|
|
|
3c6e85 |
+ ha->fw_dump_alloc_len = dump_size;
|
|
|
3c6e85 |
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
|
|
|
3c6e85 |
+ "Re-Allocated (%d KB) and save firmware dump.\n",
|
|
|
3c6e85 |
+ dump_size / 1024);
|
|
|
3c6e85 |
+ } else {
|
|
|
3c6e85 |
+ if (ha->fw_dump)
|
|
|
3c6e85 |
+ vfree(ha->fw_dump);
|
|
|
3c6e85 |
+ ha->fw_dump = fw_dump;
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
+ ha->fw_dump_len = ha->fw_dump_alloc_len =
|
|
|
3c6e85 |
+ dump_size;
|
|
|
3c6e85 |
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
|
|
|
3c6e85 |
+ "Allocated (%d KB) for firmware dump.\n",
|
|
|
3c6e85 |
+ dump_size / 1024);
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
|
|
|
3c6e85 |
+ return;
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
+ ha->fw_dump->signature[0] = 'Q';
|
|
|
3c6e85 |
+ ha->fw_dump->signature[1] = 'L';
|
|
|
3c6e85 |
+ ha->fw_dump->signature[2] = 'G';
|
|
|
3c6e85 |
+ ha->fw_dump->signature[3] = 'C';
|
|
|
3c6e85 |
+ ha->fw_dump->version = htonl(1);
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
+ ha->fw_dump->fixed_size = htonl(fixed_size);
|
|
|
3c6e85 |
+ ha->fw_dump->mem_size = htonl(mem_size);
|
|
|
3c6e85 |
+ ha->fw_dump->req_q_size = htonl(req_q_size);
|
|
|
3c6e85 |
+ ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
+ ha->fw_dump->eft_size = htonl(eft_size);
|
|
|
3c6e85 |
+ ha->fw_dump->eft_addr_l =
|
|
|
3c6e85 |
+ htonl(LSD(ha->eft_dma));
|
|
|
3c6e85 |
+ ha->fw_dump->eft_addr_h =
|
|
|
3c6e85 |
+ htonl(MSD(ha->eft_dma));
|
|
|
3c6e85 |
+
|
|
|
3c6e85 |
+ ha->fw_dump->header_size =
|
|
|
3c6e85 |
+ htonl(offsetof
|
|
|
3c6e85 |
+ (struct qla2xxx_fw_dump, isp));
|
|
|
3c6e85 |
+ }
|
|
|
3c6e85 |
}
|
|
|
3c6e85 |
}
|
|
|
3c6e85 |
}
|
|
|
3c6e85 |
--
|
|
|
3c6e85 |
2.13.6
|
|
|
3c6e85 |
|