1
0
Fork 0

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: b333293058 ("qeth: add support for af_iucv HiperSockets transport")
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
alistair/sunxi64-5.5-dsi
Julian Wiedmann 2019-12-23 15:03:22 +01:00 committed by David S. Miller
parent 8b5026bc16
commit 5b6c7b55cf
2 changed files with 28 additions and 17 deletions

View File

@ -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;

View File

@ -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;
}