* [PATCH net 1/6] s390/qeth: fix qdio teardown after early init error
2019-12-23 14:03 [PATCH net 0/6] s390/qeth: fixes 2019-12-23 Julian Wiedmann
@ 2019-12-23 14:03 ` Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 2/6] s390/qeth: lock the card while changing its hsuid Julian Wiedmann
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Julian Wiedmann @ 2019-12-23 14:03 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
qeth_l?_set_online() goes through a number of initialization steps, and
on any error uses qeth_l?_stop_card() to tear down the residual state.
The first initialization step is qeth_core_hardsetup_card(). When this
fails after having established a QDIO context on the device
(ie. somewhere after qeth_mpc_initialize()), qeth_l?_stop_card() doesn't
shut down this QDIO context again (since the card state hasn't
progressed from DOWN at this stage).
Even worse, we then call qdio_free() as final teardown step to free the
QDIO data structures - while some of them are still hooked into wider
QDIO infrastructure such as the IRQ list. This is inevitably followed by
use-after-frees and other nastyness.
Fix this by unconditionally calling qeth_qdio_clear_card() to shut down
the QDIO context, and also to halt/clear any pending activity on the
various IO channels.
Remove the naive attempt at handling the teardown in
qeth_mpc_initialize(), it clearly doesn't suffice and we're handling it
properly now in the wider teardown code.
Fixes: 4a71df50047f ("qeth: new qeth device driver")
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core_main.c | 20 ++++++++------------
drivers/s390/net/qeth_l2_main.c | 2 +-
drivers/s390/net/qeth_l3_main.c | 2 +-
3 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index bc4158888af9..324cf22f9111 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2482,50 +2482,46 @@ static int qeth_mpc_initialize(struct qeth_card *card)
rc = qeth_cm_enable(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "2err%d", rc);
- goto out_qdio;
+ return rc;
}
rc = qeth_cm_setup(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "3err%d", rc);
- goto out_qdio;
+ return rc;
}
rc = qeth_ulp_enable(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "4err%d", rc);
- goto out_qdio;
+ return rc;
}
rc = qeth_ulp_setup(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "5err%d", rc);
- goto out_qdio;
+ return rc;
}
rc = qeth_alloc_qdio_queues(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "5err%d", rc);
- goto out_qdio;
+ return rc;
}
rc = qeth_qdio_establish(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "6err%d", rc);
qeth_free_qdio_queues(card);
- goto out_qdio;
+ return rc;
}
rc = qeth_qdio_activate(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "7err%d", rc);
- goto out_qdio;
+ return rc;
}
rc = qeth_dm_act(card);
if (rc) {
QETH_CARD_TEXT_(card, 2, "8err%d", rc);
- goto out_qdio;
+ return rc;
}
return 0;
-out_qdio:
- qeth_qdio_clear_card(card, !IS_IQD(card));
- qdio_free(CARD_DDEV(card));
- return rc;
}
void qeth_print_status_message(struct qeth_card *card)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8c95e6019bac..15e2fd65d434 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -287,12 +287,12 @@ static void qeth_l2_stop_card(struct qeth_card *card)
card->state = CARD_STATE_HARDSETUP;
}
if (card->state == CARD_STATE_HARDSETUP) {
- qeth_qdio_clear_card(card, 0);
qeth_drain_output_queues(card);
qeth_clear_working_pool_list(card);
card->state = CARD_STATE_DOWN;
}
+ qeth_qdio_clear_card(card, 0);
flush_workqueue(card->event_wq);
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
card->info.promisc_mode = 0;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 04e301de376f..5508ab89b518 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1307,12 +1307,12 @@ static void qeth_l3_stop_card(struct qeth_card *card)
card->state = CARD_STATE_HARDSETUP;
}
if (card->state == CARD_STATE_HARDSETUP) {
- qeth_qdio_clear_card(card, 0);
qeth_drain_output_queues(card);
qeth_clear_working_pool_list(card);
card->state = CARD_STATE_DOWN;
}
+ qeth_qdio_clear_card(card, 0);
flush_workqueue(card->event_wq);
card->info.promisc_mode = 0;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net 2/6] s390/qeth: lock the card while changing its hsuid
2019-12-23 14:03 [PATCH net 0/6] s390/qeth: fixes 2019-12-23 Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 1/6] s390/qeth: fix qdio teardown after early init error Julian Wiedmann
@ 2019-12-23 14:03 ` Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 3/6] s390/qeth: fix false reporting of VNIC CHAR config failure Julian Wiedmann
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Julian Wiedmann @ 2019-12-23 14:03 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
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 <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core_main.c | 5 ----
drivers/s390/net/qeth_l3_sys.c | 40 +++++++++++++++++++++----------
2 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 324cf22f9111..c64ef55f0dff 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -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;
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index f9067ed6c7d3..e8c848f72c6d 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -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;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net 3/6] s390/qeth: fix false reporting of VNIC CHAR config failure
2019-12-23 14:03 [PATCH net 0/6] s390/qeth: fixes 2019-12-23 Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 1/6] s390/qeth: fix qdio teardown after early init error Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 2/6] s390/qeth: lock the card while changing its hsuid Julian Wiedmann
@ 2019-12-23 14:03 ` Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 4/6] s390/qeth: Fix vnicc_is_in_use if rx_bcast not set Julian Wiedmann
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Julian Wiedmann @ 2019-12-23 14:03 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Alexandra Winter, Julian Wiedmann
From: Alexandra Winter <wintera@linux.ibm.com>
Symptom: Error message "Configuring the VNIC characteristics failed"
in dmesg whenever an OSA interface on z15 is set online.
The VNIC characteristics get re-programmed when setting a L2 device
online. This follows the selected 'wanted' characteristics - with the
exception that the INVISIBLE characteristic unconditionally gets
switched off.
For devices that don't support INVISIBLE (ie. OSA), the resulting
IO failure raises a noisy error message
("Configuring the VNIC characteristics failed").
For IQD, INVISIBLE is off by default anyways.
So don't unnecessarily special-case the INVISIBLE characteristic, and
thereby suppress the misleading error message on OSA devices.
Fixes: caa1f0b10d18 ("s390/qeth: add VNICC enable/disable support")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_l2_main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 15e2fd65d434..fc5d8ed3a737 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -2041,7 +2041,6 @@ static void qeth_l2_vnicc_init(struct qeth_card *card)
error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING,
timeout);
chars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT;
- chars_tmp |= QETH_VNICC_BRIDGE_INVISIBLE;
chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE;
for_each_set_bit(i, &chars_tmp, chars_len) {
vnicc = BIT(i);
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net 4/6] s390/qeth: Fix vnicc_is_in_use if rx_bcast not set
2019-12-23 14:03 [PATCH net 0/6] s390/qeth: fixes 2019-12-23 Julian Wiedmann
` (2 preceding siblings ...)
2019-12-23 14:03 ` [PATCH net 3/6] s390/qeth: fix false reporting of VNIC CHAR config failure Julian Wiedmann
@ 2019-12-23 14:03 ` Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 5/6] s390/qeth: vnicc Fix init to default Julian Wiedmann
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Julian Wiedmann @ 2019-12-23 14:03 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Alexandra Winter, Julian Wiedmann
From: Alexandra Winter <wintera@linux.ibm.com>
Symptom: After vnicc/rx_bcast has been manually set to 0,
bridge_* sysfs parameters can still be set or written.
Only occurs on HiperSockets, as OSA doesn't support changing rx_bcast.
Vnic characteristics and bridgeport settings are mutually exclusive.
rx_bcast defaults to 1, so manually setting it to 0 should disable
bridge_* parameters.
Instead it makes sense here to check the supported mask. If the card
does not support vnicc at all, bridge commands are always allowed.
Fixes: caa1f0b10d18 ("s390/qeth: add VNICC enable/disable support")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_l2_main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index fc5d8ed3a737..8024a2112a87 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1952,8 +1952,7 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout)
/* check if VNICC is currently enabled */
bool qeth_l2_vnicc_is_in_use(struct qeth_card *card)
{
- /* if everything is turned off, VNICC is not active */
- if (!card->options.vnicc.cur_chars)
+ if (!card->options.vnicc.sup_chars)
return false;
/* default values are only OK if rx_bcast was not enabled by user
* or the card is offline.
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net 5/6] s390/qeth: vnicc Fix init to default
2019-12-23 14:03 [PATCH net 0/6] s390/qeth: fixes 2019-12-23 Julian Wiedmann
` (3 preceding siblings ...)
2019-12-23 14:03 ` [PATCH net 4/6] s390/qeth: Fix vnicc_is_in_use if rx_bcast not set Julian Wiedmann
@ 2019-12-23 14:03 ` Julian Wiedmann
2019-12-23 14:03 ` [PATCH net 6/6] s390/qeth: fix initialization on old HW Julian Wiedmann
2019-12-25 6:41 ` [PATCH net 0/6] s390/qeth: fixes 2019-12-23 David Miller
6 siblings, 0 replies; 8+ messages in thread
From: Julian Wiedmann @ 2019-12-23 14:03 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Alexandra Winter, Julian Wiedmann
From: Alexandra Winter <wintera@linux.ibm.com>
During vnicc_init wanted_char should be compared to cur_char and not
to QETH_VNICC_DEFAULT. Without this patch there is no way to enforce
the default values as desired values.
Note, that it is expected, that a card comes online with default values.
This patch was tested with private card firmware.
Fixes: caa1f0b10d18 ("s390/qeth: add VNICC enable/disable support")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_l2_main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8024a2112a87..47d37e75dda6 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -2039,7 +2039,9 @@ static void qeth_l2_vnicc_init(struct qeth_card *card)
/* enforce assumed default values and recover settings, if changed */
error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING,
timeout);
- chars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT;
+ /* Change chars, if necessary */
+ chars_tmp = card->options.vnicc.wanted_chars ^
+ card->options.vnicc.cur_chars;
chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE;
for_each_set_bit(i, &chars_tmp, chars_len) {
vnicc = BIT(i);
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net 6/6] s390/qeth: fix initialization on old HW
2019-12-23 14:03 [PATCH net 0/6] s390/qeth: fixes 2019-12-23 Julian Wiedmann
` (4 preceding siblings ...)
2019-12-23 14:03 ` [PATCH net 5/6] s390/qeth: vnicc Fix init to default Julian Wiedmann
@ 2019-12-23 14:03 ` Julian Wiedmann
2019-12-25 6:41 ` [PATCH net 0/6] s390/qeth: fixes 2019-12-23 David Miller
6 siblings, 0 replies; 8+ messages in thread
From: Julian Wiedmann @ 2019-12-23 14:03 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
I stumbled over an old OSA model that claims to support DIAG_ASSIST,
but then rejects the cmd to query its DIAG capabilities.
In the old code this was ok, as the returned raw error code was > 0.
Now that we translate the raw codes to errnos, the "rc < 0" causes us
to fail the initialization of the device.
The fix is trivial: don't bail out when the DIAG query fails. Such an
error is not critical, we can still use the device (with a slightly
reduced set of features).
Fixes: 742d4d40831d ("s390/qeth: convert remaining legacy cmd callbacks")
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core_main.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index c64ef55f0dff..29facb913671 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -5026,10 +5026,8 @@ int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
}
if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
rc = qeth_query_setdiagass(card);
- if (rc < 0) {
+ if (rc)
QETH_CARD_TEXT_(card, 2, "8err%d", rc);
- goto out;
- }
}
if (!qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP) ||
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH net 0/6] s390/qeth: fixes 2019-12-23
2019-12-23 14:03 [PATCH net 0/6] s390/qeth: fixes 2019-12-23 Julian Wiedmann
` (5 preceding siblings ...)
2019-12-23 14:03 ` [PATCH net 6/6] s390/qeth: fix initialization on old HW Julian Wiedmann
@ 2019-12-25 6:41 ` David Miller
6 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2019-12-25 6:41 UTC (permalink / raw)
To: jwi; +Cc: netdev, linux-s390, heiko.carstens, raspl, ubraun
From: Julian Wiedmann <jwi@linux.ibm.com>
Date: Mon, 23 Dec 2019 15:03:20 +0100
> please apply the following patch series for qeth to your net tree.
>
> This brings two fixes for errors during device initialization, deals with
> several issues in the vnicc control code, and adds a missing lock.
Series applied, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread