Commit 5565ec4e authored by Linus Torvalds's avatar Linus Torvalds

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
parents a5948745 09e797c8
...@@ -1463,6 +1463,8 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) ...@@ -1463,6 +1463,8 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
struct Scsi_Host *host = cmd->device->host; struct Scsi_Host *host = cmd->device->host;
int rtn = 0; int rtn = 0;
atomic_inc(&cmd->device->iorequest_cnt);
/* check if the device is still usable */ /* check if the device is still usable */
if (unlikely(cmd->device->sdev_state == SDEV_DEL)) { if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
/* in SDEV_DEL we error all commands. DID_NO_CONNECT /* in SDEV_DEL we error all commands. DID_NO_CONNECT
...@@ -1483,6 +1485,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) ...@@ -1483,6 +1485,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
*/ */
SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd, SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
"queuecommand : device blocked\n")); "queuecommand : device blocked\n"));
atomic_dec(&cmd->device->iorequest_cnt);
return SCSI_MLQUEUE_DEVICE_BUSY; return SCSI_MLQUEUE_DEVICE_BUSY;
} }
...@@ -1515,6 +1518,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) ...@@ -1515,6 +1518,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
trace_scsi_dispatch_cmd_start(cmd); trace_scsi_dispatch_cmd_start(cmd);
rtn = host->hostt->queuecommand(host, cmd); rtn = host->hostt->queuecommand(host, cmd);
if (rtn) { if (rtn) {
atomic_dec(&cmd->device->iorequest_cnt);
trace_scsi_dispatch_cmd_error(cmd, rtn); trace_scsi_dispatch_cmd_error(cmd, rtn);
if (rtn != SCSI_MLQUEUE_DEVICE_BUSY && if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
rtn != SCSI_MLQUEUE_TARGET_BUSY) rtn != SCSI_MLQUEUE_TARGET_BUSY)
...@@ -1761,7 +1765,6 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -1761,7 +1765,6 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
goto out_dec_host_busy; goto out_dec_host_busy;
} }
atomic_inc(&cmd->device->iorequest_cnt);
return BLK_STS_OK; return BLK_STS_OK;
out_dec_host_busy: out_dec_host_busy:
......
...@@ -1780,7 +1780,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) ...@@ -1780,7 +1780,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
length = scsi_bufflen(scmnd); length = scsi_bufflen(scmnd);
payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb; payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb;
payload_sz = sizeof(cmd_request->mpb); payload_sz = 0;
if (scsi_sg_count(scmnd)) { if (scsi_sg_count(scmnd)) {
unsigned long offset_in_hvpg = offset_in_hvpage(sgl->offset); 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) ...@@ -1789,10 +1789,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
unsigned long hvpfn, hvpfns_to_add; unsigned long hvpfn, hvpfns_to_add;
int j, i = 0, sg_count; 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) + if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
sizeof(struct vmbus_packet_mpb_array));
payload = kzalloc(payload_sz, GFP_ATOMIC); payload = kzalloc(payload_sz, GFP_ATOMIC);
if (!payload) if (!payload)
return SCSI_MLQUEUE_DEVICE_BUSY; return SCSI_MLQUEUE_DEVICE_BUSY;
......
...@@ -150,7 +150,8 @@ static int ufshcd_mcq_config_nr_queues(struct ufs_hba *hba) ...@@ -150,7 +150,8 @@ static int ufshcd_mcq_config_nr_queues(struct ufs_hba *hba)
u32 hba_maxq, rem, tot_queues; u32 hba_maxq, rem, tot_queues;
struct Scsi_Host *host = hba->host; 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 + tot_queues = UFS_MCQ_NUM_DEV_CMD_QUEUES + read_queues + poll_queues +
rw_queues; rw_queues;
...@@ -265,7 +266,7 @@ static int ufshcd_mcq_get_tag(struct ufs_hba *hba, ...@@ -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) - addr = (le64_to_cpu(cqe->command_desc_base_addr) & CQE_UCD_BA) -
hba->ucdl_dma_addr; 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, static void ufshcd_mcq_process_cqe(struct ufs_hba *hba,
......
...@@ -2849,10 +2849,10 @@ static void ufshcd_map_queues(struct Scsi_Host *shost) ...@@ -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) 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 + 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; struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr;
dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_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, u16 response_offset = offsetof(struct utp_transfer_cmd_desc,
response_upiu); response_upiu);
u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table); u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table);
...@@ -3761,7 +3761,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) ...@@ -3761,7 +3761,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
size_t utmrdl_size, utrdl_size, ucdl_size; size_t utmrdl_size, utrdl_size, ucdl_size;
/* Allocate memory for UTP command descriptors */ /* 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, hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev,
ucdl_size, ucdl_size,
&hba->ucdl_dma_addr, &hba->ucdl_dma_addr,
...@@ -3861,7 +3861,7 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) ...@@ -3861,7 +3861,7 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba)
prdt_offset = prdt_offset =
offsetof(struct utp_transfer_cmd_desc, prd_table); 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; cmd_desc_dma_addr = hba->ucdl_dma_addr;
for (i = 0; i < hba->nutrs; i++) { for (i = 0; i < hba->nutrs; i++) {
...@@ -8452,7 +8452,7 @@ static void ufshcd_release_sdb_queue(struct ufs_hba *hba, int nutrs) ...@@ -8452,7 +8452,7 @@ static void ufshcd_release_sdb_queue(struct ufs_hba *hba, int nutrs)
{ {
size_t ucdl_size, utrdl_size; 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, dmam_free_coherent(hba->dev, ucdl_size, hba->ucdl_base_addr,
hba->ucdl_dma_addr); hba->ucdl_dma_addr);
......
...@@ -1133,7 +1133,7 @@ static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba) ...@@ -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)); }) ({ (void)(hba); BUILD_BUG_ON(sg_entry_size != sizeof(struct ufshcd_sg_entry)); })
#endif #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); return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment