Blame SOURCES/0051-scsi-scsi-qla2xxx-Fix-fw-dump-corruption.patch

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