mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
SCSI fixes on 20230519
Six small fixes. Four in drivers and the two core changes should be read together as a correction to a prior iorequest_cnt fix that exposed us to a potential use after free. Signed-off-by: James E.J. Bottomley <jejb@linux.ibm.com> -----BEGIN PGP SIGNATURE----- iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCZGfmkyYcamFtZXMuYm90 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishfE1AQDpZPzr nE9y8n9yALulFS0XLDgPElY+tPspbq7W6VhKjQEAoeXWFX/9ar0Qeg3OOev1B6vn sVXkWgmCWfq+M5v9qog= =3/aP -----END PGP SIGNATURE----- Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull SCSI fixes from James Bottomley: "Six small fixes. Four in drivers and the two core changes should be read together as a correction to a prior iorequest_cnt fix that exposed us to a potential use after free" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: core: Decrease scsi_device's iorequest_cnt if dispatch failed scsi: Revert "scsi: core: Do not increase scsi_device's iorequest_cnt if dispatch failed" scsi: storvsc: Don't pass unused PFNs to Hyper-V host scsi: ufs: core: Fix MCQ nr_hw_queues scsi: ufs: core: Rename symbol sizeof_utp_transfer_cmd_desc() scsi: ufs: core: Fix MCQ tag calculation
This commit is contained in:
commit
5565ec4ef4
@ -1463,6 +1463,8 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||
struct Scsi_Host *host = cmd->device->host;
|
||||
int rtn = 0;
|
||||
|
||||
atomic_inc(&cmd->device->iorequest_cnt);
|
||||
|
||||
/* check if the device is still usable */
|
||||
if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
|
||||
/* in SDEV_DEL we error all commands. DID_NO_CONNECT
|
||||
@ -1483,6 +1485,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||
*/
|
||||
SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
|
||||
"queuecommand : device blocked\n"));
|
||||
atomic_dec(&cmd->device->iorequest_cnt);
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
@ -1515,6 +1518,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||
trace_scsi_dispatch_cmd_start(cmd);
|
||||
rtn = host->hostt->queuecommand(host, cmd);
|
||||
if (rtn) {
|
||||
atomic_dec(&cmd->device->iorequest_cnt);
|
||||
trace_scsi_dispatch_cmd_error(cmd, rtn);
|
||||
if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
|
||||
rtn != SCSI_MLQUEUE_TARGET_BUSY)
|
||||
@ -1761,7 +1765,6 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
goto out_dec_host_busy;
|
||||
}
|
||||
|
||||
atomic_inc(&cmd->device->iorequest_cnt);
|
||||
return BLK_STS_OK;
|
||||
|
||||
out_dec_host_busy:
|
||||
|
@ -1780,7 +1780,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
|
||||
|
||||
length = scsi_bufflen(scmnd);
|
||||
payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb;
|
||||
payload_sz = sizeof(cmd_request->mpb);
|
||||
payload_sz = 0;
|
||||
|
||||
if (scsi_sg_count(scmnd)) {
|
||||
unsigned long offset_in_hvpg = offset_in_hvpage(sgl->offset);
|
||||
@ -1789,10 +1789,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
|
||||
unsigned long hvpfn, hvpfns_to_add;
|
||||
int j, i = 0, sg_count;
|
||||
|
||||
if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
|
||||
payload_sz = (hvpg_count * sizeof(u64) +
|
||||
sizeof(struct vmbus_packet_mpb_array));
|
||||
|
||||
payload_sz = (hvpg_count * sizeof(u64) +
|
||||
sizeof(struct vmbus_packet_mpb_array));
|
||||
if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
|
||||
payload = kzalloc(payload_sz, GFP_ATOMIC);
|
||||
if (!payload)
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
|
@ -150,7 +150,8 @@ static int ufshcd_mcq_config_nr_queues(struct ufs_hba *hba)
|
||||
u32 hba_maxq, rem, tot_queues;
|
||||
struct Scsi_Host *host = hba->host;
|
||||
|
||||
hba_maxq = FIELD_GET(MAX_QUEUE_SUP, hba->mcq_capabilities);
|
||||
/* maxq is 0 based value */
|
||||
hba_maxq = FIELD_GET(MAX_QUEUE_SUP, hba->mcq_capabilities) + 1;
|
||||
|
||||
tot_queues = UFS_MCQ_NUM_DEV_CMD_QUEUES + read_queues + poll_queues +
|
||||
rw_queues;
|
||||
@ -265,7 +266,7 @@ static int ufshcd_mcq_get_tag(struct ufs_hba *hba,
|
||||
addr = (le64_to_cpu(cqe->command_desc_base_addr) & CQE_UCD_BA) -
|
||||
hba->ucdl_dma_addr;
|
||||
|
||||
return div_u64(addr, sizeof(struct utp_transfer_cmd_desc));
|
||||
return div_u64(addr, ufshcd_get_ucd_size(hba));
|
||||
}
|
||||
|
||||
static void ufshcd_mcq_process_cqe(struct ufs_hba *hba,
|
||||
|
@ -2849,10 +2849,10 @@ static void ufshcd_map_queues(struct Scsi_Host *shost)
|
||||
static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i)
|
||||
{
|
||||
struct utp_transfer_cmd_desc *cmd_descp = (void *)hba->ucdl_base_addr +
|
||||
i * sizeof_utp_transfer_cmd_desc(hba);
|
||||
i * ufshcd_get_ucd_size(hba);
|
||||
struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr;
|
||||
dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr +
|
||||
i * sizeof_utp_transfer_cmd_desc(hba);
|
||||
i * ufshcd_get_ucd_size(hba);
|
||||
u16 response_offset = offsetof(struct utp_transfer_cmd_desc,
|
||||
response_upiu);
|
||||
u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table);
|
||||
@ -3761,7 +3761,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
|
||||
size_t utmrdl_size, utrdl_size, ucdl_size;
|
||||
|
||||
/* Allocate memory for UTP command descriptors */
|
||||
ucdl_size = sizeof_utp_transfer_cmd_desc(hba) * hba->nutrs;
|
||||
ucdl_size = ufshcd_get_ucd_size(hba) * hba->nutrs;
|
||||
hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev,
|
||||
ucdl_size,
|
||||
&hba->ucdl_dma_addr,
|
||||
@ -3861,7 +3861,7 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba)
|
||||
prdt_offset =
|
||||
offsetof(struct utp_transfer_cmd_desc, prd_table);
|
||||
|
||||
cmd_desc_size = sizeof_utp_transfer_cmd_desc(hba);
|
||||
cmd_desc_size = ufshcd_get_ucd_size(hba);
|
||||
cmd_desc_dma_addr = hba->ucdl_dma_addr;
|
||||
|
||||
for (i = 0; i < hba->nutrs; i++) {
|
||||
@ -8452,7 +8452,7 @@ static void ufshcd_release_sdb_queue(struct ufs_hba *hba, int nutrs)
|
||||
{
|
||||
size_t ucdl_size, utrdl_size;
|
||||
|
||||
ucdl_size = sizeof(struct utp_transfer_cmd_desc) * nutrs;
|
||||
ucdl_size = ufshcd_get_ucd_size(hba) * nutrs;
|
||||
dmam_free_coherent(hba->dev, ucdl_size, hba->ucdl_base_addr,
|
||||
hba->ucdl_dma_addr);
|
||||
|
||||
|
@ -1133,7 +1133,7 @@ static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba)
|
||||
({ (void)(hba); BUILD_BUG_ON(sg_entry_size != sizeof(struct ufshcd_sg_entry)); })
|
||||
#endif
|
||||
|
||||
static inline size_t sizeof_utp_transfer_cmd_desc(const struct ufs_hba *hba)
|
||||
static inline size_t ufshcd_get_ucd_size(const struct ufs_hba *hba)
|
||||
{
|
||||
return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user