Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 846e8dd4 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files
James writes:
  "SCSI fixes on 20180925

   Nine obvious bug fixes mostly in individual drivers.  The target fix
   is of particular importance because it's CVE related."

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: sd: don't crash the host on invalid commands
  scsi: ipr: System hung while dlpar adding primary ipr adapter back
  scsi: target: iscsi: Use bin2hex instead of a re-implementation
  scsi: target: iscsi: Use hex2bin instead of a re-implementation
  scsi: lpfc: Synchronize access to remoteport via rport
  scsi: ufs: Disable blk-mq for now
  scsi: sd: Contribute to randomness when running rotational device
  scsi: ibmvscsis: Ensure partition name is properly NUL terminated
  scsi: ibmvscsis: Fix a stringop-overflow warning
parents bfb0e9b4 f1f1fada
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -3474,11 +3474,10 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
		vscsi->dds.window[LOCAL].liobn,
		vscsi->dds.window[REMOTE].liobn);

	strcpy(vscsi->eye, "VSCSI ");
	strncat(vscsi->eye, vdev->name, MAX_EYE);
	snprintf(vscsi->eye, sizeof(vscsi->eye), "VSCSI %s", vdev->name);

	vscsi->dds.unit_id = vdev->unit_address;
	strncpy(vscsi->dds.partition_name, partition_name,
	strscpy(vscsi->dds.partition_name, partition_name,
		sizeof(vscsi->dds.partition_name));
	vscsi->dds.partition_num = partition_number;

+61 −45
Original line number Diff line number Diff line
@@ -3335,6 +3335,65 @@ static void ipr_release_dump(struct kref *kref)
	LEAVE;
}

static void ipr_add_remove_thread(struct work_struct *work)
{
	unsigned long lock_flags;
	struct ipr_resource_entry *res;
	struct scsi_device *sdev;
	struct ipr_ioa_cfg *ioa_cfg =
		container_of(work, struct ipr_ioa_cfg, scsi_add_work_q);
	u8 bus, target, lun;
	int did_work;

	ENTER;
	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);

restart:
	do {
		did_work = 0;
		if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
			spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
			return;
		}

		list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
			if (res->del_from_ml && res->sdev) {
				did_work = 1;
				sdev = res->sdev;
				if (!scsi_device_get(sdev)) {
					if (!res->add_to_ml)
						list_move_tail(&res->queue, &ioa_cfg->free_res_q);
					else
						res->del_from_ml = 0;
					spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
					scsi_remove_device(sdev);
					scsi_device_put(sdev);
					spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
				}
				break;
			}
		}
	} while (did_work);

	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
		if (res->add_to_ml) {
			bus = res->bus;
			target = res->target;
			lun = res->lun;
			res->add_to_ml = 0;
			spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
			scsi_add_device(ioa_cfg->host, bus, target, lun);
			spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
			goto restart;
		}
	}

	ioa_cfg->scan_done = 1;
	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
	kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
	LEAVE;
}

/**
 * ipr_worker_thread - Worker thread
 * @work:		ioa config struct
@@ -3349,13 +3408,9 @@ static void ipr_release_dump(struct kref *kref)
static void ipr_worker_thread(struct work_struct *work)
{
	unsigned long lock_flags;
	struct ipr_resource_entry *res;
	struct scsi_device *sdev;
	struct ipr_dump *dump;
	struct ipr_ioa_cfg *ioa_cfg =
		container_of(work, struct ipr_ioa_cfg, work_q);
	u8 bus, target, lun;
	int did_work;

	ENTER;
	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -3393,49 +3448,9 @@ static void ipr_worker_thread(struct work_struct *work)
		return;
	}

restart:
	do {
		did_work = 0;
		if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
			spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
			return;
		}
	schedule_work(&ioa_cfg->scsi_add_work_q);

		list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
			if (res->del_from_ml && res->sdev) {
				did_work = 1;
				sdev = res->sdev;
				if (!scsi_device_get(sdev)) {
					if (!res->add_to_ml)
						list_move_tail(&res->queue, &ioa_cfg->free_res_q);
					else
						res->del_from_ml = 0;
	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
					scsi_remove_device(sdev);
					scsi_device_put(sdev);
					spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
				}
				break;
			}
		}
	} while (did_work);

	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
		if (res->add_to_ml) {
			bus = res->bus;
			target = res->target;
			lun = res->lun;
			res->add_to_ml = 0;
			spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
			scsi_add_device(ioa_cfg->host, bus, target, lun);
			spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
			goto restart;
		}
	}

	ioa_cfg->scan_done = 1;
	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
	kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
	LEAVE;
}

@@ -9933,6 +9948,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
	INIT_LIST_HEAD(&ioa_cfg->free_res_q);
	INIT_LIST_HEAD(&ioa_cfg->used_res_q);
	INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
	INIT_WORK(&ioa_cfg->scsi_add_work_q, ipr_add_remove_thread);
	init_waitqueue_head(&ioa_cfg->reset_wait_q);
	init_waitqueue_head(&ioa_cfg->msi_wait_q);
	init_waitqueue_head(&ioa_cfg->eeh_wait_q);
+1 −0
Original line number Diff line number Diff line
@@ -1575,6 +1575,7 @@ struct ipr_ioa_cfg {
	u8 saved_mode_page_len;

	struct work_struct work_q;
	struct work_struct scsi_add_work_q;
	struct workqueue_struct *reset_work_q;

	wait_queue_head_t reset_wait_q;
+10 −5
Original line number Diff line number Diff line
@@ -360,12 +360,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
		goto buffer_done;

	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
		nrport = NULL;
		spin_lock(&vport->phba->hbalock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (!rport)
			continue;

		/* local short-hand pointer. */
		if (rport)
			nrport = rport->remoteport;
		spin_unlock(&vport->phba->hbalock);
		if (!nrport)
			continue;

@@ -3386,6 +3386,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
	struct lpfc_nodelist  *ndlp;
#if (IS_ENABLED(CONFIG_NVME_FC))
	struct lpfc_nvme_rport *rport;
	struct nvme_fc_remote_port *remoteport = NULL;
#endif

	shost = lpfc_shost_from_vport(vport);
@@ -3396,8 +3397,12 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
		if (ndlp->rport)
			ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
#if (IS_ENABLED(CONFIG_NVME_FC))
		spin_lock(&vport->phba->hbalock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (rport)
			remoteport = rport->remoteport;
		spin_unlock(&vport->phba->hbalock);
		if (remoteport)
			nvme_fc_set_remoteport_devloss(rport->remoteport,
						       vport->cfg_devloss_tmo);
#endif
+5 −5
Original line number Diff line number Diff line
@@ -551,7 +551,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
	unsigned char *statep;
	struct nvme_fc_local_port *localport;
	struct lpfc_nvmet_tgtport *tgtp;
	struct nvme_fc_remote_port *nrport;
	struct nvme_fc_remote_port *nrport = NULL;
	struct lpfc_nvme_rport *rport;

	cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
@@ -696,11 +696,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
	len += snprintf(buf + len, size - len, "\tRport List:\n");
	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
		/* local short-hand pointer. */
		spin_lock(&phba->hbalock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (!rport)
			continue;

		if (rport)
			nrport = rport->remoteport;
		spin_unlock(&phba->hbalock);
		if (!nrport)
			continue;

Loading