Skip to content

Commit

Permalink
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "Six fixes, all of which appear to have user visible consequences.

  The DMA one is a regression fix from the merge window and of the
  others, four are driver specific and one specific to the target code"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ufs: Use explicit access size in ufshcd_dump_regs
  scsi: tcmu: fix use after free
  scsi: csiostor: fix NULL pointer dereference in csio_vport_set_state()
  scsi: lpfc: nvmet: avoid hang / use-after-free when destroying targetport
  scsi: lpfc: nvme: avoid hang / use-after-free when destroying localport
  scsi: communicate max segment size to the DMA mapping code
  • Loading branch information
Linus Torvalds committed Jan 26, 2019
2 parents 6b8f915 + d672475 commit 7930851
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 45 deletions.
9 changes: 4 additions & 5 deletions drivers/ata/pata_macio.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,10 @@ static struct scsi_host_template pata_macio_sht = {
.sg_tablesize = MAX_DCMDS,
/* We may not need that strict one */
.dma_boundary = ATA_DMA_BOUNDARY,
/* Not sure what the real max is but we know it's less than 64K, let's
* use 64K minus 256
*/
.max_segment_size = MAX_DBDMA_SEG,
.slave_configure = pata_macio_slave_config,
};

Expand Down Expand Up @@ -1044,11 +1048,6 @@ static int pata_macio_common_init(struct pata_macio_priv *priv,
/* Make sure we have sane initial timings in the cache */
pata_macio_default_timings(priv);

/* Not sure what the real max is but we know it's less than 64K, let's
* use 64K minus 256
*/
dma_set_max_seg_size(priv->dev, MAX_DBDMA_SEG);

/* Allocate libata host for 1 port */
memset(&pinfo, 0, sizeof(struct ata_port_info));
pmac_macio_calc_timing_masks(priv, &pinfo);
Expand Down
22 changes: 9 additions & 13 deletions drivers/ata/sata_inic162x.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,15 @@ struct inic_port_priv {

static struct scsi_host_template inic_sht = {
ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = LIBATA_MAX_PRD, /* maybe it can be larger? */
.dma_boundary = INIC_DMA_BOUNDARY,
.sg_tablesize = LIBATA_MAX_PRD, /* maybe it can be larger? */

/*
* This controller is braindamaged. dma_boundary is 0xffff like others
* but it will lock up the whole machine HARD if 65536 byte PRD entry
* is fed. Reduce maximum segment size.
*/
.dma_boundary = INIC_DMA_BOUNDARY,
.max_segment_size = 65536 - 512,
};

static const int scr_map[] = {
Expand Down Expand Up @@ -868,17 +875,6 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
}

/*
* This controller is braindamaged. dma_boundary is 0xffff
* like others but it will lock up the whole machine HARD if
* 65536 byte PRD entry is fed. Reduce maximum segment size.
*/
rc = dma_set_max_seg_size(&pdev->dev, 65536 - 512);
if (rc) {
dev_err(&pdev->dev, "failed to set the maximum segment size\n");
return rc;
}

rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
if (rc) {
dev_err(&pdev->dev, "failed to initialize controller\n");
Expand Down
5 changes: 1 addition & 4 deletions drivers/firewire/sbp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,10 +1144,6 @@ static int sbp2_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
if (device->is_local)
return -ENODEV;

if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
WARN_ON(dma_set_max_seg_size(device->card->device,
SBP2_MAX_SEG_SIZE));

shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
if (shost == NULL)
return -ENOMEM;
Expand Down Expand Up @@ -1610,6 +1606,7 @@ static struct scsi_host_template scsi_driver_template = {
.eh_abort_handler = sbp2_scsi_abort,
.this_id = -1,
.sg_tablesize = SG_ALL,
.max_segment_size = SBP2_MAX_SEG_SIZE,
.can_queue = 1,
.sdev_attrs = sbp2_scsi_sysfs_attrs,
};
Expand Down
9 changes: 4 additions & 5 deletions drivers/scsi/aacraid/linit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1747,11 +1747,10 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
shost->max_sectors = (shost->sg_tablesize * 8) + 112;
}

error = dma_set_max_seg_size(&pdev->dev,
(aac->adapter_info.options & AAC_OPT_NEW_COMM) ?
(shost->max_sectors << 9) : 65536);
if (error)
goto out_deinit;
if (aac->adapter_info.options & AAC_OPT_NEW_COMM)
shost->max_segment_size = shost->max_sectors << 9;
else
shost->max_segment_size = 65536;

/*
* Firmware printf works only with older firmware.
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/csiostor/csio_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,12 +594,12 @@ csio_vport_create(struct fc_vport *fc_vport, bool disable)
}

fc_vport_set_state(fc_vport, FC_VPORT_INITIALIZING);
ln->fc_vport = fc_vport;

if (csio_fcoe_alloc_vnp(hw, ln))
goto error;

*(struct csio_lnode **)fc_vport->dd_data = ln;
ln->fc_vport = fc_vport;
if (!fc_vport->node_name)
fc_vport->node_name = wwn_to_u64(csio_ln_wwnn(ln));
if (!fc_vport->port_name)
Expand Down
16 changes: 9 additions & 7 deletions drivers/scsi/lpfc/lpfc_nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ lpfc_nvme_localport_delete(struct nvme_fc_local_port *localport)
lport);

/* release any threads waiting for the unreg to complete */
complete(&lport->lport_unreg_done);
if (lport->vport->localport)
complete(lport->lport_unreg_cmp);
}

/* lpfc_nvme_remoteport_delete
Expand Down Expand Up @@ -2545,7 +2546,8 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
*/
void
lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
struct lpfc_nvme_lport *lport)
struct lpfc_nvme_lport *lport,
struct completion *lport_unreg_cmp)
{
#if (IS_ENABLED(CONFIG_NVME_FC))
u32 wait_tmo;
Expand All @@ -2557,8 +2559,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
*/
wait_tmo = msecs_to_jiffies(LPFC_NVME_WAIT_TMO * 1000);
while (true) {
ret = wait_for_completion_timeout(&lport->lport_unreg_done,
wait_tmo);
ret = wait_for_completion_timeout(lport_unreg_cmp, wait_tmo);
if (unlikely(!ret)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_IOERR,
"6176 Lport %p Localport %p wait "
Expand Down Expand Up @@ -2592,12 +2593,12 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
struct lpfc_nvme_lport *lport;
struct lpfc_nvme_ctrl_stat *cstat;
int ret;
DECLARE_COMPLETION_ONSTACK(lport_unreg_cmp);

if (vport->nvmei_support == 0)
return;

localport = vport->localport;
vport->localport = NULL;
lport = (struct lpfc_nvme_lport *)localport->private;
cstat = lport->cstat;

Expand All @@ -2608,13 +2609,14 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
/* lport's rport list is clear. Unregister
* lport and release resources.
*/
init_completion(&lport->lport_unreg_done);
lport->lport_unreg_cmp = &lport_unreg_cmp;
ret = nvme_fc_unregister_localport(localport);

/* Wait for completion. This either blocks
* indefinitely or succeeds
*/
lpfc_nvme_lport_unreg_wait(vport, lport);
lpfc_nvme_lport_unreg_wait(vport, lport, &lport_unreg_cmp);
vport->localport = NULL;
kfree(cstat);

/* Regardless of the unregister upcall response, clear
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/lpfc/lpfc_nvme.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct lpfc_nvme_ctrl_stat {
/* Declare nvme-based local and remote port definitions. */
struct lpfc_nvme_lport {
struct lpfc_vport *vport;
struct completion lport_unreg_done;
struct completion *lport_unreg_cmp;
/* Add stats counters here */
struct lpfc_nvme_ctrl_stat *cstat;
atomic_t fc4NvmeLsRequests;
Expand Down
8 changes: 5 additions & 3 deletions drivers/scsi/lpfc/lpfc_nvmet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,8 @@ lpfc_nvmet_targetport_delete(struct nvmet_fc_target_port *targetport)
struct lpfc_nvmet_tgtport *tport = targetport->private;

/* release any threads waiting for the unreg to complete */
complete(&tport->tport_unreg_done);
if (tport->phba->targetport)
complete(tport->tport_unreg_cmp);
}

static void
Expand Down Expand Up @@ -1692,6 +1693,7 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
struct lpfc_nvmet_tgtport *tgtp;
struct lpfc_queue *wq;
uint32_t qidx;
DECLARE_COMPLETION_ONSTACK(tport_unreg_cmp);

if (phba->nvmet_support == 0)
return;
Expand All @@ -1701,9 +1703,9 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
wq = phba->sli4_hba.nvme_wq[qidx];
lpfc_nvmet_wqfull_flush(phba, wq, NULL);
}
init_completion(&tgtp->tport_unreg_done);
tgtp->tport_unreg_cmp = &tport_unreg_cmp;
nvmet_fc_unregister_targetport(phba->targetport);
wait_for_completion_timeout(&tgtp->tport_unreg_done, 5);
wait_for_completion_timeout(&tport_unreg_cmp, 5);
lpfc_nvmet_cleanup_io_context(phba);
}
phba->targetport = NULL;
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/lpfc/lpfc_nvmet.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
/* Used for NVME Target */
struct lpfc_nvmet_tgtport {
struct lpfc_hba *phba;
struct completion tport_unreg_done;
struct completion *tport_unreg_cmp;

/* Stats counters - lpfc_nvmet_unsol_ls_buffer */
atomic_t rcv_ls_req_in;
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/scsi_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1842,8 +1842,8 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
blk_queue_segment_boundary(q, shost->dma_boundary);
dma_set_seg_boundary(dev, shost->dma_boundary);

blk_queue_max_segment_size(q,
min(shost->max_segment_size, dma_get_max_seg_size(dev)));
blk_queue_max_segment_size(q, shost->max_segment_size);
dma_set_max_seg_size(dev, shost->max_segment_size);

/*
* Set a reasonable default alignment: The larger of 32-byte (dword),
Expand Down
10 changes: 8 additions & 2 deletions drivers/scsi/ufs/ufshcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,19 @@
int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len,
const char *prefix)
{
u8 *regs;
u32 *regs;
size_t pos;

if (offset % 4 != 0 || len % 4 != 0) /* keep readl happy */
return -EINVAL;

regs = kzalloc(len, GFP_KERNEL);
if (!regs)
return -ENOMEM;

memcpy_fromio(regs, hba->mmio_base + offset, len);
for (pos = 0; pos < len; pos += 4)
regs[pos / 4] = ufshcd_readl(hba, offset + pos);

ufshcd_hex_dump(prefix, regs, len);
kfree(regs);

Expand Down
3 changes: 2 additions & 1 deletion drivers/target/target_core_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,12 +1317,13 @@ static int tcmu_check_expired_cmd(int id, void *p, void *data)
* target_complete_cmd will translate this to LUN COMM FAILURE
*/
scsi_status = SAM_STAT_CHECK_CONDITION;
list_del_init(&cmd->queue_entry);
} else {
list_del_init(&cmd->queue_entry);
idr_remove(&udev->commands, id);
tcmu_free_cmd(cmd);
scsi_status = SAM_STAT_TASK_SET_FULL;
}
list_del_init(&cmd->queue_entry);

pr_debug("Timing out cmd %u on dev %s that is %s.\n",
id, udev->name, is_running ? "inflight" : "queued");
Expand Down

0 comments on commit 7930851

Please sign in to comment.