]>
Commit | Line | Data |
---|---|---|
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> | |
2 | Subject: qeth: avoid crash in case of layer mismatch for VSWITCH | |
3 | References: bnc#458339 | |
4 | ||
5 | Symptom: Oops in dev_close invocation of qeth_recover | |
6 | Problem: For z/VM GuestLAN or VSWITCH devices the transport | |
7 | layer is configured in z/VM. The layer2 attribute of | |
8 | a participating Linux device has to match the z/VM | |
9 | definition. In case of a mismatch Linux currently | |
10 | crashes in qeth recovery due to a reference to the | |
11 | not yet existing net_device. | |
12 | Solution: add a check for existence of net_device and add a | |
13 | message pointing to the mismatch of layer definitions | |
14 | in Linux and z/VM. | |
15 | ||
16 | Acked-by: John Jolly <jjolly@suse.de> | |
17 | --- | |
18 | ||
19 | drivers/s390/net/qeth_core_main.c | 4 ++++ | |
20 | drivers/s390/net/qeth_l2_main.c | 8 +++++--- | |
21 | drivers/s390/net/qeth_l3_main.c | 8 +++++--- | |
22 | 3 files changed, 14 insertions(+), 6 deletions(-) | |
23 | ||
24 | Index: linux-sles11/drivers/s390/net/qeth_core_main.c | |
25 | =================================================================== | |
26 | --- linux-sles11.orig/drivers/s390/net/qeth_core_main.c | |
27 | +++ linux-sles11/drivers/s390/net/qeth_core_main.c | |
28 | @@ -571,6 +571,10 @@ static void qeth_send_control_data_cb(st | |
29 | card = CARD_FROM_CDEV(channel->ccwdev); | |
30 | if (qeth_check_idx_response(iob->data)) { | |
31 | qeth_clear_ipacmd_list(card); | |
32 | + if (((iob->data[2] & 0xc0) == 0xc0) && iob->data[4] == 0xf6) | |
33 | + dev_err(&card->gdev->dev, | |
34 | + "The qeth device is not configured " | |
35 | + "for the OSI layer required by z/VM\n"); | |
36 | qeth_schedule_recovery(card); | |
37 | goto out; | |
38 | } | |
39 | Index: linux-sles11/drivers/s390/net/qeth_l3_main.c | |
40 | =================================================================== | |
41 | --- linux-sles11.orig/drivers/s390/net/qeth_l3_main.c | |
42 | +++ linux-sles11/drivers/s390/net/qeth_l3_main.c | |
43 | @@ -2083,9 +2083,11 @@ static int qeth_l3_stop_card(struct qeth | |
44 | if (recovery_mode) | |
45 | qeth_l3_stop(card->dev); | |
46 | else { | |
47 | - rtnl_lock(); | |
48 | - dev_close(card->dev); | |
49 | - rtnl_unlock(); | |
50 | + if (card->dev) { | |
51 | + rtnl_lock(); | |
52 | + dev_close(card->dev); | |
53 | + rtnl_unlock(); | |
54 | + } | |
55 | } | |
56 | if (!card->use_hard_stop) { | |
57 | rc = qeth_send_stoplan(card); | |
58 | Index: linux-sles11/Documentation/kmsg/s390/qeth | |
59 | =================================================================== | |
60 | --- linux-sles11.orig/Documentation/kmsg/s390/qeth | |
61 | +++ linux-sles11/Documentation/kmsg/s390/qeth | |
62 | @@ -438,6 +438,20 @@ | |
63 | */ | |
64 | ||
65 | /*? | |
66 | + * Text: "%s: The qeth device is not configured for the OSI layer required by z/VM\n" | |
67 | + * Severity: Error | |
68 | + * Description: | |
69 | + * A qeth device that connects to a virtual network on z/VM must be configured for the | |
70 | + * same Open Systems Interconnection (OSI) layer as the virtual network. An ETHERNET | |
71 | + * guest LAN or VSWITCH uses the data link layer (layer 2) while an IP guest LAN | |
72 | + * or VSWITCH uses the network layer (layer 3). | |
73 | + * User action: | |
74 | + * If you are connecting to an ETHERNET guest LAN or VSWITCH, set the layer2 sysfs | |
75 | + * attribute of the qeth device to 1. If you are connecting to an IP guest LAN or | |
76 | + * VSWITCH, set the layer2 sysfs attribute of the qeth device to 0. | |
77 | + */ | |
78 | + | |
79 | +/*? | |
80 | * Text: "%s: Starting source MAC-address support for %s failed\n" | |
81 | * Severity: Warning | |
82 | * Parameter: | |
83 | Index: linux-sles11/drivers/s390/net/qeth_l2_main.c | |
84 | =================================================================== | |
85 | --- linux-sles11.orig/drivers/s390/net/qeth_l2_main.c | |
86 | +++ linux-sles11/drivers/s390/net/qeth_l2_main.c | |
87 | @@ -1139,9 +1139,11 @@ static int qeth_l2_recover(void *ptr) | |
88 | dev_info(&card->gdev->dev, | |
89 | "Device successfully recovered!\n"); | |
90 | else { | |
91 | - rtnl_lock(); | |
92 | - dev_close(card->dev); | |
93 | - rtnl_unlock(); | |
94 | + if (card->dev) { | |
95 | + rtnl_lock(); | |
96 | + dev_close(card->dev); | |
97 | + rtnl_unlock(); | |
98 | + } | |
99 | dev_warn(&card->gdev->dev, "The qeth device driver " | |
100 | "failed to recover an error on the device\n"); | |
101 | } |