mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-28 21:45:01 +08:00
scsi: qla2xxx: Fix crash due to NULL pointer dereference of ctx
Fixes following signature in the stack trace: BUG: unable to handle kernel NULL pointer dereference at 0000000000000374 IP: [<ffffffffa06ec8eb>] qla2x00_sp_free_dma+0xeb/0x2a0 [qla2xxx] Cc: <stable@vger.kernel.org> # v4.10+ Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
74939a0bc7
commit
d5ff0eed3a
@ -129,28 +129,16 @@ qla2x00_clear_loop_id(fc_port_t *fcport) {
|
||||
}
|
||||
|
||||
static inline void
|
||||
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp,
|
||||
struct qla_tgt_cmd *tc)
|
||||
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx)
|
||||
{
|
||||
struct dsd_dma *dsd_ptr, *tdsd_ptr;
|
||||
struct crc_context *ctx;
|
||||
|
||||
if (sp)
|
||||
ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
|
||||
else if (tc)
|
||||
ctx = (struct crc_context *)tc->ctx;
|
||||
else {
|
||||
BUG();
|
||||
return;
|
||||
}
|
||||
struct dsd_dma *dsd, *tdsd;
|
||||
|
||||
/* clean up allocated prev pool */
|
||||
list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
|
||||
&ctx->dsd_list, list) {
|
||||
dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr,
|
||||
dsd_ptr->dsd_list_dma);
|
||||
list_del(&dsd_ptr->list);
|
||||
kfree(dsd_ptr);
|
||||
list_for_each_entry_safe(dsd, tdsd, &ctx->dsd_list, list) {
|
||||
dma_pool_free(ha->dl_dma_pool, dsd->dsd_addr,
|
||||
dsd->dsd_list_dma);
|
||||
list_del(&dsd->list);
|
||||
kfree(dsd);
|
||||
}
|
||||
INIT_LIST_HEAD(&ctx->dsd_list);
|
||||
}
|
||||
|
@ -630,20 +630,24 @@ qla2x00_sp_free_dma(void *ptr)
|
||||
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
goto end;
|
||||
|
||||
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
|
||||
/* List assured to be having elements */
|
||||
qla2x00_clean_dsd_pool(ha, sp, NULL);
|
||||
qla2x00_clean_dsd_pool(ha, ctx);
|
||||
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
|
||||
}
|
||||
|
||||
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
|
||||
dma_pool_free(ha->dl_dma_pool, ctx,
|
||||
((struct crc_context *)ctx)->crc_ctx_dma);
|
||||
struct crc_context *ctx0 = ctx;
|
||||
|
||||
dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);
|
||||
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
|
||||
}
|
||||
|
||||
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
|
||||
struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
|
||||
struct ct6_dsd *ctx1 = ctx;
|
||||
|
||||
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
|
||||
ctx1->fcp_cmnd_dma);
|
||||
@ -653,6 +657,7 @@ qla2x00_sp_free_dma(void *ptr)
|
||||
mempool_free(ctx1, ha->ctx_mempool);
|
||||
}
|
||||
|
||||
end:
|
||||
CMD_SP(cmd) = NULL;
|
||||
qla2x00_rel_sp(sp);
|
||||
}
|
||||
@ -699,21 +704,24 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
|
||||
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
goto end;
|
||||
|
||||
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
|
||||
/* List assured to be having elements */
|
||||
qla2x00_clean_dsd_pool(ha, sp, NULL);
|
||||
qla2x00_clean_dsd_pool(ha, ctx);
|
||||
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
|
||||
}
|
||||
|
||||
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
|
||||
dma_pool_free(ha->dl_dma_pool, ctx,
|
||||
((struct crc_context *)ctx)->crc_ctx_dma);
|
||||
struct crc_context *ctx0 = ctx;
|
||||
|
||||
dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
|
||||
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
|
||||
}
|
||||
|
||||
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
|
||||
struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
|
||||
|
||||
struct ct6_dsd *ctx1 = ctx;
|
||||
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
|
||||
ctx1->fcp_cmnd_dma);
|
||||
list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
|
||||
@ -721,7 +729,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
|
||||
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
|
||||
mempool_free(ctx1, ha->ctx_mempool);
|
||||
}
|
||||
|
||||
end:
|
||||
CMD_SP(cmd) = NULL;
|
||||
qla2xxx_rel_qpair_sp(sp->qpair, sp);
|
||||
}
|
||||
|
@ -2245,10 +2245,12 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
|
||||
pci_unmap_sg(ha->pdev, cmd->prot_sg, cmd->prot_sg_cnt,
|
||||
cmd->dma_data_direction);
|
||||
|
||||
if (cmd->ctx_dsd_alloced)
|
||||
qla2x00_clean_dsd_pool(ha, NULL, cmd);
|
||||
if (!cmd->ctx)
|
||||
return;
|
||||
|
||||
if (cmd->ctx_dsd_alloced)
|
||||
qla2x00_clean_dsd_pool(ha, cmd->ctx);
|
||||
|
||||
if (cmd->ctx)
|
||||
dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user