From: Julian Wiedmann Date: Mon, 23 Dec 2019 15:03:22 +0100 Subject: s390/qeth: lock the card while changing its hsuid Git-commit: 5b6c7b55cfe26224b0f41b1c226d3534c542787f Patch-mainline: v5.5-rc5 References: git-fixes 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: b333293058aa ("qeth: add support for af_iucv HiperSockets transport") Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller [ ptesarik: All other returns under mutex also converted to gotos. ] Signed-off-by: Petr Tesarik --- drivers/s390/net/qeth_core_main.c | 6 ----- drivers/s390/net/qeth_l3_sys.c | 40 ++++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 18 deletions(-) --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3519,12 +3519,6 @@ int qeth_configure_cq(struct qeth_card * goto out; } - if (card->state != CARD_STATE_DOWN && - card->state != CARD_STATE_RECOVER) { - rc = -1; - goto out; - } - qeth_free_qdio_buffers(card); card->options.cq = cq; rc = 0; --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -271,25 +271,37 @@ static ssize_t qeth_l3_dev_hsuid_store(s 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 (!card) return -EINVAL; if (card->info.type != QETH_CARD_TYPE_IQD) return -EPERM; + + mutex_lock(&card->conf_mutex); if (card->state != CARD_STATE_DOWN && - card->state != CARD_STATE_RECOVER) - return -EPERM; - if (card->options.sniffer) - return -EPERM; - if (card->options.cq == QETH_CQ_NOTAVAILABLE) - return -EPERM; + card->state != CARD_STATE_RECOVER) { + 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 */ @@ -300,11 +312,13 @@ static ssize_t qeth_l3_dev_hsuid_store(s 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); @@ -313,6 +327,8 @@ static ssize_t qeth_l3_dev_hsuid_store(s rc = qeth_l3_modify_hsuid(card, true); +out: + mutex_unlock(&card->conf_mutex); return rc ? rc : count; }