From: Quinn Tran <quinn.tran@xxxxxxxxxx> When user extract FW dump from driver, add mutex protection to prevent driver from freeing the FW dump buffer from freeing while the extraction is in progress. Signed-off-by: Quinn Tran <quinn.tran@xxxxxxxxxx> Signed-off-by: Himanshu Madhani <hmadhani@xxxxxxxxxxx> --- drivers/scsi/qla2xxx/qla_attr.c | 25 ++++++++++++++----------- drivers/scsi/qla2xxx/qla_init.c | 6 +++++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index b2520e49971d..da64fe54f59e 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -29,24 +29,27 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj, if (!(ha->fw_dump_reading || ha->mctp_dump_reading)) return 0; + mutex_lock(&ha->optrom_mutex); if (IS_P3P_TYPE(ha)) { if (off < ha->md_template_size) { rval = memory_read_from_buffer(buf, count, &off, ha->md_tmplt_hdr, ha->md_template_size); - return rval; + } else { + off -= ha->md_template_size; + rval = memory_read_from_buffer(buf, count, + &off, ha->md_dump, ha->md_dump_size); } - off -= ha->md_template_size; - rval = memory_read_from_buffer(buf, count, - &off, ha->md_dump, ha->md_dump_size); - return rval; - } else if (ha->mctp_dumped && ha->mctp_dump_reading) - return memory_read_from_buffer(buf, count, &off, ha->mctp_dump, + } else if (ha->mctp_dumped && ha->mctp_dump_reading) { + rval = memory_read_from_buffer(buf, count, &off, ha->mctp_dump, MCTP_DUMP_SIZE); - else if (ha->fw_dump_reading) - return memory_read_from_buffer(buf, count, &off, ha->fw_dump, + } else if (ha->fw_dump_reading) { + rval = memory_read_from_buffer(buf, count, &off, ha->fw_dump, ha->fw_dump_len); - else - return 0; + } else { + rval = 0; + } + mutex_unlock(&ha->optrom_mutex); + return rval; } static ssize_t diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 57ee2d979efe..ab212b4853a1 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -3234,6 +3234,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) "Unable to allocate (%d KB) for firmware dump.\n", dump_size / 1024); } else { + mutex_lock(&ha->optrom_mutex); if (ha->fw_dumped) { memcpy(fw_dump, ha->fw_dump, ha->fw_dump_len); vfree(ha->fw_dump); @@ -3253,8 +3254,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) "Allocated (%d KB) for firmware dump.\n", dump_size / 1024); - if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + mutex_unlock(&ha->optrom_mutex); return; + } ha->fw_dump->signature[0] = 'Q'; ha->fw_dump->signature[1] = 'L'; @@ -3277,6 +3280,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) htonl(offsetof (struct qla2xxx_fw_dump, isp)); } + mutex_unlock(&ha->optrom_mutex); } } } -- 2.12.0