Commit 5b6c7b55 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller
Browse files

s390/qeth: lock the card while changing its hsuid



qeth_l3_dev_hsuid_store() initially checks the card state, but doesn't
take the conf_mutex to ensure that the card stays in this state while
being reconfigured.

Rework the code to take this lock, and drop a redundant state check in a
helper function.

Fixes: b3332930 ("qeth: add support for af_iucv HiperSockets transport")
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8b5026bc
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -3425,11 +3425,6 @@ int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
			goto out;
		}

		if (card->state != CARD_STATE_DOWN) {
			rc = -1;
			goto out;
		}

		qeth_free_qdio_queues(card);
		card->options.cq = cq;
		rc = 0;
+28 −12
Original line number Diff line number Diff line
@@ -242,21 +242,33 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct qeth_card *card = dev_get_drvdata(dev);
	int rc = 0;
	char *tmp;
	int rc;

	if (!IS_IQD(card))
		return -EPERM;
	if (card->state != CARD_STATE_DOWN)
		return -EPERM;
	if (card->options.sniffer)
		return -EPERM;
	if (card->options.cq == QETH_CQ_NOTAVAILABLE)
		return -EPERM;

	mutex_lock(&card->conf_mutex);
	if (card->state != CARD_STATE_DOWN) {
		rc = -EPERM;
		goto out;
	}

	if (card->options.sniffer) {
		rc = -EPERM;
		goto out;
	}

	if (card->options.cq == QETH_CQ_NOTAVAILABLE) {
		rc = -EPERM;
		goto out;
	}

	tmp = strsep((char **)&buf, "\n");
	if (strlen(tmp) > 8)
		return -EINVAL;
	if (strlen(tmp) > 8) {
		rc = -EINVAL;
		goto out;
	}

	if (card->options.hsuid[0])
		/* delete old ip address */
@@ -267,11 +279,13 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
		card->options.hsuid[0] = '\0';
		memcpy(card->dev->perm_addr, card->options.hsuid, 9);
		qeth_configure_cq(card, QETH_CQ_DISABLED);
		return count;
		goto out;
	}

	if (qeth_configure_cq(card, QETH_CQ_ENABLED))
		return -EPERM;
	if (qeth_configure_cq(card, QETH_CQ_ENABLED)) {
		rc = -EPERM;
		goto out;
	}

	snprintf(card->options.hsuid, sizeof(card->options.hsuid),
		 "%-8s", tmp);
@@ -280,6 +294,8 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,

	rc = qeth_l3_modify_hsuid(card, true);

out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}