1 |
commit: 387de4a9273f6e5a4bc69bbc9bcf5d4f4bdce3ea |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Aug 9 17:47:28 2019 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Aug 9 17:47:28 2019 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=387de4a9 |
7 |
|
8 |
Linux patch 5.2.8 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1007_linux-5.2.8.patch | 2838 ++++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 2842 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 139084e..6e8d29d 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -71,6 +71,10 @@ Patch: 1006_linux-5.2.7.patch |
21 |
From: https://www.kernel.org |
22 |
Desc: Linux 5.2.7 |
23 |
|
24 |
+Patch: 1007_linux-5.2.8.patch |
25 |
+From: https://www.kernel.org |
26 |
+Desc: Linux 5.2.8 |
27 |
+ |
28 |
Patch: 1500_XATTR_USER_PREFIX.patch |
29 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
30 |
Desc: Support for namespace user.pax.* on tmpfs. |
31 |
|
32 |
diff --git a/1007_linux-5.2.8.patch b/1007_linux-5.2.8.patch |
33 |
new file mode 100644 |
34 |
index 0000000..25fd638 |
35 |
--- /dev/null |
36 |
+++ b/1007_linux-5.2.8.patch |
37 |
@@ -0,0 +1,2838 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index 359a6b49e576..bad87c4c8117 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,7 +1,7 @@ |
43 |
+ # SPDX-License-Identifier: GPL-2.0 |
44 |
+ VERSION = 5 |
45 |
+ PATCHLEVEL = 2 |
46 |
+-SUBLEVEL = 7 |
47 |
++SUBLEVEL = 8 |
48 |
+ EXTRAVERSION = |
49 |
+ NAME = Bobtail Squid |
50 |
+ |
51 |
+diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c |
52 |
+index 302cf0ba1600..8c7a996d1f16 100644 |
53 |
+--- a/drivers/atm/iphase.c |
54 |
++++ b/drivers/atm/iphase.c |
55 |
+@@ -63,6 +63,7 @@ |
56 |
+ #include <asm/byteorder.h> |
57 |
+ #include <linux/vmalloc.h> |
58 |
+ #include <linux/jiffies.h> |
59 |
++#include <linux/nospec.h> |
60 |
+ #include "iphase.h" |
61 |
+ #include "suni.h" |
62 |
+ #define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8)) |
63 |
+@@ -2760,8 +2761,11 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) |
64 |
+ } |
65 |
+ if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; |
66 |
+ board = ia_cmds.status; |
67 |
+- if ((board < 0) || (board > iadev_count)) |
68 |
+- board = 0; |
69 |
++ |
70 |
++ if ((board < 0) || (board > iadev_count)) |
71 |
++ board = 0; |
72 |
++ board = array_index_nospec(board, iadev_count + 1); |
73 |
++ |
74 |
+ iadev = ia_dev[board]; |
75 |
+ switch (ia_cmds.cmd) { |
76 |
+ case MEMDUMP: |
77 |
+diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c |
78 |
+index 1dc8d03ff127..ee6fa75d65a2 100644 |
79 |
+--- a/drivers/gpu/drm/i915/intel_bios.c |
80 |
++++ b/drivers/gpu/drm/i915/intel_bios.c |
81 |
+@@ -762,7 +762,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) |
82 |
+ } |
83 |
+ |
84 |
+ if (bdb->version >= 226) { |
85 |
+- u32 wakeup_time = psr_table->psr2_tp2_tp3_wakeup_time; |
86 |
++ u32 wakeup_time = psr->psr2_tp2_tp3_wakeup_time; |
87 |
+ |
88 |
+ wakeup_time = (wakeup_time >> (2 * panel_type)) & 0x3; |
89 |
+ switch (wakeup_time) { |
90 |
+diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h |
91 |
+index fdbbb9a53804..796c070bbe6f 100644 |
92 |
+--- a/drivers/gpu/drm/i915/intel_vbt_defs.h |
93 |
++++ b/drivers/gpu/drm/i915/intel_vbt_defs.h |
94 |
+@@ -772,13 +772,13 @@ struct psr_table { |
95 |
+ /* TP wake up time in multiple of 100 */ |
96 |
+ u16 tp1_wakeup_time; |
97 |
+ u16 tp2_tp3_wakeup_time; |
98 |
+- |
99 |
+- /* PSR2 TP2/TP3 wakeup time for 16 panels */ |
100 |
+- u32 psr2_tp2_tp3_wakeup_time; |
101 |
+ } __packed; |
102 |
+ |
103 |
+ struct bdb_psr { |
104 |
+ struct psr_table psr_table[16]; |
105 |
++ |
106 |
++ /* PSR2 TP2/TP3 wakeup time for 16 panels */ |
107 |
++ u32 psr2_tp2_tp3_wakeup_time; |
108 |
+ } __packed; |
109 |
+ |
110 |
+ /* |
111 |
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h |
112 |
+index bfc584ada4eb..34a812025b94 100644 |
113 |
+--- a/drivers/hid/hid-ids.h |
114 |
++++ b/drivers/hid/hid-ids.h |
115 |
+@@ -568,6 +568,7 @@ |
116 |
+ #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a |
117 |
+ #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a |
118 |
+ #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a |
119 |
++#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641 |
120 |
+ |
121 |
+ #define USB_VENDOR_ID_HUION 0x256c |
122 |
+ #define USB_DEVICE_ID_HUION_TABLET 0x006e |
123 |
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c |
124 |
+index 1549c7a2f04c..5b669f7d653f 100644 |
125 |
+--- a/drivers/hid/hid-quirks.c |
126 |
++++ b/drivers/hid/hid-quirks.c |
127 |
+@@ -91,6 +91,7 @@ static const struct hid_device_id hid_quirks[] = { |
128 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL }, |
129 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, |
130 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL }, |
131 |
++ { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL }, |
132 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT }, |
133 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT }, |
134 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT }, |
135 |
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c |
136 |
+index 489436503e49..926c597f5f46 100644 |
137 |
+--- a/drivers/hid/wacom_wac.c |
138 |
++++ b/drivers/hid/wacom_wac.c |
139 |
+@@ -533,14 +533,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) |
140 |
+ */ |
141 |
+ buttons = (data[4] << 1) | (data[3] & 0x01); |
142 |
+ } else if (features->type == CINTIQ_COMPANION_2) { |
143 |
+- /* d-pad right -> data[4] & 0x10 |
144 |
+- * d-pad up -> data[4] & 0x20 |
145 |
+- * d-pad left -> data[4] & 0x40 |
146 |
+- * d-pad down -> data[4] & 0x80 |
147 |
+- * d-pad center -> data[3] & 0x01 |
148 |
++ /* d-pad right -> data[2] & 0x10 |
149 |
++ * d-pad up -> data[2] & 0x20 |
150 |
++ * d-pad left -> data[2] & 0x40 |
151 |
++ * d-pad down -> data[2] & 0x80 |
152 |
++ * d-pad center -> data[1] & 0x01 |
153 |
+ */ |
154 |
+ buttons = ((data[2] >> 4) << 7) | |
155 |
+- ((data[1] & 0x04) << 6) | |
156 |
++ ((data[1] & 0x04) << 4) | |
157 |
+ ((data[2] & 0x0F) << 2) | |
158 |
+ (data[1] & 0x03); |
159 |
+ } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { |
160 |
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |
161 |
+index bf39fc83d577..4039a9599d79 100644 |
162 |
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |
163 |
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |
164 |
+@@ -1934,8 +1934,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, |
165 |
+ } |
166 |
+ |
167 |
+ /* select a non-FCoE queue */ |
168 |
+- return netdev_pick_tx(dev, skb, NULL) % |
169 |
+- (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos); |
170 |
++ return netdev_pick_tx(dev, skb, NULL) % (BNX2X_NUM_ETH_QUEUES(bp)); |
171 |
+ } |
172 |
+ |
173 |
+ void bnx2x_set_num_queues(struct bnx2x *bp) |
174 |
+diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c |
175 |
+index ee7857298361..aca878a3f81f 100644 |
176 |
+--- a/drivers/net/ethernet/marvell/mvmdio.c |
177 |
++++ b/drivers/net/ethernet/marvell/mvmdio.c |
178 |
+@@ -319,15 +319,31 @@ static int orion_mdio_probe(struct platform_device *pdev) |
179 |
+ |
180 |
+ init_waitqueue_head(&dev->smi_busy_wait); |
181 |
+ |
182 |
+- for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { |
183 |
+- dev->clk[i] = of_clk_get(pdev->dev.of_node, i); |
184 |
+- if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) { |
185 |
++ if (pdev->dev.of_node) { |
186 |
++ for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { |
187 |
++ dev->clk[i] = of_clk_get(pdev->dev.of_node, i); |
188 |
++ if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) { |
189 |
++ ret = -EPROBE_DEFER; |
190 |
++ goto out_clk; |
191 |
++ } |
192 |
++ if (IS_ERR(dev->clk[i])) |
193 |
++ break; |
194 |
++ clk_prepare_enable(dev->clk[i]); |
195 |
++ } |
196 |
++ |
197 |
++ if (!IS_ERR(of_clk_get(pdev->dev.of_node, |
198 |
++ ARRAY_SIZE(dev->clk)))) |
199 |
++ dev_warn(&pdev->dev, |
200 |
++ "unsupported number of clocks, limiting to the first " |
201 |
++ __stringify(ARRAY_SIZE(dev->clk)) "\n"); |
202 |
++ } else { |
203 |
++ dev->clk[0] = clk_get(&pdev->dev, NULL); |
204 |
++ if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) { |
205 |
+ ret = -EPROBE_DEFER; |
206 |
+ goto out_clk; |
207 |
+ } |
208 |
+- if (IS_ERR(dev->clk[i])) |
209 |
+- break; |
210 |
+- clk_prepare_enable(dev->clk[i]); |
211 |
++ if (!IS_ERR(dev->clk[0])) |
212 |
++ clk_prepare_enable(dev->clk[0]); |
213 |
+ } |
214 |
+ |
215 |
+ dev->err_interrupt = platform_get_irq(pdev, 0); |
216 |
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c |
217 |
+index d8e5241097a9..50ed1bdb632d 100644 |
218 |
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c |
219 |
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c |
220 |
+@@ -3609,6 +3609,7 @@ static int mvpp2_set_mac_address(struct net_device *dev, void *p) |
221 |
+ static int mvpp2_change_mtu(struct net_device *dev, int mtu) |
222 |
+ { |
223 |
+ struct mvpp2_port *port = netdev_priv(dev); |
224 |
++ bool running = netif_running(dev); |
225 |
+ int err; |
226 |
+ |
227 |
+ if (!IS_ALIGNED(MVPP2_RX_PKT_SIZE(mtu), 8)) { |
228 |
+@@ -3617,40 +3618,24 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu) |
229 |
+ mtu = ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8); |
230 |
+ } |
231 |
+ |
232 |
+- if (!netif_running(dev)) { |
233 |
+- err = mvpp2_bm_update_mtu(dev, mtu); |
234 |
+- if (!err) { |
235 |
+- port->pkt_size = MVPP2_RX_PKT_SIZE(mtu); |
236 |
+- return 0; |
237 |
+- } |
238 |
+- |
239 |
+- /* Reconfigure BM to the original MTU */ |
240 |
+- err = mvpp2_bm_update_mtu(dev, dev->mtu); |
241 |
+- if (err) |
242 |
+- goto log_error; |
243 |
+- } |
244 |
+- |
245 |
+- mvpp2_stop_dev(port); |
246 |
++ if (running) |
247 |
++ mvpp2_stop_dev(port); |
248 |
+ |
249 |
+ err = mvpp2_bm_update_mtu(dev, mtu); |
250 |
+- if (!err) { |
251 |
++ if (err) { |
252 |
++ netdev_err(dev, "failed to change MTU\n"); |
253 |
++ /* Reconfigure BM to the original MTU */ |
254 |
++ mvpp2_bm_update_mtu(dev, dev->mtu); |
255 |
++ } else { |
256 |
+ port->pkt_size = MVPP2_RX_PKT_SIZE(mtu); |
257 |
+- goto out_start; |
258 |
+ } |
259 |
+ |
260 |
+- /* Reconfigure BM to the original MTU */ |
261 |
+- err = mvpp2_bm_update_mtu(dev, dev->mtu); |
262 |
+- if (err) |
263 |
+- goto log_error; |
264 |
+- |
265 |
+-out_start: |
266 |
+- mvpp2_start_dev(port); |
267 |
+- mvpp2_egress_enable(port); |
268 |
+- mvpp2_ingress_enable(port); |
269 |
++ if (running) { |
270 |
++ mvpp2_start_dev(port); |
271 |
++ mvpp2_egress_enable(port); |
272 |
++ mvpp2_ingress_enable(port); |
273 |
++ } |
274 |
+ |
275 |
+- return 0; |
276 |
+-log_error: |
277 |
+- netdev_err(dev, "failed to change MTU\n"); |
278 |
+ return err; |
279 |
+ } |
280 |
+ |
281 |
+@@ -5609,9 +5594,6 @@ static int mvpp2_remove(struct platform_device *pdev) |
282 |
+ |
283 |
+ mvpp2_dbgfs_cleanup(priv); |
284 |
+ |
285 |
+- flush_workqueue(priv->stats_queue); |
286 |
+- destroy_workqueue(priv->stats_queue); |
287 |
+- |
288 |
+ fwnode_for_each_available_child_node(fwnode, port_fwnode) { |
289 |
+ if (priv->port_list[i]) { |
290 |
+ mutex_destroy(&priv->port_list[i]->gather_stats_lock); |
291 |
+@@ -5620,6 +5602,8 @@ static int mvpp2_remove(struct platform_device *pdev) |
292 |
+ i++; |
293 |
+ } |
294 |
+ |
295 |
++ destroy_workqueue(priv->stats_queue); |
296 |
++ |
297 |
+ for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) { |
298 |
+ struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i]; |
299 |
+ |
300 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c |
301 |
+index f6b1da99e6c2..ba5f46da1c5c 100644 |
302 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c |
303 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c |
304 |
+@@ -213,7 +213,7 @@ void mlx5_unregister_device(struct mlx5_core_dev *dev) |
305 |
+ struct mlx5_interface *intf; |
306 |
+ |
307 |
+ mutex_lock(&mlx5_intf_mutex); |
308 |
+- list_for_each_entry(intf, &intf_list, list) |
309 |
++ list_for_each_entry_reverse(intf, &intf_list, list) |
310 |
+ mlx5_remove_device(intf, priv); |
311 |
+ list_del(&priv->dev_list); |
312 |
+ mutex_unlock(&mlx5_intf_mutex); |
313 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c |
314 |
+index d5e5afbdca6d..f777994f3005 100644 |
315 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c |
316 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c |
317 |
+@@ -78,9 +78,10 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = { |
318 |
+ }; |
319 |
+ |
320 |
+ static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev, |
321 |
+- const u32 **arr, u32 *size) |
322 |
++ const u32 **arr, u32 *size, |
323 |
++ bool force_legacy) |
324 |
+ { |
325 |
+- bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
326 |
++ bool ext = force_legacy ? false : MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
327 |
+ |
328 |
+ *size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) : |
329 |
+ ARRAY_SIZE(mlx5e_link_speed); |
330 |
+@@ -152,7 +153,8 @@ int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable, |
331 |
+ sizeof(out), MLX5_REG_PTYS, 0, 1); |
332 |
+ } |
333 |
+ |
334 |
+-u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper) |
335 |
++u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper, |
336 |
++ bool force_legacy) |
337 |
+ { |
338 |
+ unsigned long temp = eth_proto_oper; |
339 |
+ const u32 *table; |
340 |
+@@ -160,7 +162,7 @@ u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper) |
341 |
+ u32 max_size; |
342 |
+ int i; |
343 |
+ |
344 |
+- mlx5e_port_get_speed_arr(mdev, &table, &max_size); |
345 |
++ mlx5e_port_get_speed_arr(mdev, &table, &max_size, force_legacy); |
346 |
+ i = find_first_bit(&temp, max_size); |
347 |
+ if (i < max_size) |
348 |
+ speed = table[i]; |
349 |
+@@ -170,6 +172,7 @@ u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper) |
350 |
+ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) |
351 |
+ { |
352 |
+ struct mlx5e_port_eth_proto eproto; |
353 |
++ bool force_legacy = false; |
354 |
+ bool ext; |
355 |
+ int err; |
356 |
+ |
357 |
+@@ -177,8 +180,13 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) |
358 |
+ err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); |
359 |
+ if (err) |
360 |
+ goto out; |
361 |
+- |
362 |
+- *speed = mlx5e_port_ptys2speed(mdev, eproto.oper); |
363 |
++ if (ext && !eproto.admin) { |
364 |
++ force_legacy = true; |
365 |
++ err = mlx5_port_query_eth_proto(mdev, 1, false, &eproto); |
366 |
++ if (err) |
367 |
++ goto out; |
368 |
++ } |
369 |
++ *speed = mlx5e_port_ptys2speed(mdev, eproto.oper, force_legacy); |
370 |
+ if (!(*speed)) |
371 |
+ err = -EINVAL; |
372 |
+ |
373 |
+@@ -201,7 +209,7 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) |
374 |
+ if (err) |
375 |
+ return err; |
376 |
+ |
377 |
+- mlx5e_port_get_speed_arr(mdev, &table, &max_size); |
378 |
++ mlx5e_port_get_speed_arr(mdev, &table, &max_size, false); |
379 |
+ for (i = 0; i < max_size; ++i) |
380 |
+ if (eproto.cap & MLX5E_PROT_MASK(i)) |
381 |
+ max_speed = max(max_speed, table[i]); |
382 |
+@@ -210,14 +218,15 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) |
383 |
+ return 0; |
384 |
+ } |
385 |
+ |
386 |
+-u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed) |
387 |
++u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed, |
388 |
++ bool force_legacy) |
389 |
+ { |
390 |
+ u32 link_modes = 0; |
391 |
+ const u32 *table; |
392 |
+ u32 max_size; |
393 |
+ int i; |
394 |
+ |
395 |
+- mlx5e_port_get_speed_arr(mdev, &table, &max_size); |
396 |
++ mlx5e_port_get_speed_arr(mdev, &table, &max_size, force_legacy); |
397 |
+ for (i = 0; i < max_size; ++i) { |
398 |
+ if (table[i] == speed) |
399 |
+ link_modes |= MLX5E_PROT_MASK(i); |
400 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h |
401 |
+index 70f536ec51c4..4a7f4497692b 100644 |
402 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h |
403 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h |
404 |
+@@ -48,10 +48,12 @@ void mlx5_port_query_eth_autoneg(struct mlx5_core_dev *dev, u8 *an_status, |
405 |
+ u8 *an_disable_cap, u8 *an_disable_admin); |
406 |
+ int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable, |
407 |
+ u32 proto_admin, bool ext); |
408 |
+-u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper); |
409 |
++u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper, |
410 |
++ bool force_legacy); |
411 |
+ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); |
412 |
+ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); |
413 |
+-u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed); |
414 |
++u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed, |
415 |
++ bool force_legacy); |
416 |
+ |
417 |
+ int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out); |
418 |
+ int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in); |
419 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
420 |
+index dd764e0471f2..f637d81f08bc 100644 |
421 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
422 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
423 |
+@@ -764,7 +764,7 @@ static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings |
424 |
+ } |
425 |
+ |
426 |
+ static void get_speed_duplex(struct net_device *netdev, |
427 |
+- u32 eth_proto_oper, |
428 |
++ u32 eth_proto_oper, bool force_legacy, |
429 |
+ struct ethtool_link_ksettings *link_ksettings) |
430 |
+ { |
431 |
+ struct mlx5e_priv *priv = netdev_priv(netdev); |
432 |
+@@ -774,7 +774,7 @@ static void get_speed_duplex(struct net_device *netdev, |
433 |
+ if (!netif_carrier_ok(netdev)) |
434 |
+ goto out; |
435 |
+ |
436 |
+- speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper); |
437 |
++ speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper, force_legacy); |
438 |
+ if (!speed) { |
439 |
+ speed = SPEED_UNKNOWN; |
440 |
+ goto out; |
441 |
+@@ -893,8 +893,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, |
442 |
+ /* Fields: eth_proto_admin and ext_eth_proto_admin are |
443 |
+ * mutually exclusive. Hence try reading legacy advertising |
444 |
+ * when extended advertising is zero. |
445 |
+- * admin_ext indicates how eth_proto_admin should be |
446 |
+- * interpreted |
447 |
++ * admin_ext indicates which proto_admin (ext vs. legacy) |
448 |
++ * should be read and interpreted |
449 |
+ */ |
450 |
+ admin_ext = ext; |
451 |
+ if (ext && !eth_proto_admin) { |
452 |
+@@ -903,7 +903,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, |
453 |
+ admin_ext = false; |
454 |
+ } |
455 |
+ |
456 |
+- eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, |
457 |
++ eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, admin_ext, |
458 |
+ eth_proto_oper); |
459 |
+ eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise); |
460 |
+ an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin); |
461 |
+@@ -918,7 +918,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, |
462 |
+ get_supported(mdev, eth_proto_cap, link_ksettings); |
463 |
+ get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings, |
464 |
+ admin_ext); |
465 |
+- get_speed_duplex(priv->netdev, eth_proto_oper, link_ksettings); |
466 |
++ get_speed_duplex(priv->netdev, eth_proto_oper, !admin_ext, |
467 |
++ link_ksettings); |
468 |
+ |
469 |
+ eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap; |
470 |
+ |
471 |
+@@ -995,45 +996,69 @@ static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes) |
472 |
+ return ptys_modes; |
473 |
+ } |
474 |
+ |
475 |
++static bool ext_link_mode_requested(const unsigned long *adver) |
476 |
++{ |
477 |
++#define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT |
478 |
++ int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT; |
479 |
++ __ETHTOOL_DECLARE_LINK_MODE_MASK(modes); |
480 |
++ |
481 |
++ bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size); |
482 |
++ return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS); |
483 |
++} |
484 |
++ |
485 |
++static bool ext_speed_requested(u32 speed) |
486 |
++{ |
487 |
++#define MLX5E_MAX_PTYS_LEGACY_SPEED 100000 |
488 |
++ return !!(speed > MLX5E_MAX_PTYS_LEGACY_SPEED); |
489 |
++} |
490 |
++ |
491 |
++static bool ext_requested(u8 autoneg, const unsigned long *adver, u32 speed) |
492 |
++{ |
493 |
++ bool ext_link_mode = ext_link_mode_requested(adver); |
494 |
++ bool ext_speed = ext_speed_requested(speed); |
495 |
++ |
496 |
++ return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_speed; |
497 |
++} |
498 |
++ |
499 |
+ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, |
500 |
+ const struct ethtool_link_ksettings *link_ksettings) |
501 |
+ { |
502 |
+ struct mlx5_core_dev *mdev = priv->mdev; |
503 |
+ struct mlx5e_port_eth_proto eproto; |
504 |
++ const unsigned long *adver; |
505 |
+ bool an_changes = false; |
506 |
+ u8 an_disable_admin; |
507 |
+ bool ext_supported; |
508 |
+- bool ext_requested; |
509 |
+ u8 an_disable_cap; |
510 |
+ bool an_disable; |
511 |
+ u32 link_modes; |
512 |
+ u8 an_status; |
513 |
++ u8 autoneg; |
514 |
+ u32 speed; |
515 |
++ bool ext; |
516 |
+ int err; |
517 |
+ |
518 |
+ u32 (*ethtool2ptys_adver_func)(const unsigned long *adver); |
519 |
+ |
520 |
+-#define MLX5E_PTYS_EXT ((1ULL << ETHTOOL_LINK_MODE_50000baseKR_Full_BIT) - 1) |
521 |
++ adver = link_ksettings->link_modes.advertising; |
522 |
++ autoneg = link_ksettings->base.autoneg; |
523 |
++ speed = link_ksettings->base.speed; |
524 |
+ |
525 |
+- ext_requested = !!(link_ksettings->link_modes.advertising[0] > |
526 |
+- MLX5E_PTYS_EXT || |
527 |
+- link_ksettings->link_modes.advertising[1]); |
528 |
++ ext = ext_requested(autoneg, adver, speed), |
529 |
+ ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
530 |
+- ext_requested &= ext_supported; |
531 |
++ if (!ext_supported && ext) |
532 |
++ return -EOPNOTSUPP; |
533 |
+ |
534 |
+- speed = link_ksettings->base.speed; |
535 |
+- ethtool2ptys_adver_func = ext_requested ? |
536 |
+- mlx5e_ethtool2ptys_ext_adver_link : |
537 |
++ ethtool2ptys_adver_func = ext ? mlx5e_ethtool2ptys_ext_adver_link : |
538 |
+ mlx5e_ethtool2ptys_adver_link; |
539 |
+- err = mlx5_port_query_eth_proto(mdev, 1, ext_requested, &eproto); |
540 |
++ err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); |
541 |
+ if (err) { |
542 |
+ netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n", |
543 |
+ __func__, err); |
544 |
+ goto out; |
545 |
+ } |
546 |
+- link_modes = link_ksettings->base.autoneg == AUTONEG_ENABLE ? |
547 |
+- ethtool2ptys_adver_func(link_ksettings->link_modes.advertising) : |
548 |
+- mlx5e_port_speed2linkmodes(mdev, speed); |
549 |
++ link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : |
550 |
++ mlx5e_port_speed2linkmodes(mdev, speed, !ext); |
551 |
+ |
552 |
+ link_modes = link_modes & eproto.cap; |
553 |
+ if (!link_modes) { |
554 |
+@@ -1046,14 +1071,14 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, |
555 |
+ mlx5_port_query_eth_autoneg(mdev, &an_status, &an_disable_cap, |
556 |
+ &an_disable_admin); |
557 |
+ |
558 |
+- an_disable = link_ksettings->base.autoneg == AUTONEG_DISABLE; |
559 |
++ an_disable = autoneg == AUTONEG_DISABLE; |
560 |
+ an_changes = ((!an_disable && an_disable_admin) || |
561 |
+ (an_disable && !an_disable_admin)); |
562 |
+ |
563 |
+ if (!an_changes && link_modes == eproto.admin) |
564 |
+ goto out; |
565 |
+ |
566 |
+- mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext_requested); |
567 |
++ mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext); |
568 |
+ mlx5_toggle_port_link(mdev); |
569 |
+ |
570 |
+ out: |
571 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
572 |
+index a44c24280128..882d26b8095d 100644 |
573 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
574 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
575 |
+@@ -340,12 +340,11 @@ static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix) |
576 |
+ |
577 |
+ static void mlx5e_init_frags_partition(struct mlx5e_rq *rq) |
578 |
+ { |
579 |
+- struct mlx5e_wqe_frag_info next_frag, *prev; |
580 |
++ struct mlx5e_wqe_frag_info next_frag = {}; |
581 |
++ struct mlx5e_wqe_frag_info *prev = NULL; |
582 |
+ int i; |
583 |
+ |
584 |
+ next_frag.di = &rq->wqe.di[0]; |
585 |
+- next_frag.offset = 0; |
586 |
+- prev = NULL; |
587 |
+ |
588 |
+ for (i = 0; i < mlx5_wq_cyc_get_size(&rq->wqe.wq); i++) { |
589 |
+ struct mlx5e_rq_frag_info *frag_info = &rq->wqe.info.arr[0]; |
590 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c |
591 |
+index e40c60d1631f..ee95f96ead4e 100644 |
592 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c |
593 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c |
594 |
+@@ -1210,13 +1210,13 @@ static struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow) |
595 |
+ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) |
596 |
+ { |
597 |
+ struct mlx5e_neigh *m_neigh = &nhe->m_neigh; |
598 |
+- u64 bytes, packets, lastuse = 0; |
599 |
+ struct mlx5e_tc_flow *flow; |
600 |
+ struct mlx5e_encap_entry *e; |
601 |
+ struct mlx5_fc *counter; |
602 |
+ struct neigh_table *tbl; |
603 |
+ bool neigh_used = false; |
604 |
+ struct neighbour *n; |
605 |
++ u64 lastuse; |
606 |
+ |
607 |
+ if (m_neigh->family == AF_INET) |
608 |
+ tbl = &arp_tbl; |
609 |
+@@ -1236,7 +1236,7 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) |
610 |
+ encaps[efi->index]); |
611 |
+ if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) { |
612 |
+ counter = mlx5e_tc_get_counter(flow); |
613 |
+- mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse); |
614 |
++ lastuse = mlx5_fc_query_lastuse(counter); |
615 |
+ if (time_after((unsigned long)lastuse, nhe->reported_lastuse)) { |
616 |
+ neigh_used = true; |
617 |
+ break; |
618 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h |
619 |
+index a08c3d09a50f..2664a05eee00 100644 |
620 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h |
621 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h |
622 |
+@@ -68,7 +68,7 @@ enum fs_flow_table_type { |
623 |
+ FS_FT_SNIFFER_RX = 0X5, |
624 |
+ FS_FT_SNIFFER_TX = 0X6, |
625 |
+ FS_FT_RDMA_RX = 0X7, |
626 |
+- FS_FT_MAX_TYPE = FS_FT_SNIFFER_TX, |
627 |
++ FS_FT_MAX_TYPE = FS_FT_RDMA_RX, |
628 |
+ }; |
629 |
+ |
630 |
+ enum fs_flow_table_op_mod { |
631 |
+@@ -274,7 +274,8 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev); |
632 |
+ (type == FS_FT_FDB) ? MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, cap) : \ |
633 |
+ (type == FS_FT_SNIFFER_RX) ? MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) : \ |
634 |
+ (type == FS_FT_SNIFFER_TX) ? MLX5_CAP_FLOWTABLE_SNIFFER_TX(mdev, cap) : \ |
635 |
+- (BUILD_BUG_ON_ZERO(FS_FT_SNIFFER_TX != FS_FT_MAX_TYPE))\ |
636 |
++ (type == FS_FT_RDMA_RX) ? MLX5_CAP_FLOWTABLE_RDMA_RX(mdev, cap) : \ |
637 |
++ (BUILD_BUG_ON_ZERO(FS_FT_RDMA_RX != FS_FT_MAX_TYPE))\ |
638 |
+ ) |
639 |
+ |
640 |
+ #endif |
641 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c |
642 |
+index c6c28f56aa29..add9db67028f 100644 |
643 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c |
644 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c |
645 |
+@@ -367,6 +367,11 @@ int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter, |
646 |
+ } |
647 |
+ EXPORT_SYMBOL(mlx5_fc_query); |
648 |
+ |
649 |
++u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter) |
650 |
++{ |
651 |
++ return counter->cache.lastuse; |
652 |
++} |
653 |
++ |
654 |
+ void mlx5_fc_query_cached(struct mlx5_fc *counter, |
655 |
+ u64 *bytes, u64 *packets, u64 *lastuse) |
656 |
+ { |
657 |
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c |
658 |
+index 23204356ad88..d51442e63aba 100644 |
659 |
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c |
660 |
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c |
661 |
+@@ -5989,7 +5989,7 @@ static int __init mlxsw_sp_module_init(void) |
662 |
+ return 0; |
663 |
+ |
664 |
+ err_sp2_pci_driver_register: |
665 |
+- mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver); |
666 |
++ mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver); |
667 |
+ err_sp1_pci_driver_register: |
668 |
+ mlxsw_core_driver_unregister(&mlxsw_sp2_driver); |
669 |
+ err_sp2_core_driver_register: |
670 |
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c |
671 |
+index 1537f70bc26d..888ba4300bcc 100644 |
672 |
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c |
673 |
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c |
674 |
+@@ -437,8 +437,8 @@ static const struct mlxsw_sp_sb_pr mlxsw_sp1_sb_prs[] = { |
675 |
+ MLXSW_SP1_SB_PR_CPU_SIZE, true, false), |
676 |
+ }; |
677 |
+ |
678 |
+-#define MLXSW_SP2_SB_PR_INGRESS_SIZE 38128752 |
679 |
+-#define MLXSW_SP2_SB_PR_EGRESS_SIZE 38128752 |
680 |
++#define MLXSW_SP2_SB_PR_INGRESS_SIZE 35297568 |
681 |
++#define MLXSW_SP2_SB_PR_EGRESS_SIZE 35297568 |
682 |
+ #define MLXSW_SP2_SB_PR_CPU_SIZE (256 * 1000) |
683 |
+ |
684 |
+ /* Order according to mlxsw_sp2_sb_pool_dess */ |
685 |
+diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c |
686 |
+index 02ad11e0b0d8..58e76e7cb0d6 100644 |
687 |
+--- a/drivers/net/ethernet/mscc/ocelot.c |
688 |
++++ b/drivers/net/ethernet/mscc/ocelot.c |
689 |
+@@ -1797,6 +1797,7 @@ EXPORT_SYMBOL(ocelot_init); |
690 |
+ |
691 |
+ void ocelot_deinit(struct ocelot *ocelot) |
692 |
+ { |
693 |
++ cancel_delayed_work(&ocelot->stats_work); |
694 |
+ destroy_workqueue(ocelot->stats_queue); |
695 |
+ mutex_destroy(&ocelot->stats_lock); |
696 |
+ } |
697 |
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h |
698 |
+index 4bf20d0651c4..90ad5694e2af 100644 |
699 |
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h |
700 |
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h |
701 |
+@@ -51,7 +51,7 @@ struct rmnet_map_dl_csum_trailer { |
702 |
+ struct rmnet_map_ul_csum_header { |
703 |
+ __be16 csum_start_offset; |
704 |
+ u16 csum_insert_offset:14; |
705 |
+- u16 udp_ip4_ind:1; |
706 |
++ u16 udp_ind:1; |
707 |
+ u16 csum_enabled:1; |
708 |
+ } __aligned(1); |
709 |
+ |
710 |
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c |
711 |
+index 60189923737a..21d38167f961 100644 |
712 |
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c |
713 |
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c |
714 |
+@@ -206,9 +206,9 @@ rmnet_map_ipv4_ul_csum_header(void *iphdr, |
715 |
+ ul_header->csum_insert_offset = skb->csum_offset; |
716 |
+ ul_header->csum_enabled = 1; |
717 |
+ if (ip4h->protocol == IPPROTO_UDP) |
718 |
+- ul_header->udp_ip4_ind = 1; |
719 |
++ ul_header->udp_ind = 1; |
720 |
+ else |
721 |
+- ul_header->udp_ip4_ind = 0; |
722 |
++ ul_header->udp_ind = 0; |
723 |
+ |
724 |
+ /* Changing remaining fields to network order */ |
725 |
+ hdr++; |
726 |
+@@ -239,6 +239,7 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr, |
727 |
+ struct rmnet_map_ul_csum_header *ul_header, |
728 |
+ struct sk_buff *skb) |
729 |
+ { |
730 |
++ struct ipv6hdr *ip6h = (struct ipv6hdr *)ip6hdr; |
731 |
+ __be16 *hdr = (__be16 *)ul_header, offset; |
732 |
+ |
733 |
+ offset = htons((__force u16)(skb_transport_header(skb) - |
734 |
+@@ -246,7 +247,11 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr, |
735 |
+ ul_header->csum_start_offset = offset; |
736 |
+ ul_header->csum_insert_offset = skb->csum_offset; |
737 |
+ ul_header->csum_enabled = 1; |
738 |
+- ul_header->udp_ip4_ind = 0; |
739 |
++ |
740 |
++ if (ip6h->nexthdr == IPPROTO_UDP) |
741 |
++ ul_header->udp_ind = 1; |
742 |
++ else |
743 |
++ ul_header->udp_ind = 0; |
744 |
+ |
745 |
+ /* Changing remaining fields to network order */ |
746 |
+ hdr++; |
747 |
+@@ -419,7 +424,7 @@ sw_csum: |
748 |
+ ul_header->csum_start_offset = 0; |
749 |
+ ul_header->csum_insert_offset = 0; |
750 |
+ ul_header->csum_enabled = 0; |
751 |
+- ul_header->udp_ip4_ind = 0; |
752 |
++ ul_header->udp_ind = 0; |
753 |
+ |
754 |
+ priv->stats.csum_sw++; |
755 |
+ } |
756 |
+diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c |
757 |
+index 96637fcbe65d..36261b2959b4 100644 |
758 |
+--- a/drivers/net/ethernet/realtek/r8169.c |
759 |
++++ b/drivers/net/ethernet/realtek/r8169.c |
760 |
+@@ -7050,13 +7050,18 @@ static int rtl_alloc_irq(struct rtl8169_private *tp) |
761 |
+ { |
762 |
+ unsigned int flags; |
763 |
+ |
764 |
+- if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { |
765 |
++ switch (tp->mac_version) { |
766 |
++ case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: |
767 |
+ rtl_unlock_config_regs(tp); |
768 |
+ RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); |
769 |
+ rtl_lock_config_regs(tp); |
770 |
++ /* fall through */ |
771 |
++ case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_24: |
772 |
+ flags = PCI_IRQ_LEGACY; |
773 |
+- } else { |
774 |
++ break; |
775 |
++ default: |
776 |
+ flags = PCI_IRQ_ALL_TYPES; |
777 |
++ break; |
778 |
+ } |
779 |
+ |
780 |
+ return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags); |
781 |
+diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c |
782 |
+index 3e5bc1fc3c46..c245a0f15066 100644 |
783 |
+--- a/drivers/net/ethernet/rocker/rocker_main.c |
784 |
++++ b/drivers/net/ethernet/rocker/rocker_main.c |
785 |
+@@ -2208,6 +2208,7 @@ static int rocker_router_fib_event(struct notifier_block *nb, |
786 |
+ |
787 |
+ if (fen_info->fi->fib_nh_is_v6) { |
788 |
+ NL_SET_ERR_MSG_MOD(info->extack, "IPv6 gateway with IPv4 route is not supported"); |
789 |
++ kfree(fib_work); |
790 |
+ return notifier_from_errno(-EINVAL); |
791 |
+ } |
792 |
+ } |
793 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
794 |
+index 932e54e25b71..b14f46a57154 100644 |
795 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
796 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
797 |
+@@ -4374,8 +4374,9 @@ int stmmac_dvr_probe(struct device *device, |
798 |
+ NAPI_POLL_WEIGHT); |
799 |
+ } |
800 |
+ if (queue < priv->plat->tx_queues_to_use) { |
801 |
+- netif_napi_add(ndev, &ch->tx_napi, stmmac_napi_poll_tx, |
802 |
+- NAPI_POLL_WEIGHT); |
803 |
++ netif_tx_napi_add(ndev, &ch->tx_napi, |
804 |
++ stmmac_napi_poll_tx, |
805 |
++ NAPI_POLL_WEIGHT); |
806 |
+ } |
807 |
+ } |
808 |
+ |
809 |
+diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c |
810 |
+index 3ffe46df249e..7c5265fd2b94 100644 |
811 |
+--- a/drivers/net/phy/fixed_phy.c |
812 |
++++ b/drivers/net/phy/fixed_phy.c |
813 |
+@@ -216,8 +216,10 @@ static struct gpio_desc *fixed_phy_get_gpiod(struct device_node *np) |
814 |
+ if (IS_ERR(gpiod)) { |
815 |
+ if (PTR_ERR(gpiod) == -EPROBE_DEFER) |
816 |
+ return gpiod; |
817 |
+- pr_err("error getting GPIO for fixed link %pOF, proceed without\n", |
818 |
+- fixed_link_node); |
819 |
++ |
820 |
++ if (PTR_ERR(gpiod) != -ENOENT) |
821 |
++ pr_err("error getting GPIO for fixed link %pOF, proceed without\n", |
822 |
++ fixed_link_node); |
823 |
+ gpiod = NULL; |
824 |
+ } |
825 |
+ |
826 |
+diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c |
827 |
+index 28676af97b42..645d354ffb48 100644 |
828 |
+--- a/drivers/net/phy/mscc.c |
829 |
++++ b/drivers/net/phy/mscc.c |
830 |
+@@ -2226,8 +2226,8 @@ static int vsc8514_probe(struct phy_device *phydev) |
831 |
+ vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; |
832 |
+ vsc8531->hw_stats = vsc85xx_hw_stats; |
833 |
+ vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); |
834 |
+- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, |
835 |
+- sizeof(u64), GFP_KERNEL); |
836 |
++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, |
837 |
++ sizeof(u64), GFP_KERNEL); |
838 |
+ if (!vsc8531->stats) |
839 |
+ return -ENOMEM; |
840 |
+ |
841 |
+@@ -2251,8 +2251,8 @@ static int vsc8574_probe(struct phy_device *phydev) |
842 |
+ vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; |
843 |
+ vsc8531->hw_stats = vsc8584_hw_stats; |
844 |
+ vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); |
845 |
+- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, |
846 |
+- sizeof(u64), GFP_KERNEL); |
847 |
++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, |
848 |
++ sizeof(u64), GFP_KERNEL); |
849 |
+ if (!vsc8531->stats) |
850 |
+ return -ENOMEM; |
851 |
+ |
852 |
+@@ -2281,8 +2281,8 @@ static int vsc8584_probe(struct phy_device *phydev) |
853 |
+ vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; |
854 |
+ vsc8531->hw_stats = vsc8584_hw_stats; |
855 |
+ vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); |
856 |
+- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, |
857 |
+- sizeof(u64), GFP_KERNEL); |
858 |
++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, |
859 |
++ sizeof(u64), GFP_KERNEL); |
860 |
+ if (!vsc8531->stats) |
861 |
+ return -ENOMEM; |
862 |
+ |
863 |
+@@ -2311,8 +2311,8 @@ static int vsc85xx_probe(struct phy_device *phydev) |
864 |
+ vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; |
865 |
+ vsc8531->hw_stats = vsc85xx_hw_stats; |
866 |
+ vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); |
867 |
+- vsc8531->stats = devm_kmalloc_array(&phydev->mdio.dev, vsc8531->nstats, |
868 |
+- sizeof(u64), GFP_KERNEL); |
869 |
++ vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, |
870 |
++ sizeof(u64), GFP_KERNEL); |
871 |
+ if (!vsc8531->stats) |
872 |
+ return -ENOMEM; |
873 |
+ |
874 |
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c |
875 |
+index a3f8740c6163..ffa402732aea 100644 |
876 |
+--- a/drivers/net/phy/phy_device.c |
877 |
++++ b/drivers/net/phy/phy_device.c |
878 |
+@@ -1730,6 +1730,12 @@ done: |
879 |
+ phydev->link = status & BMSR_LSTATUS ? 1 : 0; |
880 |
+ phydev->autoneg_complete = status & BMSR_ANEGCOMPLETE ? 1 : 0; |
881 |
+ |
882 |
++ /* Consider the case that autoneg was started and "aneg complete" |
883 |
++ * bit has been reset, but "link up" bit not yet. |
884 |
++ */ |
885 |
++ if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) |
886 |
++ phydev->link = 0; |
887 |
++ |
888 |
+ return 0; |
889 |
+ } |
890 |
+ EXPORT_SYMBOL(genphy_update_link); |
891 |
+diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c |
892 |
+index 4c0616ba314d..c45ee6e3fe01 100644 |
893 |
+--- a/drivers/net/phy/phylink.c |
894 |
++++ b/drivers/net/phy/phylink.c |
895 |
+@@ -195,6 +195,8 @@ static int phylink_parse_fixedlink(struct phylink *pl, |
896 |
+ pl->supported, true); |
897 |
+ linkmode_zero(pl->supported); |
898 |
+ phylink_set(pl->supported, MII); |
899 |
++ phylink_set(pl->supported, Pause); |
900 |
++ phylink_set(pl->supported, Asym_Pause); |
901 |
+ if (s) { |
902 |
+ __set_bit(s->bit, pl->supported); |
903 |
+ } else { |
904 |
+@@ -912,10 +914,10 @@ void phylink_start(struct phylink *pl) |
905 |
+ |
906 |
+ if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio)) |
907 |
+ mod_timer(&pl->link_poll, jiffies + HZ); |
908 |
+- if (pl->sfp_bus) |
909 |
+- sfp_upstream_start(pl->sfp_bus); |
910 |
+ if (pl->phydev) |
911 |
+ phy_start(pl->phydev); |
912 |
++ if (pl->sfp_bus) |
913 |
++ sfp_upstream_start(pl->sfp_bus); |
914 |
+ } |
915 |
+ EXPORT_SYMBOL_GPL(phylink_start); |
916 |
+ |
917 |
+@@ -932,10 +934,10 @@ void phylink_stop(struct phylink *pl) |
918 |
+ { |
919 |
+ ASSERT_RTNL(); |
920 |
+ |
921 |
+- if (pl->phydev) |
922 |
+- phy_stop(pl->phydev); |
923 |
+ if (pl->sfp_bus) |
924 |
+ sfp_upstream_stop(pl->sfp_bus); |
925 |
++ if (pl->phydev) |
926 |
++ phy_stop(pl->phydev); |
927 |
+ if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio)) |
928 |
+ del_timer_sync(&pl->link_poll); |
929 |
+ |
930 |
+diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c |
931 |
+index 1d902ecb4aa8..a44dd3c8af63 100644 |
932 |
+--- a/drivers/net/ppp/pppoe.c |
933 |
++++ b/drivers/net/ppp/pppoe.c |
934 |
+@@ -1115,6 +1115,9 @@ static const struct proto_ops pppoe_ops = { |
935 |
+ .recvmsg = pppoe_recvmsg, |
936 |
+ .mmap = sock_no_mmap, |
937 |
+ .ioctl = pppox_ioctl, |
938 |
++#ifdef CONFIG_COMPAT |
939 |
++ .compat_ioctl = pppox_compat_ioctl, |
940 |
++#endif |
941 |
+ }; |
942 |
+ |
943 |
+ static const struct pppox_proto pppoe_proto = { |
944 |
+diff --git a/drivers/net/ppp/pppox.c b/drivers/net/ppp/pppox.c |
945 |
+index 5ef422a43d70..08364f10a43f 100644 |
946 |
+--- a/drivers/net/ppp/pppox.c |
947 |
++++ b/drivers/net/ppp/pppox.c |
948 |
+@@ -17,6 +17,7 @@ |
949 |
+ #include <linux/string.h> |
950 |
+ #include <linux/module.h> |
951 |
+ #include <linux/kernel.h> |
952 |
++#include <linux/compat.h> |
953 |
+ #include <linux/errno.h> |
954 |
+ #include <linux/netdevice.h> |
955 |
+ #include <linux/net.h> |
956 |
+@@ -98,6 +99,18 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
957 |
+ |
958 |
+ EXPORT_SYMBOL(pppox_ioctl); |
959 |
+ |
960 |
++#ifdef CONFIG_COMPAT |
961 |
++int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
962 |
++{ |
963 |
++ if (cmd == PPPOEIOCSFWD32) |
964 |
++ cmd = PPPOEIOCSFWD; |
965 |
++ |
966 |
++ return pppox_ioctl(sock, cmd, (unsigned long)compat_ptr(arg)); |
967 |
++} |
968 |
++ |
969 |
++EXPORT_SYMBOL(pppox_compat_ioctl); |
970 |
++#endif |
971 |
++ |
972 |
+ static int pppox_create(struct net *net, struct socket *sock, int protocol, |
973 |
+ int kern) |
974 |
+ { |
975 |
+diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c |
976 |
+index a8e52c8e4128..734de7de03f7 100644 |
977 |
+--- a/drivers/net/ppp/pptp.c |
978 |
++++ b/drivers/net/ppp/pptp.c |
979 |
+@@ -623,6 +623,9 @@ static const struct proto_ops pptp_ops = { |
980 |
+ .recvmsg = sock_no_recvmsg, |
981 |
+ .mmap = sock_no_mmap, |
982 |
+ .ioctl = pppox_ioctl, |
983 |
++#ifdef CONFIG_COMPAT |
984 |
++ .compat_ioctl = pppox_compat_ioctl, |
985 |
++#endif |
986 |
+ }; |
987 |
+ |
988 |
+ static const struct pppox_proto pppox_pptp_proto = { |
989 |
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c |
990 |
+index d7c55e0fa8f4..192ac47fd055 100644 |
991 |
+--- a/drivers/net/tun.c |
992 |
++++ b/drivers/net/tun.c |
993 |
+@@ -1600,7 +1600,8 @@ static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile, |
994 |
+ return true; |
995 |
+ } |
996 |
+ |
997 |
+-static struct sk_buff *__tun_build_skb(struct page_frag *alloc_frag, char *buf, |
998 |
++static struct sk_buff *__tun_build_skb(struct tun_file *tfile, |
999 |
++ struct page_frag *alloc_frag, char *buf, |
1000 |
+ int buflen, int len, int pad) |
1001 |
+ { |
1002 |
+ struct sk_buff *skb = build_skb(buf, buflen); |
1003 |
+@@ -1610,6 +1611,7 @@ static struct sk_buff *__tun_build_skb(struct page_frag *alloc_frag, char *buf, |
1004 |
+ |
1005 |
+ skb_reserve(skb, pad); |
1006 |
+ skb_put(skb, len); |
1007 |
++ skb_set_owner_w(skb, tfile->socket.sk); |
1008 |
+ |
1009 |
+ get_page(alloc_frag->page); |
1010 |
+ alloc_frag->offset += buflen; |
1011 |
+@@ -1687,7 +1689,8 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, |
1012 |
+ */ |
1013 |
+ if (hdr->gso_type || !xdp_prog) { |
1014 |
+ *skb_xdp = 1; |
1015 |
+- return __tun_build_skb(alloc_frag, buf, buflen, len, pad); |
1016 |
++ return __tun_build_skb(tfile, alloc_frag, buf, buflen, len, |
1017 |
++ pad); |
1018 |
+ } |
1019 |
+ |
1020 |
+ *skb_xdp = 0; |
1021 |
+@@ -1724,7 +1727,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, |
1022 |
+ rcu_read_unlock(); |
1023 |
+ local_bh_enable(); |
1024 |
+ |
1025 |
+- return __tun_build_skb(alloc_frag, buf, buflen, len, pad); |
1026 |
++ return __tun_build_skb(tfile, alloc_frag, buf, buflen, len, pad); |
1027 |
+ |
1028 |
+ err_xdp: |
1029 |
+ put_page(alloc_frag->page); |
1030 |
+diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c |
1031 |
+index e65d027b91fa..529be35ac178 100644 |
1032 |
+--- a/drivers/nfc/nfcmrvl/main.c |
1033 |
++++ b/drivers/nfc/nfcmrvl/main.c |
1034 |
+@@ -244,7 +244,7 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv) |
1035 |
+ /* Reset possible fault of previous session */ |
1036 |
+ clear_bit(NFCMRVL_PHY_ERROR, &priv->flags); |
1037 |
+ |
1038 |
+- if (priv->config.reset_n_io) { |
1039 |
++ if (gpio_is_valid(priv->config.reset_n_io)) { |
1040 |
+ nfc_info(priv->dev, "reset the chip\n"); |
1041 |
+ gpio_set_value(priv->config.reset_n_io, 0); |
1042 |
+ usleep_range(5000, 10000); |
1043 |
+@@ -255,7 +255,7 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv) |
1044 |
+ |
1045 |
+ void nfcmrvl_chip_halt(struct nfcmrvl_private *priv) |
1046 |
+ { |
1047 |
+- if (priv->config.reset_n_io) |
1048 |
++ if (gpio_is_valid(priv->config.reset_n_io)) |
1049 |
+ gpio_set_value(priv->config.reset_n_io, 0); |
1050 |
+ } |
1051 |
+ |
1052 |
+diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c |
1053 |
+index 9a22056e8d9e..e5a622ce4b95 100644 |
1054 |
+--- a/drivers/nfc/nfcmrvl/uart.c |
1055 |
++++ b/drivers/nfc/nfcmrvl/uart.c |
1056 |
+@@ -26,7 +26,7 @@ |
1057 |
+ static unsigned int hci_muxed; |
1058 |
+ static unsigned int flow_control; |
1059 |
+ static unsigned int break_control; |
1060 |
+-static unsigned int reset_n_io; |
1061 |
++static int reset_n_io = -EINVAL; |
1062 |
+ |
1063 |
+ /* |
1064 |
+ ** NFCMRVL NCI OPS |
1065 |
+@@ -231,5 +231,5 @@ MODULE_PARM_DESC(break_control, "Tell if UART driver must drive break signal."); |
1066 |
+ module_param(hci_muxed, uint, 0); |
1067 |
+ MODULE_PARM_DESC(hci_muxed, "Tell if transport is muxed in HCI one."); |
1068 |
+ |
1069 |
+-module_param(reset_n_io, uint, 0); |
1070 |
++module_param(reset_n_io, int, 0); |
1071 |
+ MODULE_PARM_DESC(reset_n_io, "GPIO that is wired to RESET_N signal."); |
1072 |
+diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c |
1073 |
+index 945cc903d8f1..888e298f610b 100644 |
1074 |
+--- a/drivers/nfc/nfcmrvl/usb.c |
1075 |
++++ b/drivers/nfc/nfcmrvl/usb.c |
1076 |
+@@ -305,6 +305,7 @@ static int nfcmrvl_probe(struct usb_interface *intf, |
1077 |
+ |
1078 |
+ /* No configuration for USB */ |
1079 |
+ memset(&config, 0, sizeof(config)); |
1080 |
++ config.reset_n_io = -EINVAL; |
1081 |
+ |
1082 |
+ nfc_info(&udev->dev, "intf %p id %p\n", intf, id); |
1083 |
+ |
1084 |
+diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c |
1085 |
+index dfb93228d6a7..df41f3571dc9 100644 |
1086 |
+--- a/drivers/nvdimm/bus.c |
1087 |
++++ b/drivers/nvdimm/bus.c |
1088 |
+@@ -887,10 +887,12 @@ void wait_nvdimm_bus_probe_idle(struct device *dev) |
1089 |
+ do { |
1090 |
+ if (nvdimm_bus->probe_active == 0) |
1091 |
+ break; |
1092 |
+- nvdimm_bus_unlock(&nvdimm_bus->dev); |
1093 |
++ nvdimm_bus_unlock(dev); |
1094 |
++ device_unlock(dev); |
1095 |
+ wait_event(nvdimm_bus->wait, |
1096 |
+ nvdimm_bus->probe_active == 0); |
1097 |
+- nvdimm_bus_lock(&nvdimm_bus->dev); |
1098 |
++ device_lock(dev); |
1099 |
++ nvdimm_bus_lock(dev); |
1100 |
+ } while (true); |
1101 |
+ } |
1102 |
+ |
1103 |
+@@ -973,20 +975,19 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1104 |
+ int read_only, unsigned int ioctl_cmd, unsigned long arg) |
1105 |
+ { |
1106 |
+ struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; |
1107 |
+- static char out_env[ND_CMD_MAX_ENVELOPE]; |
1108 |
+- static char in_env[ND_CMD_MAX_ENVELOPE]; |
1109 |
+ const struct nd_cmd_desc *desc = NULL; |
1110 |
+ unsigned int cmd = _IOC_NR(ioctl_cmd); |
1111 |
+ struct device *dev = &nvdimm_bus->dev; |
1112 |
+ void __user *p = (void __user *) arg; |
1113 |
++ char *out_env = NULL, *in_env = NULL; |
1114 |
+ const char *cmd_name, *dimm_name; |
1115 |
+ u32 in_len = 0, out_len = 0; |
1116 |
+ unsigned int func = cmd; |
1117 |
+ unsigned long cmd_mask; |
1118 |
+ struct nd_cmd_pkg pkg; |
1119 |
+ int rc, i, cmd_rc; |
1120 |
++ void *buf = NULL; |
1121 |
+ u64 buf_len = 0; |
1122 |
+- void *buf; |
1123 |
+ |
1124 |
+ if (nvdimm) { |
1125 |
+ desc = nd_cmd_dimm_desc(cmd); |
1126 |
+@@ -1017,7 +1018,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1127 |
+ case ND_CMD_ARS_START: |
1128 |
+ case ND_CMD_CLEAR_ERROR: |
1129 |
+ case ND_CMD_CALL: |
1130 |
+- dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n", |
1131 |
++ dev_dbg(dev, "'%s' command while read-only.\n", |
1132 |
+ nvdimm ? nvdimm_cmd_name(cmd) |
1133 |
+ : nvdimm_bus_cmd_name(cmd)); |
1134 |
+ return -EPERM; |
1135 |
+@@ -1026,6 +1027,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1136 |
+ } |
1137 |
+ |
1138 |
+ /* process an input envelope */ |
1139 |
++ in_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); |
1140 |
++ if (!in_env) |
1141 |
++ return -ENOMEM; |
1142 |
+ for (i = 0; i < desc->in_num; i++) { |
1143 |
+ u32 in_size, copy; |
1144 |
+ |
1145 |
+@@ -1033,14 +1037,17 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1146 |
+ if (in_size == UINT_MAX) { |
1147 |
+ dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n", |
1148 |
+ __func__, dimm_name, cmd_name, i); |
1149 |
+- return -ENXIO; |
1150 |
++ rc = -ENXIO; |
1151 |
++ goto out; |
1152 |
+ } |
1153 |
+- if (in_len < sizeof(in_env)) |
1154 |
+- copy = min_t(u32, sizeof(in_env) - in_len, in_size); |
1155 |
++ if (in_len < ND_CMD_MAX_ENVELOPE) |
1156 |
++ copy = min_t(u32, ND_CMD_MAX_ENVELOPE - in_len, in_size); |
1157 |
+ else |
1158 |
+ copy = 0; |
1159 |
+- if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) |
1160 |
+- return -EFAULT; |
1161 |
++ if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) { |
1162 |
++ rc = -EFAULT; |
1163 |
++ goto out; |
1164 |
++ } |
1165 |
+ in_len += in_size; |
1166 |
+ } |
1167 |
+ |
1168 |
+@@ -1052,6 +1059,12 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1169 |
+ } |
1170 |
+ |
1171 |
+ /* process an output envelope */ |
1172 |
++ out_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); |
1173 |
++ if (!out_env) { |
1174 |
++ rc = -ENOMEM; |
1175 |
++ goto out; |
1176 |
++ } |
1177 |
++ |
1178 |
+ for (i = 0; i < desc->out_num; i++) { |
1179 |
+ u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, |
1180 |
+ (u32 *) in_env, (u32 *) out_env, 0); |
1181 |
+@@ -1060,15 +1073,18 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1182 |
+ if (out_size == UINT_MAX) { |
1183 |
+ dev_dbg(dev, "%s unknown output size cmd: %s field: %d\n", |
1184 |
+ dimm_name, cmd_name, i); |
1185 |
+- return -EFAULT; |
1186 |
++ rc = -EFAULT; |
1187 |
++ goto out; |
1188 |
+ } |
1189 |
+- if (out_len < sizeof(out_env)) |
1190 |
+- copy = min_t(u32, sizeof(out_env) - out_len, out_size); |
1191 |
++ if (out_len < ND_CMD_MAX_ENVELOPE) |
1192 |
++ copy = min_t(u32, ND_CMD_MAX_ENVELOPE - out_len, out_size); |
1193 |
+ else |
1194 |
+ copy = 0; |
1195 |
+ if (copy && copy_from_user(&out_env[out_len], |
1196 |
+- p + in_len + out_len, copy)) |
1197 |
+- return -EFAULT; |
1198 |
++ p + in_len + out_len, copy)) { |
1199 |
++ rc = -EFAULT; |
1200 |
++ goto out; |
1201 |
++ } |
1202 |
+ out_len += out_size; |
1203 |
+ } |
1204 |
+ |
1205 |
+@@ -1076,19 +1092,23 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1206 |
+ if (buf_len > ND_IOCTL_MAX_BUFLEN) { |
1207 |
+ dev_dbg(dev, "%s cmd: %s buf_len: %llu > %d\n", dimm_name, |
1208 |
+ cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN); |
1209 |
+- return -EINVAL; |
1210 |
++ rc = -EINVAL; |
1211 |
++ goto out; |
1212 |
+ } |
1213 |
+ |
1214 |
+ buf = vmalloc(buf_len); |
1215 |
+- if (!buf) |
1216 |
+- return -ENOMEM; |
1217 |
++ if (!buf) { |
1218 |
++ rc = -ENOMEM; |
1219 |
++ goto out; |
1220 |
++ } |
1221 |
+ |
1222 |
+ if (copy_from_user(buf, p, buf_len)) { |
1223 |
+ rc = -EFAULT; |
1224 |
+ goto out; |
1225 |
+ } |
1226 |
+ |
1227 |
+- nvdimm_bus_lock(&nvdimm_bus->dev); |
1228 |
++ device_lock(dev); |
1229 |
++ nvdimm_bus_lock(dev); |
1230 |
+ rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf); |
1231 |
+ if (rc) |
1232 |
+ goto out_unlock; |
1233 |
+@@ -1103,17 +1123,16 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, |
1234 |
+ nvdimm_account_cleared_poison(nvdimm_bus, clear_err->address, |
1235 |
+ clear_err->cleared); |
1236 |
+ } |
1237 |
+- nvdimm_bus_unlock(&nvdimm_bus->dev); |
1238 |
+ |
1239 |
+ if (copy_to_user(p, buf, buf_len)) |
1240 |
+ rc = -EFAULT; |
1241 |
+ |
1242 |
+- vfree(buf); |
1243 |
+- return rc; |
1244 |
+- |
1245 |
+- out_unlock: |
1246 |
+- nvdimm_bus_unlock(&nvdimm_bus->dev); |
1247 |
+- out: |
1248 |
++out_unlock: |
1249 |
++ nvdimm_bus_unlock(dev); |
1250 |
++ device_unlock(dev); |
1251 |
++out: |
1252 |
++ kfree(in_env); |
1253 |
++ kfree(out_env); |
1254 |
+ vfree(buf); |
1255 |
+ return rc; |
1256 |
+ } |
1257 |
+diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c |
1258 |
+index 4fed9ce9c2fe..a15276cdec7d 100644 |
1259 |
+--- a/drivers/nvdimm/region_devs.c |
1260 |
++++ b/drivers/nvdimm/region_devs.c |
1261 |
+@@ -422,10 +422,12 @@ static ssize_t available_size_show(struct device *dev, |
1262 |
+ * memory nvdimm_bus_lock() is dropped, but that's userspace's |
1263 |
+ * problem to not race itself. |
1264 |
+ */ |
1265 |
++ device_lock(dev); |
1266 |
+ nvdimm_bus_lock(dev); |
1267 |
+ wait_nvdimm_bus_probe_idle(dev); |
1268 |
+ available = nd_region_available_dpa(nd_region); |
1269 |
+ nvdimm_bus_unlock(dev); |
1270 |
++ device_unlock(dev); |
1271 |
+ |
1272 |
+ return sprintf(buf, "%llu\n", available); |
1273 |
+ } |
1274 |
+@@ -437,10 +439,12 @@ static ssize_t max_available_extent_show(struct device *dev, |
1275 |
+ struct nd_region *nd_region = to_nd_region(dev); |
1276 |
+ unsigned long long available = 0; |
1277 |
+ |
1278 |
++ device_lock(dev); |
1279 |
+ nvdimm_bus_lock(dev); |
1280 |
+ wait_nvdimm_bus_probe_idle(dev); |
1281 |
+ available = nd_region_allocatable_dpa(nd_region); |
1282 |
+ nvdimm_bus_unlock(dev); |
1283 |
++ device_unlock(dev); |
1284 |
+ |
1285 |
+ return sprintf(buf, "%llu\n", available); |
1286 |
+ } |
1287 |
+diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c |
1288 |
+index 590ec8009f52..9e444b1846ce 100644 |
1289 |
+--- a/drivers/scsi/fcoe/fcoe_ctlr.c |
1290 |
++++ b/drivers/scsi/fcoe/fcoe_ctlr.c |
1291 |
+@@ -2005,7 +2005,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); |
1292 |
+ */ |
1293 |
+ static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) |
1294 |
+ { |
1295 |
+- return (struct fcoe_rport *)(rdata + 1); |
1296 |
++ return container_of(rdata, struct fcoe_rport, rdata); |
1297 |
+ } |
1298 |
+ |
1299 |
+ /** |
1300 |
+@@ -2269,7 +2269,7 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip) |
1301 |
+ */ |
1302 |
+ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, |
1303 |
+ struct sk_buff *skb, |
1304 |
+- struct fc_rport_priv *rdata) |
1305 |
++ struct fcoe_rport *frport) |
1306 |
+ { |
1307 |
+ struct fip_header *fiph; |
1308 |
+ struct fip_desc *desc = NULL; |
1309 |
+@@ -2277,16 +2277,12 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, |
1310 |
+ struct fip_wwn_desc *wwn = NULL; |
1311 |
+ struct fip_vn_desc *vn = NULL; |
1312 |
+ struct fip_size_desc *size = NULL; |
1313 |
+- struct fcoe_rport *frport; |
1314 |
+ size_t rlen; |
1315 |
+ size_t dlen; |
1316 |
+ u32 desc_mask = 0; |
1317 |
+ u32 dtype; |
1318 |
+ u8 sub; |
1319 |
+ |
1320 |
+- memset(rdata, 0, sizeof(*rdata) + sizeof(*frport)); |
1321 |
+- frport = fcoe_ctlr_rport(rdata); |
1322 |
+- |
1323 |
+ fiph = (struct fip_header *)skb->data; |
1324 |
+ frport->flags = ntohs(fiph->fip_flags); |
1325 |
+ |
1326 |
+@@ -2349,15 +2345,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, |
1327 |
+ if (dlen != sizeof(struct fip_wwn_desc)) |
1328 |
+ goto len_err; |
1329 |
+ wwn = (struct fip_wwn_desc *)desc; |
1330 |
+- rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn); |
1331 |
++ frport->rdata.ids.node_name = |
1332 |
++ get_unaligned_be64(&wwn->fd_wwn); |
1333 |
+ break; |
1334 |
+ case FIP_DT_VN_ID: |
1335 |
+ if (dlen != sizeof(struct fip_vn_desc)) |
1336 |
+ goto len_err; |
1337 |
+ vn = (struct fip_vn_desc *)desc; |
1338 |
+ memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN); |
1339 |
+- rdata->ids.port_id = ntoh24(vn->fd_fc_id); |
1340 |
+- rdata->ids.port_name = get_unaligned_be64(&vn->fd_wwpn); |
1341 |
++ frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id); |
1342 |
++ frport->rdata.ids.port_name = |
1343 |
++ get_unaligned_be64(&vn->fd_wwpn); |
1344 |
+ break; |
1345 |
+ case FIP_DT_FC4F: |
1346 |
+ if (dlen != sizeof(struct fip_fc4_feat)) |
1347 |
+@@ -2738,10 +2736,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) |
1348 |
+ { |
1349 |
+ struct fip_header *fiph; |
1350 |
+ enum fip_vn2vn_subcode sub; |
1351 |
+- struct { |
1352 |
+- struct fc_rport_priv rdata; |
1353 |
+- struct fcoe_rport frport; |
1354 |
+- } buf; |
1355 |
++ struct fcoe_rport frport = { }; |
1356 |
+ int rc, vlan_id = 0; |
1357 |
+ |
1358 |
+ fiph = (struct fip_header *)skb->data; |
1359 |
+@@ -2757,7 +2752,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) |
1360 |
+ goto drop; |
1361 |
+ } |
1362 |
+ |
1363 |
+- rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata); |
1364 |
++ rc = fcoe_ctlr_vn_parse(fip, skb, &frport); |
1365 |
+ if (rc) { |
1366 |
+ LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc); |
1367 |
+ goto drop; |
1368 |
+@@ -2766,19 +2761,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) |
1369 |
+ mutex_lock(&fip->ctlr_mutex); |
1370 |
+ switch (sub) { |
1371 |
+ case FIP_SC_VN_PROBE_REQ: |
1372 |
+- fcoe_ctlr_vn_probe_req(fip, &buf.rdata); |
1373 |
++ fcoe_ctlr_vn_probe_req(fip, &frport.rdata); |
1374 |
+ break; |
1375 |
+ case FIP_SC_VN_PROBE_REP: |
1376 |
+- fcoe_ctlr_vn_probe_reply(fip, &buf.rdata); |
1377 |
++ fcoe_ctlr_vn_probe_reply(fip, &frport.rdata); |
1378 |
+ break; |
1379 |
+ case FIP_SC_VN_CLAIM_NOTIFY: |
1380 |
+- fcoe_ctlr_vn_claim_notify(fip, &buf.rdata); |
1381 |
++ fcoe_ctlr_vn_claim_notify(fip, &frport.rdata); |
1382 |
+ break; |
1383 |
+ case FIP_SC_VN_CLAIM_REP: |
1384 |
+- fcoe_ctlr_vn_claim_resp(fip, &buf.rdata); |
1385 |
++ fcoe_ctlr_vn_claim_resp(fip, &frport.rdata); |
1386 |
+ break; |
1387 |
+ case FIP_SC_VN_BEACON: |
1388 |
+- fcoe_ctlr_vn_beacon(fip, &buf.rdata); |
1389 |
++ fcoe_ctlr_vn_beacon(fip, &frport.rdata); |
1390 |
+ break; |
1391 |
+ default: |
1392 |
+ LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub); |
1393 |
+@@ -2802,22 +2797,18 @@ drop: |
1394 |
+ */ |
1395 |
+ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, |
1396 |
+ struct sk_buff *skb, |
1397 |
+- struct fc_rport_priv *rdata) |
1398 |
++ struct fcoe_rport *frport) |
1399 |
+ { |
1400 |
+ struct fip_header *fiph; |
1401 |
+ struct fip_desc *desc = NULL; |
1402 |
+ struct fip_mac_desc *macd = NULL; |
1403 |
+ struct fip_wwn_desc *wwn = NULL; |
1404 |
+- struct fcoe_rport *frport; |
1405 |
+ size_t rlen; |
1406 |
+ size_t dlen; |
1407 |
+ u32 desc_mask = 0; |
1408 |
+ u32 dtype; |
1409 |
+ u8 sub; |
1410 |
+ |
1411 |
+- memset(rdata, 0, sizeof(*rdata) + sizeof(*frport)); |
1412 |
+- frport = fcoe_ctlr_rport(rdata); |
1413 |
+- |
1414 |
+ fiph = (struct fip_header *)skb->data; |
1415 |
+ frport->flags = ntohs(fiph->fip_flags); |
1416 |
+ |
1417 |
+@@ -2871,7 +2862,8 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, |
1418 |
+ if (dlen != sizeof(struct fip_wwn_desc)) |
1419 |
+ goto len_err; |
1420 |
+ wwn = (struct fip_wwn_desc *)desc; |
1421 |
+- rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn); |
1422 |
++ frport->rdata.ids.node_name = |
1423 |
++ get_unaligned_be64(&wwn->fd_wwn); |
1424 |
+ break; |
1425 |
+ default: |
1426 |
+ LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x " |
1427 |
+@@ -2982,22 +2974,19 @@ static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) |
1428 |
+ { |
1429 |
+ struct fip_header *fiph; |
1430 |
+ enum fip_vlan_subcode sub; |
1431 |
+- struct { |
1432 |
+- struct fc_rport_priv rdata; |
1433 |
+- struct fcoe_rport frport; |
1434 |
+- } buf; |
1435 |
++ struct fcoe_rport frport = { }; |
1436 |
+ int rc; |
1437 |
+ |
1438 |
+ fiph = (struct fip_header *)skb->data; |
1439 |
+ sub = fiph->fip_subcode; |
1440 |
+- rc = fcoe_ctlr_vlan_parse(fip, skb, &buf.rdata); |
1441 |
++ rc = fcoe_ctlr_vlan_parse(fip, skb, &frport); |
1442 |
+ if (rc) { |
1443 |
+ LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc); |
1444 |
+ goto drop; |
1445 |
+ } |
1446 |
+ mutex_lock(&fip->ctlr_mutex); |
1447 |
+ if (sub == FIP_SC_VL_REQ) |
1448 |
+- fcoe_ctlr_vlan_disc_reply(fip, &buf.rdata); |
1449 |
++ fcoe_ctlr_vlan_disc_reply(fip, &frport.rdata); |
1450 |
+ mutex_unlock(&fip->ctlr_mutex); |
1451 |
+ |
1452 |
+ drop: |
1453 |
+diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c |
1454 |
+index e0f3852fdad1..da6e97d8dc3b 100644 |
1455 |
+--- a/drivers/scsi/libfc/fc_rport.c |
1456 |
++++ b/drivers/scsi/libfc/fc_rport.c |
1457 |
+@@ -128,6 +128,7 @@ EXPORT_SYMBOL(fc_rport_lookup); |
1458 |
+ struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) |
1459 |
+ { |
1460 |
+ struct fc_rport_priv *rdata; |
1461 |
++ size_t rport_priv_size = sizeof(*rdata); |
1462 |
+ |
1463 |
+ lockdep_assert_held(&lport->disc.disc_mutex); |
1464 |
+ |
1465 |
+@@ -135,7 +136,9 @@ struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) |
1466 |
+ if (rdata) |
1467 |
+ return rdata; |
1468 |
+ |
1469 |
+- rdata = kzalloc(sizeof(*rdata) + lport->rport_priv_size, GFP_KERNEL); |
1470 |
++ if (lport->rport_priv_size > 0) |
1471 |
++ rport_priv_size = lport->rport_priv_size; |
1472 |
++ rdata = kzalloc(rport_priv_size, GFP_KERNEL); |
1473 |
+ if (!rdata) |
1474 |
+ return NULL; |
1475 |
+ |
1476 |
+diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c |
1477 |
+index 402c1efcd762..6435b8652159 100644 |
1478 |
+--- a/drivers/spi/spi-bcm2835.c |
1479 |
++++ b/drivers/spi/spi-bcm2835.c |
1480 |
+@@ -764,7 +764,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, |
1481 |
+ bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); |
1482 |
+ |
1483 |
+ /* handle all the 3-wire mode */ |
1484 |
+- if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) |
1485 |
++ if (spi->mode & SPI_3WIRE && tfr->rx_buf && |
1486 |
++ tfr->rx_buf != master->dummy_rx) |
1487 |
+ cs |= BCM2835_SPI_CS_REN; |
1488 |
+ else |
1489 |
+ cs &= ~BCM2835_SPI_CS_REN; |
1490 |
+diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c |
1491 |
+index 6e30949d9f77..a7ec2d3dff92 100644 |
1492 |
+--- a/fs/compat_ioctl.c |
1493 |
++++ b/fs/compat_ioctl.c |
1494 |
+@@ -638,9 +638,6 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN) |
1495 |
+ COMPATIBLE_IOCTL(PPPIOCATTCHAN) |
1496 |
+ COMPATIBLE_IOCTL(PPPIOCGCHAN) |
1497 |
+ COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS) |
1498 |
+-/* PPPOX */ |
1499 |
+-COMPATIBLE_IOCTL(PPPOEIOCSFWD) |
1500 |
+-COMPATIBLE_IOCTL(PPPOEIOCDFWD) |
1501 |
+ /* Big A */ |
1502 |
+ /* sparc only */ |
1503 |
+ /* Big Q for sound/OSS */ |
1504 |
+diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h |
1505 |
+index 8b728750a625..69e813bcb947 100644 |
1506 |
+--- a/include/linux/if_pppox.h |
1507 |
++++ b/include/linux/if_pppox.h |
1508 |
+@@ -80,6 +80,9 @@ extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp); |
1509 |
+ extern void unregister_pppox_proto(int proto_num); |
1510 |
+ extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ |
1511 |
+ extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); |
1512 |
++extern int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); |
1513 |
++ |
1514 |
++#define PPPOEIOCSFWD32 _IOW(0xB1 ,0, compat_size_t) |
1515 |
+ |
1516 |
+ /* PPPoX socket states */ |
1517 |
+ enum { |
1518 |
+diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h |
1519 |
+index e690ba0f965c..70185079f83e 100644 |
1520 |
+--- a/include/linux/mlx5/fs.h |
1521 |
++++ b/include/linux/mlx5/fs.h |
1522 |
+@@ -211,6 +211,7 @@ int mlx5_modify_rule_destination(struct mlx5_flow_handle *handler, |
1523 |
+ |
1524 |
+ struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging); |
1525 |
+ void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter); |
1526 |
++u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter); |
1527 |
+ void mlx5_fc_query_cached(struct mlx5_fc *counter, |
1528 |
+ u64 *bytes, u64 *packets, u64 *lastuse); |
1529 |
+ int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter, |
1530 |
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h |
1531 |
+index 7e42efa143a0..29b55f8cd7b3 100644 |
1532 |
+--- a/include/linux/mlx5/mlx5_ifc.h |
1533 |
++++ b/include/linux/mlx5/mlx5_ifc.h |
1534 |
+@@ -5865,10 +5865,12 @@ struct mlx5_ifc_modify_cq_in_bits { |
1535 |
+ |
1536 |
+ struct mlx5_ifc_cqc_bits cq_context; |
1537 |
+ |
1538 |
+- u8 reserved_at_280[0x40]; |
1539 |
++ u8 reserved_at_280[0x60]; |
1540 |
+ |
1541 |
+ u8 cq_umem_valid[0x1]; |
1542 |
+- u8 reserved_at_2c1[0x5bf]; |
1543 |
++ u8 reserved_at_2e1[0x1f]; |
1544 |
++ |
1545 |
++ u8 reserved_at_300[0x580]; |
1546 |
+ |
1547 |
+ u8 pas[0][0x40]; |
1548 |
+ }; |
1549 |
+diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h |
1550 |
+index c50fb297e265..e89a922ee849 100644 |
1551 |
+--- a/include/scsi/libfcoe.h |
1552 |
++++ b/include/scsi/libfcoe.h |
1553 |
+@@ -229,6 +229,7 @@ struct fcoe_fcf { |
1554 |
+ * @vn_mac: VN_Node assigned MAC address for data |
1555 |
+ */ |
1556 |
+ struct fcoe_rport { |
1557 |
++ struct fc_rport_priv rdata; |
1558 |
+ unsigned long time; |
1559 |
+ u16 fcoe_len; |
1560 |
+ u16 flags; |
1561 |
+diff --git a/net/bridge/br.c b/net/bridge/br.c |
1562 |
+index d164f63a4345..8a8f9e5f264f 100644 |
1563 |
+--- a/net/bridge/br.c |
1564 |
++++ b/net/bridge/br.c |
1565 |
+@@ -37,12 +37,15 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v |
1566 |
+ int err; |
1567 |
+ |
1568 |
+ if (dev->priv_flags & IFF_EBRIDGE) { |
1569 |
++ err = br_vlan_bridge_event(dev, event, ptr); |
1570 |
++ if (err) |
1571 |
++ return notifier_from_errno(err); |
1572 |
++ |
1573 |
+ if (event == NETDEV_REGISTER) { |
1574 |
+ /* register of bridge completed, add sysfs entries */ |
1575 |
+ br_sysfs_addbr(dev); |
1576 |
+ return NOTIFY_DONE; |
1577 |
+ } |
1578 |
+- br_vlan_bridge_event(dev, event, ptr); |
1579 |
+ } |
1580 |
+ |
1581 |
+ /* not a port of a bridge */ |
1582 |
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c |
1583 |
+index 3d8deac2353d..f8cac3702712 100644 |
1584 |
+--- a/net/bridge/br_multicast.c |
1585 |
++++ b/net/bridge/br_multicast.c |
1586 |
+@@ -1388,6 +1388,9 @@ br_multicast_leave_group(struct net_bridge *br, |
1587 |
+ if (!br_port_group_equal(p, port, src)) |
1588 |
+ continue; |
1589 |
+ |
1590 |
++ if (p->flags & MDB_PG_FLAGS_PERMANENT) |
1591 |
++ break; |
1592 |
++ |
1593 |
+ rcu_assign_pointer(*pp, p->next); |
1594 |
+ hlist_del_init(&p->mglist); |
1595 |
+ del_timer(&p->timer); |
1596 |
+diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h |
1597 |
+index 159a0e2cb0f6..9564a953bdf9 100644 |
1598 |
+--- a/net/bridge/br_private.h |
1599 |
++++ b/net/bridge/br_private.h |
1600 |
+@@ -893,8 +893,8 @@ int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask); |
1601 |
+ void br_vlan_get_stats(const struct net_bridge_vlan *v, |
1602 |
+ struct br_vlan_stats *stats); |
1603 |
+ void br_vlan_port_event(struct net_bridge_port *p, unsigned long event); |
1604 |
+-void br_vlan_bridge_event(struct net_device *dev, unsigned long event, |
1605 |
+- void *ptr); |
1606 |
++int br_vlan_bridge_event(struct net_device *dev, unsigned long event, |
1607 |
++ void *ptr); |
1608 |
+ |
1609 |
+ static inline struct net_bridge_vlan_group *br_vlan_group( |
1610 |
+ const struct net_bridge *br) |
1611 |
+@@ -1084,9 +1084,10 @@ static inline void br_vlan_port_event(struct net_bridge_port *p, |
1612 |
+ { |
1613 |
+ } |
1614 |
+ |
1615 |
+-static inline void br_vlan_bridge_event(struct net_device *dev, |
1616 |
+- unsigned long event, void *ptr) |
1617 |
++static inline int br_vlan_bridge_event(struct net_device *dev, |
1618 |
++ unsigned long event, void *ptr) |
1619 |
+ { |
1620 |
++ return 0; |
1621 |
+ } |
1622 |
+ #endif |
1623 |
+ |
1624 |
+diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c |
1625 |
+index f47f526b4f19..6b2c48b07e04 100644 |
1626 |
+--- a/net/bridge/br_vlan.c |
1627 |
++++ b/net/bridge/br_vlan.c |
1628 |
+@@ -1043,7 +1043,6 @@ int br_vlan_init(struct net_bridge *br) |
1629 |
+ { |
1630 |
+ struct net_bridge_vlan_group *vg; |
1631 |
+ int ret = -ENOMEM; |
1632 |
+- bool changed; |
1633 |
+ |
1634 |
+ vg = kzalloc(sizeof(*vg), GFP_KERNEL); |
1635 |
+ if (!vg) |
1636 |
+@@ -1058,17 +1057,10 @@ int br_vlan_init(struct net_bridge *br) |
1637 |
+ br->vlan_proto = htons(ETH_P_8021Q); |
1638 |
+ br->default_pvid = 1; |
1639 |
+ rcu_assign_pointer(br->vlgrp, vg); |
1640 |
+- ret = br_vlan_add(br, 1, |
1641 |
+- BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED | |
1642 |
+- BRIDGE_VLAN_INFO_BRENTRY, &changed, NULL); |
1643 |
+- if (ret) |
1644 |
+- goto err_vlan_add; |
1645 |
+ |
1646 |
+ out: |
1647 |
+ return ret; |
1648 |
+ |
1649 |
+-err_vlan_add: |
1650 |
+- vlan_tunnel_deinit(vg); |
1651 |
+ err_tunnel_init: |
1652 |
+ rhashtable_destroy(&vg->vlan_hash); |
1653 |
+ err_rhtbl: |
1654 |
+@@ -1443,13 +1435,23 @@ static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid) |
1655 |
+ } |
1656 |
+ |
1657 |
+ /* Must be protected by RTNL. */ |
1658 |
+-void br_vlan_bridge_event(struct net_device *dev, unsigned long event, |
1659 |
+- void *ptr) |
1660 |
++int br_vlan_bridge_event(struct net_device *dev, unsigned long event, void *ptr) |
1661 |
+ { |
1662 |
+ struct netdev_notifier_changeupper_info *info; |
1663 |
+- struct net_bridge *br; |
1664 |
++ struct net_bridge *br = netdev_priv(dev); |
1665 |
++ bool changed; |
1666 |
++ int ret = 0; |
1667 |
+ |
1668 |
+ switch (event) { |
1669 |
++ case NETDEV_REGISTER: |
1670 |
++ ret = br_vlan_add(br, br->default_pvid, |
1671 |
++ BRIDGE_VLAN_INFO_PVID | |
1672 |
++ BRIDGE_VLAN_INFO_UNTAGGED | |
1673 |
++ BRIDGE_VLAN_INFO_BRENTRY, &changed, NULL); |
1674 |
++ break; |
1675 |
++ case NETDEV_UNREGISTER: |
1676 |
++ br_vlan_delete(br, br->default_pvid); |
1677 |
++ break; |
1678 |
+ case NETDEV_CHANGEUPPER: |
1679 |
+ info = ptr; |
1680 |
+ br_vlan_upper_change(dev, info->upper_dev, info->linking); |
1681 |
+@@ -1457,12 +1459,13 @@ void br_vlan_bridge_event(struct net_device *dev, unsigned long event, |
1682 |
+ |
1683 |
+ case NETDEV_CHANGE: |
1684 |
+ case NETDEV_UP: |
1685 |
+- br = netdev_priv(dev); |
1686 |
+ if (!br_opt_get(br, BROPT_VLAN_BRIDGE_BINDING)) |
1687 |
+- return; |
1688 |
++ break; |
1689 |
+ br_vlan_link_state_change(dev, br); |
1690 |
+ break; |
1691 |
+ } |
1692 |
++ |
1693 |
++ return ret; |
1694 |
+ } |
1695 |
+ |
1696 |
+ /* Must be protected by RTNL. */ |
1697 |
+diff --git a/net/core/dev.c b/net/core/dev.c |
1698 |
+index d6edd218babd..29fcff2c3d51 100644 |
1699 |
+--- a/net/core/dev.c |
1700 |
++++ b/net/core/dev.c |
1701 |
+@@ -4382,12 +4382,17 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, |
1702 |
+ |
1703 |
+ act = bpf_prog_run_xdp(xdp_prog, xdp); |
1704 |
+ |
1705 |
++ /* check if bpf_xdp_adjust_head was used */ |
1706 |
+ off = xdp->data - orig_data; |
1707 |
+- if (off > 0) |
1708 |
+- __skb_pull(skb, off); |
1709 |
+- else if (off < 0) |
1710 |
+- __skb_push(skb, -off); |
1711 |
+- skb->mac_header += off; |
1712 |
++ if (off) { |
1713 |
++ if (off > 0) |
1714 |
++ __skb_pull(skb, off); |
1715 |
++ else if (off < 0) |
1716 |
++ __skb_push(skb, -off); |
1717 |
++ |
1718 |
++ skb->mac_header += off; |
1719 |
++ skb_reset_network_header(skb); |
1720 |
++ } |
1721 |
+ |
1722 |
+ /* check if bpf_xdp_adjust_tail was used. it can only "shrink" |
1723 |
+ * pckt. |
1724 |
+@@ -9711,6 +9716,8 @@ static void __net_exit default_device_exit(struct net *net) |
1725 |
+ |
1726 |
+ /* Push remaining network devices to init_net */ |
1727 |
+ snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex); |
1728 |
++ if (__dev_get_by_name(&init_net, fb_name)) |
1729 |
++ snprintf(fb_name, IFNAMSIZ, "dev%%d"); |
1730 |
+ err = dev_change_net_namespace(dev, &init_net, fb_name); |
1731 |
+ if (err) { |
1732 |
+ pr_emerg("%s: failed to move %s to init_net: %d\n", |
1733 |
+diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c |
1734 |
+index 43adfc1641ba..2f01cf6fa0de 100644 |
1735 |
+--- a/net/ipv4/ipip.c |
1736 |
++++ b/net/ipv4/ipip.c |
1737 |
+@@ -275,6 +275,9 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, |
1738 |
+ const struct iphdr *tiph = &tunnel->parms.iph; |
1739 |
+ u8 ipproto; |
1740 |
+ |
1741 |
++ if (!pskb_inet_may_pull(skb)) |
1742 |
++ goto tx_error; |
1743 |
++ |
1744 |
+ switch (skb->protocol) { |
1745 |
+ case htons(ETH_P_IP): |
1746 |
+ ipproto = IPPROTO_IPIP; |
1747 |
+diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c |
1748 |
+index c2049c72f3e5..dd2d0b963260 100644 |
1749 |
+--- a/net/ipv6/ip6_gre.c |
1750 |
++++ b/net/ipv6/ip6_gre.c |
1751 |
+@@ -660,12 +660,13 @@ static int prepare_ip6gre_xmit_ipv6(struct sk_buff *skb, |
1752 |
+ struct flowi6 *fl6, __u8 *dsfield, |
1753 |
+ int *encap_limit) |
1754 |
+ { |
1755 |
+- struct ipv6hdr *ipv6h = ipv6_hdr(skb); |
1756 |
++ struct ipv6hdr *ipv6h; |
1757 |
+ struct ip6_tnl *t = netdev_priv(dev); |
1758 |
+ __u16 offset; |
1759 |
+ |
1760 |
+ offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); |
1761 |
+ /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ |
1762 |
++ ipv6h = ipv6_hdr(skb); |
1763 |
+ |
1764 |
+ if (offset > 0) { |
1765 |
+ struct ipv6_tlv_tnl_enc_lim *tel; |
1766 |
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c |
1767 |
+index b80fde1bc005..d10a9e40729f 100644 |
1768 |
+--- a/net/ipv6/ip6_tunnel.c |
1769 |
++++ b/net/ipv6/ip6_tunnel.c |
1770 |
+@@ -1278,12 +1278,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
1771 |
+ } |
1772 |
+ |
1773 |
+ fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); |
1774 |
++ dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); |
1775 |
+ |
1776 |
+ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) |
1777 |
+ return -1; |
1778 |
+ |
1779 |
+- dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); |
1780 |
+- |
1781 |
+ skb_set_inner_ipproto(skb, IPPROTO_IPIP); |
1782 |
+ |
1783 |
+ err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, |
1784 |
+@@ -1367,12 +1366,11 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
1785 |
+ } |
1786 |
+ |
1787 |
+ fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); |
1788 |
++ dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h)); |
1789 |
+ |
1790 |
+ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) |
1791 |
+ return -1; |
1792 |
+ |
1793 |
+- dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h)); |
1794 |
+- |
1795 |
+ skb_set_inner_ipproto(skb, IPPROTO_IPV6); |
1796 |
+ |
1797 |
+ err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, |
1798 |
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c |
1799 |
+index 1d0e5904dedf..c54cb59593ef 100644 |
1800 |
+--- a/net/l2tp/l2tp_ppp.c |
1801 |
++++ b/net/l2tp/l2tp_ppp.c |
1802 |
+@@ -1681,6 +1681,9 @@ static const struct proto_ops pppol2tp_ops = { |
1803 |
+ .recvmsg = pppol2tp_recvmsg, |
1804 |
+ .mmap = sock_no_mmap, |
1805 |
+ .ioctl = pppox_ioctl, |
1806 |
++#ifdef CONFIG_COMPAT |
1807 |
++ .compat_ioctl = pppox_compat_ioctl, |
1808 |
++#endif |
1809 |
+ }; |
1810 |
+ |
1811 |
+ static const struct pppox_proto pppol2tp_proto = { |
1812 |
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c |
1813 |
+index 06aac0aaae64..8dc6580e1787 100644 |
1814 |
+--- a/net/mac80211/iface.c |
1815 |
++++ b/net/mac80211/iface.c |
1816 |
+@@ -1222,7 +1222,6 @@ static void ieee80211_if_setup(struct net_device *dev) |
1817 |
+ static void ieee80211_if_setup_no_queue(struct net_device *dev) |
1818 |
+ { |
1819 |
+ ieee80211_if_setup(dev); |
1820 |
+- dev->features |= NETIF_F_LLTX; |
1821 |
+ dev->priv_flags |= IFF_NO_QUEUE; |
1822 |
+ } |
1823 |
+ |
1824 |
+diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c |
1825 |
+index 8126b26f125e..fd1f7e799e23 100644 |
1826 |
+--- a/net/sched/act_bpf.c |
1827 |
++++ b/net/sched/act_bpf.c |
1828 |
+@@ -285,6 +285,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, |
1829 |
+ struct tcf_bpf *prog; |
1830 |
+ bool is_bpf, is_ebpf; |
1831 |
+ int ret, res = 0; |
1832 |
++ u32 index; |
1833 |
+ |
1834 |
+ if (!nla) |
1835 |
+ return -EINVAL; |
1836 |
+@@ -298,13 +299,13 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, |
1837 |
+ return -EINVAL; |
1838 |
+ |
1839 |
+ parm = nla_data(tb[TCA_ACT_BPF_PARMS]); |
1840 |
+- |
1841 |
+- ret = tcf_idr_check_alloc(tn, &parm->index, act, bind); |
1842 |
++ index = parm->index; |
1843 |
++ ret = tcf_idr_check_alloc(tn, &index, act, bind); |
1844 |
+ if (!ret) { |
1845 |
+- ret = tcf_idr_create(tn, parm->index, est, act, |
1846 |
++ ret = tcf_idr_create(tn, index, est, act, |
1847 |
+ &act_bpf_ops, bind, true); |
1848 |
+ if (ret < 0) { |
1849 |
+- tcf_idr_cleanup(tn, parm->index); |
1850 |
++ tcf_idr_cleanup(tn, index); |
1851 |
+ return ret; |
1852 |
+ } |
1853 |
+ |
1854 |
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c |
1855 |
+index ce36b0f7e1dc..32ac04d77a45 100644 |
1856 |
+--- a/net/sched/act_connmark.c |
1857 |
++++ b/net/sched/act_connmark.c |
1858 |
+@@ -103,6 +103,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, |
1859 |
+ struct tcf_connmark_info *ci; |
1860 |
+ struct tc_connmark *parm; |
1861 |
+ int ret = 0, err; |
1862 |
++ u32 index; |
1863 |
+ |
1864 |
+ if (!nla) |
1865 |
+ return -EINVAL; |
1866 |
+@@ -116,13 +117,13 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, |
1867 |
+ return -EINVAL; |
1868 |
+ |
1869 |
+ parm = nla_data(tb[TCA_CONNMARK_PARMS]); |
1870 |
+- |
1871 |
+- ret = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
1872 |
++ index = parm->index; |
1873 |
++ ret = tcf_idr_check_alloc(tn, &index, a, bind); |
1874 |
+ if (!ret) { |
1875 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
1876 |
++ ret = tcf_idr_create(tn, index, est, a, |
1877 |
+ &act_connmark_ops, bind, false); |
1878 |
+ if (ret) { |
1879 |
+- tcf_idr_cleanup(tn, parm->index); |
1880 |
++ tcf_idr_cleanup(tn, index); |
1881 |
+ return ret; |
1882 |
+ } |
1883 |
+ |
1884 |
+diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c |
1885 |
+index 621fb22ce2a9..9b9288267a54 100644 |
1886 |
+--- a/net/sched/act_csum.c |
1887 |
++++ b/net/sched/act_csum.c |
1888 |
+@@ -52,6 +52,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla, |
1889 |
+ struct tc_csum *parm; |
1890 |
+ struct tcf_csum *p; |
1891 |
+ int ret = 0, err; |
1892 |
++ u32 index; |
1893 |
+ |
1894 |
+ if (nla == NULL) |
1895 |
+ return -EINVAL; |
1896 |
+@@ -64,13 +65,13 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla, |
1897 |
+ if (tb[TCA_CSUM_PARMS] == NULL) |
1898 |
+ return -EINVAL; |
1899 |
+ parm = nla_data(tb[TCA_CSUM_PARMS]); |
1900 |
+- |
1901 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
1902 |
++ index = parm->index; |
1903 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
1904 |
+ if (!err) { |
1905 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
1906 |
++ ret = tcf_idr_create(tn, index, est, a, |
1907 |
+ &act_csum_ops, bind, true); |
1908 |
+ if (ret) { |
1909 |
+- tcf_idr_cleanup(tn, parm->index); |
1910 |
++ tcf_idr_cleanup(tn, index); |
1911 |
+ return ret; |
1912 |
+ } |
1913 |
+ ret = ACT_P_CREATED; |
1914 |
+diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c |
1915 |
+index b2380c5284e6..8f0140c6ca58 100644 |
1916 |
+--- a/net/sched/act_gact.c |
1917 |
++++ b/net/sched/act_gact.c |
1918 |
+@@ -61,6 +61,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, |
1919 |
+ struct tc_gact *parm; |
1920 |
+ struct tcf_gact *gact; |
1921 |
+ int ret = 0; |
1922 |
++ u32 index; |
1923 |
+ int err; |
1924 |
+ #ifdef CONFIG_GACT_PROB |
1925 |
+ struct tc_gact_p *p_parm = NULL; |
1926 |
+@@ -77,6 +78,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, |
1927 |
+ if (tb[TCA_GACT_PARMS] == NULL) |
1928 |
+ return -EINVAL; |
1929 |
+ parm = nla_data(tb[TCA_GACT_PARMS]); |
1930 |
++ index = parm->index; |
1931 |
+ |
1932 |
+ #ifndef CONFIG_GACT_PROB |
1933 |
+ if (tb[TCA_GACT_PROB] != NULL) |
1934 |
+@@ -94,12 +96,12 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, |
1935 |
+ } |
1936 |
+ #endif |
1937 |
+ |
1938 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
1939 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
1940 |
+ if (!err) { |
1941 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
1942 |
++ ret = tcf_idr_create(tn, index, est, a, |
1943 |
+ &act_gact_ops, bind, true); |
1944 |
+ if (ret) { |
1945 |
+- tcf_idr_cleanup(tn, parm->index); |
1946 |
++ tcf_idr_cleanup(tn, index); |
1947 |
+ return ret; |
1948 |
+ } |
1949 |
+ ret = ACT_P_CREATED; |
1950 |
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c |
1951 |
+index 41d5398dd2f2..92ee853d43e6 100644 |
1952 |
+--- a/net/sched/act_ife.c |
1953 |
++++ b/net/sched/act_ife.c |
1954 |
+@@ -479,8 +479,14 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, |
1955 |
+ u8 *saddr = NULL; |
1956 |
+ bool exists = false; |
1957 |
+ int ret = 0; |
1958 |
++ u32 index; |
1959 |
+ int err; |
1960 |
+ |
1961 |
++ if (!nla) { |
1962 |
++ NL_SET_ERR_MSG_MOD(extack, "IFE requires attributes to be passed"); |
1963 |
++ return -EINVAL; |
1964 |
++ } |
1965 |
++ |
1966 |
+ err = nla_parse_nested_deprecated(tb, TCA_IFE_MAX, nla, ife_policy, |
1967 |
+ NULL); |
1968 |
+ if (err < 0) |
1969 |
+@@ -502,7 +508,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, |
1970 |
+ if (!p) |
1971 |
+ return -ENOMEM; |
1972 |
+ |
1973 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
1974 |
++ index = parm->index; |
1975 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
1976 |
+ if (err < 0) { |
1977 |
+ kfree(p); |
1978 |
+ return err; |
1979 |
+@@ -514,10 +521,10 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, |
1980 |
+ } |
1981 |
+ |
1982 |
+ if (!exists) { |
1983 |
+- ret = tcf_idr_create(tn, parm->index, est, a, &act_ife_ops, |
1984 |
++ ret = tcf_idr_create(tn, index, est, a, &act_ife_ops, |
1985 |
+ bind, true); |
1986 |
+ if (ret) { |
1987 |
+- tcf_idr_cleanup(tn, parm->index); |
1988 |
++ tcf_idr_cleanup(tn, index); |
1989 |
+ kfree(p); |
1990 |
+ return ret; |
1991 |
+ } |
1992 |
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c |
1993 |
+index 58e7573dded4..d10dca7a13e1 100644 |
1994 |
+--- a/net/sched/act_mirred.c |
1995 |
++++ b/net/sched/act_mirred.c |
1996 |
+@@ -101,6 +101,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, |
1997 |
+ struct net_device *dev; |
1998 |
+ bool exists = false; |
1999 |
+ int ret, err; |
2000 |
++ u32 index; |
2001 |
+ |
2002 |
+ if (!nla) { |
2003 |
+ NL_SET_ERR_MSG_MOD(extack, "Mirred requires attributes to be passed"); |
2004 |
+@@ -115,8 +116,8 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, |
2005 |
+ return -EINVAL; |
2006 |
+ } |
2007 |
+ parm = nla_data(tb[TCA_MIRRED_PARMS]); |
2008 |
+- |
2009 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2010 |
++ index = parm->index; |
2011 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2012 |
+ if (err < 0) |
2013 |
+ return err; |
2014 |
+ exists = err; |
2015 |
+@@ -133,21 +134,21 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, |
2016 |
+ if (exists) |
2017 |
+ tcf_idr_release(*a, bind); |
2018 |
+ else |
2019 |
+- tcf_idr_cleanup(tn, parm->index); |
2020 |
++ tcf_idr_cleanup(tn, index); |
2021 |
+ NL_SET_ERR_MSG_MOD(extack, "Unknown mirred option"); |
2022 |
+ return -EINVAL; |
2023 |
+ } |
2024 |
+ |
2025 |
+ if (!exists) { |
2026 |
+ if (!parm->ifindex) { |
2027 |
+- tcf_idr_cleanup(tn, parm->index); |
2028 |
++ tcf_idr_cleanup(tn, index); |
2029 |
+ NL_SET_ERR_MSG_MOD(extack, "Specified device does not exist"); |
2030 |
+ return -EINVAL; |
2031 |
+ } |
2032 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2033 |
++ ret = tcf_idr_create(tn, index, est, a, |
2034 |
+ &act_mirred_ops, bind, true); |
2035 |
+ if (ret) { |
2036 |
+- tcf_idr_cleanup(tn, parm->index); |
2037 |
++ tcf_idr_cleanup(tn, index); |
2038 |
+ return ret; |
2039 |
+ } |
2040 |
+ ret = ACT_P_CREATED; |
2041 |
+diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c |
2042 |
+index 45923ebb7a4f..7b858c11b1b5 100644 |
2043 |
+--- a/net/sched/act_nat.c |
2044 |
++++ b/net/sched/act_nat.c |
2045 |
+@@ -44,6 +44,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, |
2046 |
+ struct tc_nat *parm; |
2047 |
+ int ret = 0, err; |
2048 |
+ struct tcf_nat *p; |
2049 |
++ u32 index; |
2050 |
+ |
2051 |
+ if (nla == NULL) |
2052 |
+ return -EINVAL; |
2053 |
+@@ -56,13 +57,13 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, |
2054 |
+ if (tb[TCA_NAT_PARMS] == NULL) |
2055 |
+ return -EINVAL; |
2056 |
+ parm = nla_data(tb[TCA_NAT_PARMS]); |
2057 |
+- |
2058 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2059 |
++ index = parm->index; |
2060 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2061 |
+ if (!err) { |
2062 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2063 |
++ ret = tcf_idr_create(tn, index, est, a, |
2064 |
+ &act_nat_ops, bind, false); |
2065 |
+ if (ret) { |
2066 |
+- tcf_idr_cleanup(tn, parm->index); |
2067 |
++ tcf_idr_cleanup(tn, index); |
2068 |
+ return ret; |
2069 |
+ } |
2070 |
+ ret = ACT_P_CREATED; |
2071 |
+diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c |
2072 |
+index 45e9d6bfddb3..17360c6faeaa 100644 |
2073 |
+--- a/net/sched/act_pedit.c |
2074 |
++++ b/net/sched/act_pedit.c |
2075 |
+@@ -149,6 +149,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, |
2076 |
+ struct tcf_pedit *p; |
2077 |
+ int ret = 0, err; |
2078 |
+ int ksize; |
2079 |
++ u32 index; |
2080 |
+ |
2081 |
+ if (!nla) { |
2082 |
+ NL_SET_ERR_MSG_MOD(extack, "Pedit requires attributes to be passed"); |
2083 |
+@@ -179,18 +180,19 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, |
2084 |
+ if (IS_ERR(keys_ex)) |
2085 |
+ return PTR_ERR(keys_ex); |
2086 |
+ |
2087 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2088 |
++ index = parm->index; |
2089 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2090 |
+ if (!err) { |
2091 |
+ if (!parm->nkeys) { |
2092 |
+- tcf_idr_cleanup(tn, parm->index); |
2093 |
++ tcf_idr_cleanup(tn, index); |
2094 |
+ NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed"); |
2095 |
+ ret = -EINVAL; |
2096 |
+ goto out_free; |
2097 |
+ } |
2098 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2099 |
++ ret = tcf_idr_create(tn, index, est, a, |
2100 |
+ &act_pedit_ops, bind, false); |
2101 |
+ if (ret) { |
2102 |
+- tcf_idr_cleanup(tn, parm->index); |
2103 |
++ tcf_idr_cleanup(tn, index); |
2104 |
+ goto out_free; |
2105 |
+ } |
2106 |
+ ret = ACT_P_CREATED; |
2107 |
+diff --git a/net/sched/act_police.c b/net/sched/act_police.c |
2108 |
+index a065f62fa79c..49cec3e64a4d 100644 |
2109 |
+--- a/net/sched/act_police.c |
2110 |
++++ b/net/sched/act_police.c |
2111 |
+@@ -57,6 +57,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, |
2112 |
+ struct tc_action_net *tn = net_generic(net, police_net_id); |
2113 |
+ struct tcf_police_params *new; |
2114 |
+ bool exists = false; |
2115 |
++ u32 index; |
2116 |
+ |
2117 |
+ if (nla == NULL) |
2118 |
+ return -EINVAL; |
2119 |
+@@ -73,7 +74,8 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, |
2120 |
+ return -EINVAL; |
2121 |
+ |
2122 |
+ parm = nla_data(tb[TCA_POLICE_TBF]); |
2123 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2124 |
++ index = parm->index; |
2125 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2126 |
+ if (err < 0) |
2127 |
+ return err; |
2128 |
+ exists = err; |
2129 |
+@@ -81,10 +83,10 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, |
2130 |
+ return 0; |
2131 |
+ |
2132 |
+ if (!exists) { |
2133 |
+- ret = tcf_idr_create(tn, parm->index, NULL, a, |
2134 |
++ ret = tcf_idr_create(tn, index, NULL, a, |
2135 |
+ &act_police_ops, bind, true); |
2136 |
+ if (ret) { |
2137 |
+- tcf_idr_cleanup(tn, parm->index); |
2138 |
++ tcf_idr_cleanup(tn, index); |
2139 |
+ return ret; |
2140 |
+ } |
2141 |
+ ret = ACT_P_CREATED; |
2142 |
+diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c |
2143 |
+index 274d7a0c0e25..595308d60133 100644 |
2144 |
+--- a/net/sched/act_sample.c |
2145 |
++++ b/net/sched/act_sample.c |
2146 |
+@@ -41,8 +41,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, |
2147 |
+ struct tc_action_net *tn = net_generic(net, sample_net_id); |
2148 |
+ struct nlattr *tb[TCA_SAMPLE_MAX + 1]; |
2149 |
+ struct psample_group *psample_group; |
2150 |
++ u32 psample_group_num, rate, index; |
2151 |
+ struct tcf_chain *goto_ch = NULL; |
2152 |
+- u32 psample_group_num, rate; |
2153 |
+ struct tc_sample *parm; |
2154 |
+ struct tcf_sample *s; |
2155 |
+ bool exists = false; |
2156 |
+@@ -59,8 +59,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, |
2157 |
+ return -EINVAL; |
2158 |
+ |
2159 |
+ parm = nla_data(tb[TCA_SAMPLE_PARMS]); |
2160 |
+- |
2161 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2162 |
++ index = parm->index; |
2163 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2164 |
+ if (err < 0) |
2165 |
+ return err; |
2166 |
+ exists = err; |
2167 |
+@@ -68,10 +68,10 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, |
2168 |
+ return 0; |
2169 |
+ |
2170 |
+ if (!exists) { |
2171 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2172 |
++ ret = tcf_idr_create(tn, index, est, a, |
2173 |
+ &act_sample_ops, bind, true); |
2174 |
+ if (ret) { |
2175 |
+- tcf_idr_cleanup(tn, parm->index); |
2176 |
++ tcf_idr_cleanup(tn, index); |
2177 |
+ return ret; |
2178 |
+ } |
2179 |
+ ret = ACT_P_CREATED; |
2180 |
+diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c |
2181 |
+index f28ddbabff76..33aefa25b545 100644 |
2182 |
+--- a/net/sched/act_simple.c |
2183 |
++++ b/net/sched/act_simple.c |
2184 |
+@@ -95,6 +95,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, |
2185 |
+ struct tcf_defact *d; |
2186 |
+ bool exists = false; |
2187 |
+ int ret = 0, err; |
2188 |
++ u32 index; |
2189 |
+ |
2190 |
+ if (nla == NULL) |
2191 |
+ return -EINVAL; |
2192 |
+@@ -108,7 +109,8 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, |
2193 |
+ return -EINVAL; |
2194 |
+ |
2195 |
+ parm = nla_data(tb[TCA_DEF_PARMS]); |
2196 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2197 |
++ index = parm->index; |
2198 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2199 |
+ if (err < 0) |
2200 |
+ return err; |
2201 |
+ exists = err; |
2202 |
+@@ -119,15 +121,15 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, |
2203 |
+ if (exists) |
2204 |
+ tcf_idr_release(*a, bind); |
2205 |
+ else |
2206 |
+- tcf_idr_cleanup(tn, parm->index); |
2207 |
++ tcf_idr_cleanup(tn, index); |
2208 |
+ return -EINVAL; |
2209 |
+ } |
2210 |
+ |
2211 |
+ if (!exists) { |
2212 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2213 |
++ ret = tcf_idr_create(tn, index, est, a, |
2214 |
+ &act_simp_ops, bind, false); |
2215 |
+ if (ret) { |
2216 |
+- tcf_idr_cleanup(tn, parm->index); |
2217 |
++ tcf_idr_cleanup(tn, index); |
2218 |
+ return ret; |
2219 |
+ } |
2220 |
+ |
2221 |
+diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c |
2222 |
+index 215a06705cef..b100870f02a6 100644 |
2223 |
+--- a/net/sched/act_skbedit.c |
2224 |
++++ b/net/sched/act_skbedit.c |
2225 |
+@@ -99,6 +99,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, |
2226 |
+ u16 *queue_mapping = NULL, *ptype = NULL; |
2227 |
+ bool exists = false; |
2228 |
+ int ret = 0, err; |
2229 |
++ u32 index; |
2230 |
+ |
2231 |
+ if (nla == NULL) |
2232 |
+ return -EINVAL; |
2233 |
+@@ -146,8 +147,8 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, |
2234 |
+ } |
2235 |
+ |
2236 |
+ parm = nla_data(tb[TCA_SKBEDIT_PARMS]); |
2237 |
+- |
2238 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2239 |
++ index = parm->index; |
2240 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2241 |
+ if (err < 0) |
2242 |
+ return err; |
2243 |
+ exists = err; |
2244 |
+@@ -158,15 +159,15 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, |
2245 |
+ if (exists) |
2246 |
+ tcf_idr_release(*a, bind); |
2247 |
+ else |
2248 |
+- tcf_idr_cleanup(tn, parm->index); |
2249 |
++ tcf_idr_cleanup(tn, index); |
2250 |
+ return -EINVAL; |
2251 |
+ } |
2252 |
+ |
2253 |
+ if (!exists) { |
2254 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2255 |
++ ret = tcf_idr_create(tn, index, est, a, |
2256 |
+ &act_skbedit_ops, bind, true); |
2257 |
+ if (ret) { |
2258 |
+- tcf_idr_cleanup(tn, parm->index); |
2259 |
++ tcf_idr_cleanup(tn, index); |
2260 |
+ return ret; |
2261 |
+ } |
2262 |
+ |
2263 |
+diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c |
2264 |
+index 4f07706eff07..7da3518e18ef 100644 |
2265 |
+--- a/net/sched/act_skbmod.c |
2266 |
++++ b/net/sched/act_skbmod.c |
2267 |
+@@ -87,12 +87,12 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, |
2268 |
+ struct tcf_skbmod_params *p, *p_old; |
2269 |
+ struct tcf_chain *goto_ch = NULL; |
2270 |
+ struct tc_skbmod *parm; |
2271 |
++ u32 lflags = 0, index; |
2272 |
+ struct tcf_skbmod *d; |
2273 |
+ bool exists = false; |
2274 |
+ u8 *daddr = NULL; |
2275 |
+ u8 *saddr = NULL; |
2276 |
+ u16 eth_type = 0; |
2277 |
+- u32 lflags = 0; |
2278 |
+ int ret = 0, err; |
2279 |
+ |
2280 |
+ if (!nla) |
2281 |
+@@ -122,10 +122,11 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, |
2282 |
+ } |
2283 |
+ |
2284 |
+ parm = nla_data(tb[TCA_SKBMOD_PARMS]); |
2285 |
++ index = parm->index; |
2286 |
+ if (parm->flags & SKBMOD_F_SWAPMAC) |
2287 |
+ lflags = SKBMOD_F_SWAPMAC; |
2288 |
+ |
2289 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2290 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2291 |
+ if (err < 0) |
2292 |
+ return err; |
2293 |
+ exists = err; |
2294 |
+@@ -136,15 +137,15 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, |
2295 |
+ if (exists) |
2296 |
+ tcf_idr_release(*a, bind); |
2297 |
+ else |
2298 |
+- tcf_idr_cleanup(tn, parm->index); |
2299 |
++ tcf_idr_cleanup(tn, index); |
2300 |
+ return -EINVAL; |
2301 |
+ } |
2302 |
+ |
2303 |
+ if (!exists) { |
2304 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2305 |
++ ret = tcf_idr_create(tn, index, est, a, |
2306 |
+ &act_skbmod_ops, bind, true); |
2307 |
+ if (ret) { |
2308 |
+- tcf_idr_cleanup(tn, parm->index); |
2309 |
++ tcf_idr_cleanup(tn, index); |
2310 |
+ return ret; |
2311 |
+ } |
2312 |
+ |
2313 |
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c |
2314 |
+index 10dffda1d5cc..6d0debdc9b97 100644 |
2315 |
+--- a/net/sched/act_tunnel_key.c |
2316 |
++++ b/net/sched/act_tunnel_key.c |
2317 |
+@@ -225,6 +225,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, |
2318 |
+ __be16 flags = 0; |
2319 |
+ u8 tos, ttl; |
2320 |
+ int ret = 0; |
2321 |
++ u32 index; |
2322 |
+ int err; |
2323 |
+ |
2324 |
+ if (!nla) { |
2325 |
+@@ -245,7 +246,8 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, |
2326 |
+ } |
2327 |
+ |
2328 |
+ parm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]); |
2329 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2330 |
++ index = parm->index; |
2331 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2332 |
+ if (err < 0) |
2333 |
+ return err; |
2334 |
+ exists = err; |
2335 |
+@@ -345,7 +347,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, |
2336 |
+ } |
2337 |
+ |
2338 |
+ if (!exists) { |
2339 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2340 |
++ ret = tcf_idr_create(tn, index, est, a, |
2341 |
+ &act_tunnel_key_ops, bind, true); |
2342 |
+ if (ret) { |
2343 |
+ NL_SET_ERR_MSG(extack, "Cannot create TC IDR"); |
2344 |
+@@ -403,7 +405,7 @@ err_out: |
2345 |
+ if (exists) |
2346 |
+ tcf_idr_release(*a, bind); |
2347 |
+ else |
2348 |
+- tcf_idr_cleanup(tn, parm->index); |
2349 |
++ tcf_idr_cleanup(tn, index); |
2350 |
+ return ret; |
2351 |
+ } |
2352 |
+ |
2353 |
+diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c |
2354 |
+index 9269d350fb8a..a3c9eea1ee8a 100644 |
2355 |
+--- a/net/sched/act_vlan.c |
2356 |
++++ b/net/sched/act_vlan.c |
2357 |
+@@ -116,6 +116,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, |
2358 |
+ u8 push_prio = 0; |
2359 |
+ bool exists = false; |
2360 |
+ int ret = 0, err; |
2361 |
++ u32 index; |
2362 |
+ |
2363 |
+ if (!nla) |
2364 |
+ return -EINVAL; |
2365 |
+@@ -128,7 +129,8 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, |
2366 |
+ if (!tb[TCA_VLAN_PARMS]) |
2367 |
+ return -EINVAL; |
2368 |
+ parm = nla_data(tb[TCA_VLAN_PARMS]); |
2369 |
+- err = tcf_idr_check_alloc(tn, &parm->index, a, bind); |
2370 |
++ index = parm->index; |
2371 |
++ err = tcf_idr_check_alloc(tn, &index, a, bind); |
2372 |
+ if (err < 0) |
2373 |
+ return err; |
2374 |
+ exists = err; |
2375 |
+@@ -144,7 +146,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, |
2376 |
+ if (exists) |
2377 |
+ tcf_idr_release(*a, bind); |
2378 |
+ else |
2379 |
+- tcf_idr_cleanup(tn, parm->index); |
2380 |
++ tcf_idr_cleanup(tn, index); |
2381 |
+ return -EINVAL; |
2382 |
+ } |
2383 |
+ push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]); |
2384 |
+@@ -152,7 +154,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, |
2385 |
+ if (exists) |
2386 |
+ tcf_idr_release(*a, bind); |
2387 |
+ else |
2388 |
+- tcf_idr_cleanup(tn, parm->index); |
2389 |
++ tcf_idr_cleanup(tn, index); |
2390 |
+ return -ERANGE; |
2391 |
+ } |
2392 |
+ |
2393 |
+@@ -166,7 +168,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, |
2394 |
+ if (exists) |
2395 |
+ tcf_idr_release(*a, bind); |
2396 |
+ else |
2397 |
+- tcf_idr_cleanup(tn, parm->index); |
2398 |
++ tcf_idr_cleanup(tn, index); |
2399 |
+ return -EPROTONOSUPPORT; |
2400 |
+ } |
2401 |
+ } else { |
2402 |
+@@ -180,16 +182,16 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, |
2403 |
+ if (exists) |
2404 |
+ tcf_idr_release(*a, bind); |
2405 |
+ else |
2406 |
+- tcf_idr_cleanup(tn, parm->index); |
2407 |
++ tcf_idr_cleanup(tn, index); |
2408 |
+ return -EINVAL; |
2409 |
+ } |
2410 |
+ action = parm->v_action; |
2411 |
+ |
2412 |
+ if (!exists) { |
2413 |
+- ret = tcf_idr_create(tn, parm->index, est, a, |
2414 |
++ ret = tcf_idr_create(tn, index, est, a, |
2415 |
+ &act_vlan_ops, bind, true); |
2416 |
+ if (ret) { |
2417 |
+- tcf_idr_cleanup(tn, parm->index); |
2418 |
++ tcf_idr_cleanup(tn, index); |
2419 |
+ return ret; |
2420 |
+ } |
2421 |
+ |
2422 |
+@@ -306,6 +308,14 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index) |
2423 |
+ return tcf_idr_search(tn, a, index); |
2424 |
+ } |
2425 |
+ |
2426 |
++static size_t tcf_vlan_get_fill_size(const struct tc_action *act) |
2427 |
++{ |
2428 |
++ return nla_total_size(sizeof(struct tc_vlan)) |
2429 |
++ + nla_total_size(sizeof(u16)) /* TCA_VLAN_PUSH_VLAN_ID */ |
2430 |
++ + nla_total_size(sizeof(u16)) /* TCA_VLAN_PUSH_VLAN_PROTOCOL */ |
2431 |
++ + nla_total_size(sizeof(u8)); /* TCA_VLAN_PUSH_VLAN_PRIORITY */ |
2432 |
++} |
2433 |
++ |
2434 |
+ static struct tc_action_ops act_vlan_ops = { |
2435 |
+ .kind = "vlan", |
2436 |
+ .id = TCA_ID_VLAN, |
2437 |
+@@ -315,6 +325,7 @@ static struct tc_action_ops act_vlan_ops = { |
2438 |
+ .init = tcf_vlan_init, |
2439 |
+ .cleanup = tcf_vlan_cleanup, |
2440 |
+ .walk = tcf_vlan_walker, |
2441 |
++ .get_fill_size = tcf_vlan_get_fill_size, |
2442 |
+ .lookup = tcf_vlan_search, |
2443 |
+ .size = sizeof(struct tcf_vlan), |
2444 |
+ }; |
2445 |
+diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c |
2446 |
+index 25ef172c23df..30169b3adbbb 100644 |
2447 |
+--- a/net/sched/sch_codel.c |
2448 |
++++ b/net/sched/sch_codel.c |
2449 |
+@@ -71,10 +71,10 @@ static struct sk_buff *dequeue_func(struct codel_vars *vars, void *ctx) |
2450 |
+ struct Qdisc *sch = ctx; |
2451 |
+ struct sk_buff *skb = __qdisc_dequeue_head(&sch->q); |
2452 |
+ |
2453 |
+- if (skb) |
2454 |
++ if (skb) { |
2455 |
+ sch->qstats.backlog -= qdisc_pkt_len(skb); |
2456 |
+- |
2457 |
+- prefetch(&skb->end); /* we'll need skb_shinfo() */ |
2458 |
++ prefetch(&skb->end); /* we'll need skb_shinfo() */ |
2459 |
++ } |
2460 |
+ return skb; |
2461 |
+ } |
2462 |
+ |
2463 |
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c |
2464 |
+index 7621ec2f539c..a3cc879d2589 100644 |
2465 |
+--- a/net/smc/af_smc.c |
2466 |
++++ b/net/smc/af_smc.c |
2467 |
+@@ -253,7 +253,7 @@ static int smc_bind(struct socket *sock, struct sockaddr *uaddr, |
2468 |
+ |
2469 |
+ /* Check if socket is already active */ |
2470 |
+ rc = -EINVAL; |
2471 |
+- if (sk->sk_state != SMC_INIT) |
2472 |
++ if (sk->sk_state != SMC_INIT || smc->connect_nonblock) |
2473 |
+ goto out_rel; |
2474 |
+ |
2475 |
+ smc->clcsock->sk->sk_reuse = sk->sk_reuse; |
2476 |
+@@ -1399,7 +1399,8 @@ static int smc_listen(struct socket *sock, int backlog) |
2477 |
+ lock_sock(sk); |
2478 |
+ |
2479 |
+ rc = -EINVAL; |
2480 |
+- if ((sk->sk_state != SMC_INIT) && (sk->sk_state != SMC_LISTEN)) |
2481 |
++ if ((sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) || |
2482 |
++ smc->connect_nonblock) |
2483 |
+ goto out; |
2484 |
+ |
2485 |
+ rc = 0; |
2486 |
+@@ -1527,7 +1528,7 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) |
2487 |
+ goto out; |
2488 |
+ |
2489 |
+ if (msg->msg_flags & MSG_FASTOPEN) { |
2490 |
+- if (sk->sk_state == SMC_INIT) { |
2491 |
++ if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) { |
2492 |
+ smc_switch_to_fallback(smc); |
2493 |
+ smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP; |
2494 |
+ } else { |
2495 |
+@@ -1741,14 +1742,18 @@ static int smc_setsockopt(struct socket *sock, int level, int optname, |
2496 |
+ } |
2497 |
+ break; |
2498 |
+ case TCP_NODELAY: |
2499 |
+- if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) { |
2500 |
++ if (sk->sk_state != SMC_INIT && |
2501 |
++ sk->sk_state != SMC_LISTEN && |
2502 |
++ sk->sk_state != SMC_CLOSED) { |
2503 |
+ if (val && !smc->use_fallback) |
2504 |
+ mod_delayed_work(system_wq, &smc->conn.tx_work, |
2505 |
+ 0); |
2506 |
+ } |
2507 |
+ break; |
2508 |
+ case TCP_CORK: |
2509 |
+- if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) { |
2510 |
++ if (sk->sk_state != SMC_INIT && |
2511 |
++ sk->sk_state != SMC_LISTEN && |
2512 |
++ sk->sk_state != SMC_CLOSED) { |
2513 |
+ if (!val && !smc->use_fallback) |
2514 |
+ mod_delayed_work(system_wq, &smc->conn.tx_work, |
2515 |
+ 0); |
2516 |
+diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c |
2517 |
+index cf155061c472..acd8a72169c1 100644 |
2518 |
+--- a/net/tipc/netlink_compat.c |
2519 |
++++ b/net/tipc/netlink_compat.c |
2520 |
+@@ -55,6 +55,7 @@ struct tipc_nl_compat_msg { |
2521 |
+ int rep_type; |
2522 |
+ int rep_size; |
2523 |
+ int req_type; |
2524 |
++ int req_size; |
2525 |
+ struct net *net; |
2526 |
+ struct sk_buff *rep; |
2527 |
+ struct tlv_desc *req; |
2528 |
+@@ -257,7 +258,8 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, |
2529 |
+ int err; |
2530 |
+ struct sk_buff *arg; |
2531 |
+ |
2532 |
+- if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) |
2533 |
++ if (msg->req_type && (!msg->req_size || |
2534 |
++ !TLV_CHECK_TYPE(msg->req, msg->req_type))) |
2535 |
+ return -EINVAL; |
2536 |
+ |
2537 |
+ msg->rep = tipc_tlv_alloc(msg->rep_size); |
2538 |
+@@ -354,7 +356,8 @@ static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, |
2539 |
+ { |
2540 |
+ int err; |
2541 |
+ |
2542 |
+- if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) |
2543 |
++ if (msg->req_type && (!msg->req_size || |
2544 |
++ !TLV_CHECK_TYPE(msg->req, msg->req_type))) |
2545 |
+ return -EINVAL; |
2546 |
+ |
2547 |
+ err = __tipc_nl_compat_doit(cmd, msg); |
2548 |
+@@ -1288,8 +1291,8 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) |
2549 |
+ goto send; |
2550 |
+ } |
2551 |
+ |
2552 |
+- len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); |
2553 |
+- if (!len || !TLV_OK(msg.req, len)) { |
2554 |
++ msg.req_size = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); |
2555 |
++ if (msg.req_size && !TLV_OK(msg.req, msg.req_size)) { |
2556 |
+ msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); |
2557 |
+ err = -EOPNOTSUPP; |
2558 |
+ goto send; |
2559 |
+diff --git a/net/tipc/socket.c b/net/tipc/socket.c |
2560 |
+index dd8537f988c4..83ae41d7e554 100644 |
2561 |
+--- a/net/tipc/socket.c |
2562 |
++++ b/net/tipc/socket.c |
2563 |
+@@ -485,9 +485,8 @@ static int tipc_sk_create(struct net *net, struct socket *sock, |
2564 |
+ tsk_set_unreturnable(tsk, true); |
2565 |
+ if (sock->type == SOCK_DGRAM) |
2566 |
+ tsk_set_unreliable(tsk, true); |
2567 |
+- __skb_queue_head_init(&tsk->mc_method.deferredq); |
2568 |
+ } |
2569 |
+- |
2570 |
++ __skb_queue_head_init(&tsk->mc_method.deferredq); |
2571 |
+ trace_tipc_sk_create(sk, NULL, TIPC_DUMP_NONE, " "); |
2572 |
+ return 0; |
2573 |
+ } |
2574 |
+diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c |
2575 |
+index 62dcdf082349..6c81a911fc02 100644 |
2576 |
+--- a/net/vmw_vsock/hyperv_transport.c |
2577 |
++++ b/net/vmw_vsock/hyperv_transport.c |
2578 |
+@@ -311,6 +311,11 @@ static void hvs_close_connection(struct vmbus_channel *chan) |
2579 |
+ lock_sock(sk); |
2580 |
+ hvs_do_close_lock_held(vsock_sk(sk), true); |
2581 |
+ release_sock(sk); |
2582 |
++ |
2583 |
++ /* Release the refcnt for the channel that's opened in |
2584 |
++ * hvs_open_connection(). |
2585 |
++ */ |
2586 |
++ sock_put(sk); |
2587 |
+ } |
2588 |
+ |
2589 |
+ static void hvs_open_connection(struct vmbus_channel *chan) |
2590 |
+@@ -378,6 +383,9 @@ static void hvs_open_connection(struct vmbus_channel *chan) |
2591 |
+ } |
2592 |
+ |
2593 |
+ set_per_channel_state(chan, conn_from_host ? new : sk); |
2594 |
++ |
2595 |
++ /* This reference will be dropped by hvs_close_connection(). */ |
2596 |
++ sock_hold(conn_from_host ? new : sk); |
2597 |
+ vmbus_set_chn_rescind_callback(chan, hvs_close_connection); |
2598 |
+ |
2599 |
+ /* Set the pending send size to max packet size to always get |
2600 |
+diff --git a/sound/usb/helper.c b/sound/usb/helper.c |
2601 |
+index 84aa265dd802..4c12cc5b53fd 100644 |
2602 |
+--- a/sound/usb/helper.c |
2603 |
++++ b/sound/usb/helper.c |
2604 |
+@@ -63,6 +63,20 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype |
2605 |
+ return NULL; |
2606 |
+ } |
2607 |
+ |
2608 |
++/* check the validity of pipe and EP types */ |
2609 |
++int snd_usb_pipe_sanity_check(struct usb_device *dev, unsigned int pipe) |
2610 |
++{ |
2611 |
++ static const int pipetypes[4] = { |
2612 |
++ PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT |
2613 |
++ }; |
2614 |
++ struct usb_host_endpoint *ep; |
2615 |
++ |
2616 |
++ ep = usb_pipe_endpoint(dev, pipe); |
2617 |
++ if (!ep || usb_pipetype(pipe) != pipetypes[usb_endpoint_type(&ep->desc)]) |
2618 |
++ return -EINVAL; |
2619 |
++ return 0; |
2620 |
++} |
2621 |
++ |
2622 |
+ /* |
2623 |
+ * Wrapper for usb_control_msg(). |
2624 |
+ * Allocates a temp buffer to prevent dmaing from/to the stack. |
2625 |
+@@ -75,6 +89,9 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, |
2626 |
+ void *buf = NULL; |
2627 |
+ int timeout; |
2628 |
+ |
2629 |
++ if (snd_usb_pipe_sanity_check(dev, pipe)) |
2630 |
++ return -EINVAL; |
2631 |
++ |
2632 |
+ if (size > 0) { |
2633 |
+ buf = kmemdup(data, size, GFP_KERNEL); |
2634 |
+ if (!buf) |
2635 |
+diff --git a/sound/usb/helper.h b/sound/usb/helper.h |
2636 |
+index d338bd0e0ca6..6afb70156ec4 100644 |
2637 |
+--- a/sound/usb/helper.h |
2638 |
++++ b/sound/usb/helper.h |
2639 |
+@@ -7,6 +7,7 @@ unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size); |
2640 |
+ void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype); |
2641 |
+ void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype); |
2642 |
+ |
2643 |
++int snd_usb_pipe_sanity_check(struct usb_device *dev, unsigned int pipe); |
2644 |
+ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, |
2645 |
+ __u8 request, __u8 requesttype, __u16 value, __u16 index, |
2646 |
+ void *data, __u16 size); |
2647 |
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c |
2648 |
+index cf5cff10c08e..78858918cbc1 100644 |
2649 |
+--- a/sound/usb/quirks.c |
2650 |
++++ b/sound/usb/quirks.c |
2651 |
+@@ -828,11 +828,13 @@ static int snd_usb_novation_boot_quirk(struct usb_device *dev) |
2652 |
+ static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev) |
2653 |
+ { |
2654 |
+ int err, actual_length; |
2655 |
+- |
2656 |
+ /* "midi send" enable */ |
2657 |
+ static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 }; |
2658 |
++ void *buf; |
2659 |
+ |
2660 |
+- void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL); |
2661 |
++ if (snd_usb_pipe_sanity_check(dev, usb_sndintpipe(dev, 0x05))) |
2662 |
++ return -EINVAL; |
2663 |
++ buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL); |
2664 |
+ if (!buf) |
2665 |
+ return -ENOMEM; |
2666 |
+ err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf, |
2667 |
+@@ -857,7 +859,11 @@ static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev) |
2668 |
+ |
2669 |
+ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) |
2670 |
+ { |
2671 |
+- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
2672 |
++ int ret; |
2673 |
++ |
2674 |
++ if (snd_usb_pipe_sanity_check(dev, usb_sndctrlpipe(dev, 0))) |
2675 |
++ return -EINVAL; |
2676 |
++ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
2677 |
+ 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
2678 |
+ 1, 0, NULL, 0, 1000); |
2679 |
+ |
2680 |
+@@ -964,6 +970,8 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev) |
2681 |
+ |
2682 |
+ dev_dbg(&dev->dev, "Waiting for Axe-Fx III to boot up...\n"); |
2683 |
+ |
2684 |
++ if (snd_usb_pipe_sanity_check(dev, usb_sndctrlpipe(dev, 0))) |
2685 |
++ return -EINVAL; |
2686 |
+ /* If the Axe-Fx III has not fully booted, it will timeout when trying |
2687 |
+ * to enable the audio streaming interface. A more generous timeout is |
2688 |
+ * used here to detect when the Axe-Fx III has finished booting as the |
2689 |
+@@ -996,6 +1004,8 @@ static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf, |
2690 |
+ { |
2691 |
+ int err, actual_length; |
2692 |
+ |
2693 |
++ if (snd_usb_pipe_sanity_check(dev, usb_sndintpipe(dev, 0x01))) |
2694 |
++ return -EINVAL; |
2695 |
+ err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x01), buf, *length, |
2696 |
+ &actual_length, 1000); |
2697 |
+ if (err < 0) |
2698 |
+@@ -1006,6 +1016,8 @@ static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf, |
2699 |
+ |
2700 |
+ memset(buf, 0, buf_size); |
2701 |
+ |
2702 |
++ if (snd_usb_pipe_sanity_check(dev, usb_rcvintpipe(dev, 0x82))) |
2703 |
++ return -EINVAL; |
2704 |
+ err = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x82), buf, buf_size, |
2705 |
+ &actual_length, 1000); |
2706 |
+ if (err < 0) |
2707 |
+diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile |
2708 |
+index f1573a11d3e4..b9e88ccc289b 100644 |
2709 |
+--- a/tools/testing/selftests/bpf/Makefile |
2710 |
++++ b/tools/testing/selftests/bpf/Makefile |
2711 |
+@@ -51,7 +51,8 @@ TEST_PROGS := test_kmod.sh \ |
2712 |
+ test_lirc_mode2.sh \ |
2713 |
+ test_skb_cgroup_id.sh \ |
2714 |
+ test_flow_dissector.sh \ |
2715 |
+- test_xdp_vlan.sh \ |
2716 |
++ test_xdp_vlan_mode_generic.sh \ |
2717 |
++ test_xdp_vlan_mode_native.sh \ |
2718 |
+ test_lwt_ip_encap.sh \ |
2719 |
+ test_tcp_check_syncookie.sh \ |
2720 |
+ test_tc_tunnel.sh \ |
2721 |
+diff --git a/tools/testing/selftests/bpf/test_xdp_vlan.sh b/tools/testing/selftests/bpf/test_xdp_vlan.sh |
2722 |
+index 51a3a31d1aac..bb8b0da91686 100755 |
2723 |
+--- a/tools/testing/selftests/bpf/test_xdp_vlan.sh |
2724 |
++++ b/tools/testing/selftests/bpf/test_xdp_vlan.sh |
2725 |
+@@ -1,6 +1,14 @@ |
2726 |
+ #!/bin/bash |
2727 |
++# SPDX-License-Identifier: GPL-2.0 |
2728 |
++# Author: Jesper Dangaard Brouer <hawk@××××××.org> |
2729 |
+ |
2730 |
+-TESTNAME=xdp_vlan |
2731 |
++# Allow wrapper scripts to name test |
2732 |
++if [ -z "$TESTNAME" ]; then |
2733 |
++ TESTNAME=xdp_vlan |
2734 |
++fi |
2735 |
++ |
2736 |
++# Default XDP mode |
2737 |
++XDP_MODE=xdpgeneric |
2738 |
+ |
2739 |
+ usage() { |
2740 |
+ echo "Testing XDP + TC eBPF VLAN manipulations: $TESTNAME" |
2741 |
+@@ -9,9 +17,23 @@ usage() { |
2742 |
+ echo " -v | --verbose : Verbose" |
2743 |
+ echo " --flush : Flush before starting (e.g. after --interactive)" |
2744 |
+ echo " --interactive : Keep netns setup running after test-run" |
2745 |
++ echo " --mode=XXX : Choose XDP mode (xdp | xdpgeneric | xdpdrv)" |
2746 |
+ echo "" |
2747 |
+ } |
2748 |
+ |
2749 |
++valid_xdp_mode() |
2750 |
++{ |
2751 |
++ local mode=$1 |
2752 |
++ |
2753 |
++ case "$mode" in |
2754 |
++ xdpgeneric | xdpdrv | xdp) |
2755 |
++ return 0 |
2756 |
++ ;; |
2757 |
++ *) |
2758 |
++ return 1 |
2759 |
++ esac |
2760 |
++} |
2761 |
++ |
2762 |
+ cleanup() |
2763 |
+ { |
2764 |
+ local status=$? |
2765 |
+@@ -37,7 +59,7 @@ cleanup() |
2766 |
+ |
2767 |
+ # Using external program "getopt" to get --long-options |
2768 |
+ OPTIONS=$(getopt -o hvfi: \ |
2769 |
+- --long verbose,flush,help,interactive,debug -- "$@") |
2770 |
++ --long verbose,flush,help,interactive,debug,mode: -- "$@") |
2771 |
+ if (( $? != 0 )); then |
2772 |
+ usage |
2773 |
+ echo "selftests: $TESTNAME [FAILED] Error calling getopt, unknown option?" |
2774 |
+@@ -60,6 +82,11 @@ while true; do |
2775 |
+ cleanup |
2776 |
+ shift |
2777 |
+ ;; |
2778 |
++ --mode ) |
2779 |
++ shift |
2780 |
++ XDP_MODE=$1 |
2781 |
++ shift |
2782 |
++ ;; |
2783 |
+ -- ) |
2784 |
+ shift |
2785 |
+ break |
2786 |
+@@ -81,8 +108,14 @@ if [ "$EUID" -ne 0 ]; then |
2787 |
+ exit 1 |
2788 |
+ fi |
2789 |
+ |
2790 |
+-ip link set dev lo xdp off 2>/dev/null > /dev/null |
2791 |
+-if [ $? -ne 0 ];then |
2792 |
++valid_xdp_mode $XDP_MODE |
2793 |
++if [ $? -ne 0 ]; then |
2794 |
++ echo "selftests: $TESTNAME [FAILED] unknown XDP mode ($XDP_MODE)" |
2795 |
++ exit 1 |
2796 |
++fi |
2797 |
++ |
2798 |
++ip link set dev lo xdpgeneric off 2>/dev/null > /dev/null |
2799 |
++if [ $? -ne 0 ]; then |
2800 |
+ echo "selftests: $TESTNAME [SKIP] need ip xdp support" |
2801 |
+ exit 0 |
2802 |
+ fi |
2803 |
+@@ -155,7 +188,7 @@ ip netns exec ns2 ip link set lo up |
2804 |
+ # At this point, the hosts cannot reach each-other, |
2805 |
+ # because ns2 are using VLAN tags on the packets. |
2806 |
+ |
2807 |
+-ip netns exec ns2 sh -c 'ping -W 1 -c 1 100.64.41.1 || echo "Okay ping fails"' |
2808 |
++ip netns exec ns2 sh -c 'ping -W 1 -c 1 100.64.41.1 || echo "Success: First ping must fail"' |
2809 |
+ |
2810 |
+ |
2811 |
+ # Now we can use the test_xdp_vlan.c program to pop/push these VLAN tags |
2812 |
+@@ -166,7 +199,7 @@ export FILE=test_xdp_vlan.o |
2813 |
+ |
2814 |
+ # First test: Remove VLAN by setting VLAN ID 0, using "xdp_vlan_change" |
2815 |
+ export XDP_PROG=xdp_vlan_change |
2816 |
+-ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG |
2817 |
++ip netns exec ns1 ip link set $DEVNS1 $XDP_MODE object $FILE section $XDP_PROG |
2818 |
+ |
2819 |
+ # In ns1: egress use TC to add back VLAN tag 4011 |
2820 |
+ # (del cmd) |
2821 |
+@@ -177,8 +210,8 @@ ip netns exec ns1 tc filter add dev $DEVNS1 egress \ |
2822 |
+ prio 1 handle 1 bpf da obj $FILE sec tc_vlan_push |
2823 |
+ |
2824 |
+ # Now the namespaces can reach each-other, test with ping: |
2825 |
+-ip netns exec ns2 ping -W 2 -c 3 $IPADDR1 |
2826 |
+-ip netns exec ns1 ping -W 2 -c 3 $IPADDR2 |
2827 |
++ip netns exec ns2 ping -i 0.2 -W 2 -c 2 $IPADDR1 |
2828 |
++ip netns exec ns1 ping -i 0.2 -W 2 -c 2 $IPADDR2 |
2829 |
+ |
2830 |
+ # Second test: Replace xdp prog, that fully remove vlan header |
2831 |
+ # |
2832 |
+@@ -187,9 +220,9 @@ ip netns exec ns1 ping -W 2 -c 3 $IPADDR2 |
2833 |
+ # ETH_P_8021Q indication, and this cause overwriting of our changes. |
2834 |
+ # |
2835 |
+ export XDP_PROG=xdp_vlan_remove_outer2 |
2836 |
+-ip netns exec ns1 ip link set $DEVNS1 xdp off |
2837 |
+-ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG |
2838 |
++ip netns exec ns1 ip link set $DEVNS1 $XDP_MODE off |
2839 |
++ip netns exec ns1 ip link set $DEVNS1 $XDP_MODE object $FILE section $XDP_PROG |
2840 |
+ |
2841 |
+ # Now the namespaces should still be able reach each-other, test with ping: |
2842 |
+-ip netns exec ns2 ping -W 2 -c 3 $IPADDR1 |
2843 |
+-ip netns exec ns1 ping -W 2 -c 3 $IPADDR2 |
2844 |
++ip netns exec ns2 ping -i 0.2 -W 2 -c 2 $IPADDR1 |
2845 |
++ip netns exec ns1 ping -i 0.2 -W 2 -c 2 $IPADDR2 |
2846 |
+diff --git a/tools/testing/selftests/bpf/test_xdp_vlan_mode_generic.sh b/tools/testing/selftests/bpf/test_xdp_vlan_mode_generic.sh |
2847 |
+new file mode 100644 |
2848 |
+index 000000000000..c515326d6d59 |
2849 |
+--- /dev/null |
2850 |
++++ b/tools/testing/selftests/bpf/test_xdp_vlan_mode_generic.sh |
2851 |
+@@ -0,0 +1,9 @@ |
2852 |
++#!/bin/bash |
2853 |
++# SPDX-License-Identifier: GPL-2.0 |
2854 |
++ |
2855 |
++# Exit on failure |
2856 |
++set -e |
2857 |
++ |
2858 |
++# Wrapper script to test generic-XDP |
2859 |
++export TESTNAME=xdp_vlan_mode_generic |
2860 |
++./test_xdp_vlan.sh --mode=xdpgeneric |
2861 |
+diff --git a/tools/testing/selftests/bpf/test_xdp_vlan_mode_native.sh b/tools/testing/selftests/bpf/test_xdp_vlan_mode_native.sh |
2862 |
+new file mode 100644 |
2863 |
+index 000000000000..5cf7ce1f16c1 |
2864 |
+--- /dev/null |
2865 |
++++ b/tools/testing/selftests/bpf/test_xdp_vlan_mode_native.sh |
2866 |
+@@ -0,0 +1,9 @@ |
2867 |
++#!/bin/bash |
2868 |
++# SPDX-License-Identifier: GPL-2.0 |
2869 |
++ |
2870 |
++# Exit on failure |
2871 |
++set -e |
2872 |
++ |
2873 |
++# Wrapper script to test native-XDP |
2874 |
++export TESTNAME=xdp_vlan_mode_native |
2875 |
++./test_xdp_vlan.sh --mode=xdpdrv |