1 |
commit: 7479460913c1df286827f19d9f4c454dcea094af |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Mar 2 13:09:05 2022 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Mar 2 13:09:05 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=74794609 |
7 |
|
8 |
Linux patch 4.9.304 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1303_linux-4.9.304.patch | 943 +++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 947 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 40c5fe88..84a4162f 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -1255,6 +1255,10 @@ Patch: 1302_linux-4.9.303.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 4.9.303 |
23 |
|
24 |
+Patch: 1303_linux-4.9.304.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 4.9.304 |
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/1303_linux-4.9.304.patch b/1303_linux-4.9.304.patch |
33 |
new file mode 100644 |
34 |
index 00000000..8b373ea3 |
35 |
--- /dev/null |
36 |
+++ b/1303_linux-4.9.304.patch |
37 |
@@ -0,0 +1,943 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index 27d5e129444e3..bd2f7d437b439 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,6 +1,6 @@ |
43 |
+ VERSION = 4 |
44 |
+ PATCHLEVEL = 9 |
45 |
+-SUBLEVEL = 303 |
46 |
++SUBLEVEL = 304 |
47 |
+ EXTRAVERSION = |
48 |
+ NAME = Roaring Lionus |
49 |
+ |
50 |
+diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c |
51 |
+index 2b65c01777789..957bdeb7a5c79 100644 |
52 |
+--- a/arch/parisc/kernel/unaligned.c |
53 |
++++ b/arch/parisc/kernel/unaligned.c |
54 |
+@@ -353,7 +353,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) |
55 |
+ : "r" (val), "r" (regs->ior), "r" (regs->isr) |
56 |
+ : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); |
57 |
+ |
58 |
+- return 0; |
59 |
++ return ret; |
60 |
+ } |
61 |
+ static int emulate_std(struct pt_regs *regs, int frreg, int flop) |
62 |
+ { |
63 |
+@@ -410,7 +410,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) |
64 |
+ __asm__ __volatile__ ( |
65 |
+ " mtsp %4, %%sr1\n" |
66 |
+ " zdep %2, 29, 2, %%r19\n" |
67 |
+-" dep %%r0, 31, 2, %2\n" |
68 |
++" dep %%r0, 31, 2, %3\n" |
69 |
+ " mtsar %%r19\n" |
70 |
+ " zvdepi -2, 32, %%r19\n" |
71 |
+ "1: ldw 0(%%sr1,%3),%%r20\n" |
72 |
+@@ -422,7 +422,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) |
73 |
+ " andcm %%r21, %%r19, %%r21\n" |
74 |
+ " or %1, %%r20, %1\n" |
75 |
+ " or %2, %%r21, %2\n" |
76 |
+-"3: stw %1,0(%%sr1,%1)\n" |
77 |
++"3: stw %1,0(%%sr1,%3)\n" |
78 |
+ "4: stw %%r1,4(%%sr1,%3)\n" |
79 |
+ "5: stw %2,8(%%sr1,%3)\n" |
80 |
+ " copy %%r0, %0\n" |
81 |
+@@ -610,7 +610,6 @@ void handle_unaligned(struct pt_regs *regs) |
82 |
+ ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */ |
83 |
+ break; |
84 |
+ } |
85 |
+-#ifdef CONFIG_PA20 |
86 |
+ switch (regs->iir & OPCODE2_MASK) |
87 |
+ { |
88 |
+ case OPCODE_FLDD_L: |
89 |
+@@ -621,22 +620,23 @@ void handle_unaligned(struct pt_regs *regs) |
90 |
+ flop=1; |
91 |
+ ret = emulate_std(regs, R2(regs->iir),1); |
92 |
+ break; |
93 |
++#ifdef CONFIG_PA20 |
94 |
+ case OPCODE_LDD_L: |
95 |
+ ret = emulate_ldd(regs, R2(regs->iir),0); |
96 |
+ break; |
97 |
+ case OPCODE_STD_L: |
98 |
+ ret = emulate_std(regs, R2(regs->iir),0); |
99 |
+ break; |
100 |
+- } |
101 |
+ #endif |
102 |
++ } |
103 |
+ switch (regs->iir & OPCODE3_MASK) |
104 |
+ { |
105 |
+ case OPCODE_FLDW_L: |
106 |
+ flop=1; |
107 |
+- ret = emulate_ldw(regs, R2(regs->iir),0); |
108 |
++ ret = emulate_ldw(regs, R2(regs->iir), 1); |
109 |
+ break; |
110 |
+ case OPCODE_LDW_M: |
111 |
+- ret = emulate_ldw(regs, R2(regs->iir),1); |
112 |
++ ret = emulate_ldw(regs, R2(regs->iir), 0); |
113 |
+ break; |
114 |
+ |
115 |
+ case OPCODE_FSTW_L: |
116 |
+diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c |
117 |
+index 3ba843f5cdc0f..821fc1f2324c8 100644 |
118 |
+--- a/drivers/ata/pata_hpt37x.c |
119 |
++++ b/drivers/ata/pata_hpt37x.c |
120 |
+@@ -919,6 +919,20 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
121 |
+ irqmask &= ~0x10; |
122 |
+ pci_write_config_byte(dev, 0x5a, irqmask); |
123 |
+ |
124 |
++ /* |
125 |
++ * HPT371 chips physically have only one channel, the secondary one, |
126 |
++ * but the primary channel registers do exist! Go figure... |
127 |
++ * So, we manually disable the non-existing channel here |
128 |
++ * (if the BIOS hasn't done this already). |
129 |
++ */ |
130 |
++ if (dev->device == PCI_DEVICE_ID_TTI_HPT371) { |
131 |
++ u8 mcr1; |
132 |
++ |
133 |
++ pci_read_config_byte(dev, 0x50, &mcr1); |
134 |
++ mcr1 &= ~0x04; |
135 |
++ pci_write_config_byte(dev, 0x50, mcr1); |
136 |
++ } |
137 |
++ |
138 |
+ /* |
139 |
+ * default to pci clock. make sure MA15/16 are set to output |
140 |
+ * to prevent drives having problems with 40-pin cables. Needed |
141 |
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c |
142 |
+index 5b5970f0e91d3..b07b32eb0c4bb 100644 |
143 |
+--- a/drivers/gpu/drm/drm_edid.c |
144 |
++++ b/drivers/gpu/drm/drm_edid.c |
145 |
+@@ -3886,6 +3886,7 @@ static void drm_add_display_info(struct drm_connector *connector, |
146 |
+ if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) |
147 |
+ return; |
148 |
+ |
149 |
++ info->color_formats |= DRM_COLOR_FORMAT_RGB444; |
150 |
+ drm_parse_cea_ext(connector, edid); |
151 |
+ |
152 |
+ /* |
153 |
+@@ -3934,7 +3935,6 @@ static void drm_add_display_info(struct drm_connector *connector, |
154 |
+ DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n", |
155 |
+ connector->name, info->bpc); |
156 |
+ |
157 |
+- info->color_formats |= DRM_COLOR_FORMAT_RGB444; |
158 |
+ if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) |
159 |
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
160 |
+ if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) |
161 |
+diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c |
162 |
+index 8f3606de4eafb..47be2cd2c60db 100644 |
163 |
+--- a/drivers/iio/adc/men_z188_adc.c |
164 |
++++ b/drivers/iio/adc/men_z188_adc.c |
165 |
+@@ -107,6 +107,7 @@ static int men_z188_probe(struct mcb_device *dev, |
166 |
+ struct z188_adc *adc; |
167 |
+ struct iio_dev *indio_dev; |
168 |
+ struct resource *mem; |
169 |
++ int ret; |
170 |
+ |
171 |
+ indio_dev = devm_iio_device_alloc(&dev->dev, sizeof(struct z188_adc)); |
172 |
+ if (!indio_dev) |
173 |
+@@ -133,8 +134,14 @@ static int men_z188_probe(struct mcb_device *dev, |
174 |
+ adc->mem = mem; |
175 |
+ mcb_set_drvdata(dev, indio_dev); |
176 |
+ |
177 |
+- return iio_device_register(indio_dev); |
178 |
++ ret = iio_device_register(indio_dev); |
179 |
++ if (ret) |
180 |
++ goto err_unmap; |
181 |
++ |
182 |
++ return 0; |
183 |
+ |
184 |
++err_unmap: |
185 |
++ iounmap(adc->base); |
186 |
+ err: |
187 |
+ mcb_release_mem(mem); |
188 |
+ return -ENXIO; |
189 |
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c |
190 |
+index af68be201c299..67b993f4ec91a 100644 |
191 |
+--- a/drivers/infiniband/ulp/srp/ib_srp.c |
192 |
++++ b/drivers/infiniband/ulp/srp/ib_srp.c |
193 |
+@@ -3646,9 +3646,11 @@ static void srp_remove_one(struct ib_device *device, void *client_data) |
194 |
+ spin_unlock(&host->target_lock); |
195 |
+ |
196 |
+ /* |
197 |
+- * Wait for tl_err and target port removal tasks. |
198 |
++ * srp_queue_remove_work() queues a call to |
199 |
++ * srp_remove_target(). The latter function cancels |
200 |
++ * target->tl_err_work so waiting for the remove works to |
201 |
++ * finish is sufficient. |
202 |
+ */ |
203 |
+- flush_workqueue(system_long_wq); |
204 |
+ flush_workqueue(srp_remove_wq); |
205 |
+ |
206 |
+ kfree(host); |
207 |
+diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c |
208 |
+index 40fdc9d267b96..1c8e95cf29d24 100644 |
209 |
+--- a/drivers/mtd/nand/brcmnand/brcmnand.c |
210 |
++++ b/drivers/mtd/nand/brcmnand/brcmnand.c |
211 |
+@@ -1637,7 +1637,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, |
212 |
+ mtd->oobsize / trans, |
213 |
+ host->hwcfg.sector_size_1k); |
214 |
+ |
215 |
+- if (!ret) { |
216 |
++ if (ret != -EBADMSG) { |
217 |
+ *err_addr = brcmnand_read_reg(ctrl, |
218 |
+ BRCMNAND_UNCORR_ADDR) | |
219 |
+ ((u64)(brcmnand_read_reg(ctrl, |
220 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
221 |
+index e13a6cd5163f4..5f23e26b0415e 100644 |
222 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
223 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
224 |
+@@ -1405,7 +1405,7 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev, |
225 |
+ if (size_read < 0) { |
226 |
+ netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n", |
227 |
+ __func__, size_read); |
228 |
+- return 0; |
229 |
++ return size_read; |
230 |
+ } |
231 |
+ |
232 |
+ i += size_read; |
233 |
+diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c |
234 |
+index 8f03cc52ddda2..1819b104418c4 100644 |
235 |
+--- a/drivers/net/usb/cdc_ether.c |
236 |
++++ b/drivers/net/usb/cdc_ether.c |
237 |
+@@ -555,6 +555,11 @@ static const struct usb_device_id products[] = { |
238 |
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ |
239 |
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE |
240 |
+ |
241 |
++#define ZAURUS_FAKE_INTERFACE \ |
242 |
++ .bInterfaceClass = USB_CLASS_COMM, \ |
243 |
++ .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \ |
244 |
++ .bInterfaceProtocol = USB_CDC_PROTO_NONE |
245 |
++ |
246 |
+ /* SA-1100 based Sharp Zaurus ("collie"), or compatible; |
247 |
+ * wire-incompatible with true CDC Ethernet implementations. |
248 |
+ * (And, it seems, needlessly so...) |
249 |
+@@ -608,6 +613,13 @@ static const struct usb_device_id products[] = { |
250 |
+ .idProduct = 0x9032, /* SL-6000 */ |
251 |
+ ZAURUS_MASTER_INTERFACE, |
252 |
+ .driver_info = 0, |
253 |
++}, { |
254 |
++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
255 |
++ | USB_DEVICE_ID_MATCH_DEVICE, |
256 |
++ .idVendor = 0x04DD, |
257 |
++ .idProduct = 0x9032, /* SL-6000 */ |
258 |
++ ZAURUS_FAKE_INTERFACE, |
259 |
++ .driver_info = 0, |
260 |
+ }, { |
261 |
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
262 |
+ | USB_DEVICE_ID_MATCH_DEVICE, |
263 |
+diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c |
264 |
+index aadfe1d1c37ee..f4c4df01874c3 100644 |
265 |
+--- a/drivers/net/usb/sr9700.c |
266 |
++++ b/drivers/net/usb/sr9700.c |
267 |
+@@ -409,7 +409,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
268 |
+ /* ignore the CRC length */ |
269 |
+ len = (skb->data[1] | (skb->data[2] << 8)) - 4; |
270 |
+ |
271 |
+- if (len > ETH_FRAME_LEN) |
272 |
++ if (len > ETH_FRAME_LEN || len > skb->len) |
273 |
+ return 0; |
274 |
+ |
275 |
+ /* the last packet of current skb */ |
276 |
+diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c |
277 |
+index 6aaa6eb9df72a..3d126761044f5 100644 |
278 |
+--- a/drivers/net/usb/zaurus.c |
279 |
++++ b/drivers/net/usb/zaurus.c |
280 |
+@@ -268,6 +268,11 @@ static const struct usb_device_id products [] = { |
281 |
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ |
282 |
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE |
283 |
+ |
284 |
++#define ZAURUS_FAKE_INTERFACE \ |
285 |
++ .bInterfaceClass = USB_CLASS_COMM, \ |
286 |
++ .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \ |
287 |
++ .bInterfaceProtocol = USB_CDC_PROTO_NONE |
288 |
++ |
289 |
+ /* SA-1100 based Sharp Zaurus ("collie"), or compatible. */ |
290 |
+ { |
291 |
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
292 |
+@@ -325,6 +330,13 @@ static const struct usb_device_id products [] = { |
293 |
+ .idProduct = 0x9032, /* SL-6000 */ |
294 |
+ ZAURUS_MASTER_INTERFACE, |
295 |
+ .driver_info = ZAURUS_PXA_INFO, |
296 |
++}, { |
297 |
++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
298 |
++ | USB_DEVICE_ID_MATCH_DEVICE, |
299 |
++ .idVendor = 0x04DD, |
300 |
++ .idProduct = 0x9032, /* SL-6000 */ |
301 |
++ ZAURUS_FAKE_INTERFACE, |
302 |
++ .driver_info = (unsigned long)&bogus_mdlm_info, |
303 |
+ }, { |
304 |
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
305 |
+ | USB_DEVICE_ID_MATCH_DEVICE, |
306 |
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c |
307 |
+index 67e5b587a1062..2311f8a635a6f 100644 |
308 |
+--- a/drivers/tty/n_gsm.c |
309 |
++++ b/drivers/tty/n_gsm.c |
310 |
+@@ -444,7 +444,7 @@ static u8 gsm_encode_modem(const struct gsm_dlci *dlci) |
311 |
+ modembits |= MDM_RTR; |
312 |
+ if (dlci->modem_tx & TIOCM_RI) |
313 |
+ modembits |= MDM_IC; |
314 |
+- if (dlci->modem_tx & TIOCM_CD) |
315 |
++ if (dlci->modem_tx & TIOCM_CD || dlci->gsm->initiator) |
316 |
+ modembits |= MDM_DV; |
317 |
+ return modembits; |
318 |
+ } |
319 |
+@@ -1506,7 +1506,7 @@ static void gsm_dlci_t1(unsigned long data) |
320 |
+ dlci->mode = DLCI_MODE_ADM; |
321 |
+ gsm_dlci_open(dlci); |
322 |
+ } else { |
323 |
+- gsm_dlci_close(dlci); |
324 |
++ gsm_dlci_begin_close(dlci); /* prevent half open link */ |
325 |
+ } |
326 |
+ |
327 |
+ break; |
328 |
+diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c |
329 |
+index f89dfde934a32..54ed7675e4470 100644 |
330 |
+--- a/drivers/tty/serial/8250/8250_of.c |
331 |
++++ b/drivers/tty/serial/8250/8250_of.c |
332 |
+@@ -86,7 +86,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, |
333 |
+ ret = of_address_to_resource(np, 0, &resource); |
334 |
+ if (ret) { |
335 |
+ dev_warn(&ofdev->dev, "invalid address\n"); |
336 |
+- goto out; |
337 |
++ goto err_unprepare; |
338 |
+ } |
339 |
+ |
340 |
+ spin_lock_init(&port->lock); |
341 |
+@@ -94,8 +94,17 @@ static int of_platform_serial_setup(struct platform_device *ofdev, |
342 |
+ port->mapsize = resource_size(&resource); |
343 |
+ |
344 |
+ /* Check for shifted address mapping */ |
345 |
+- if (of_property_read_u32(np, "reg-offset", &prop) == 0) |
346 |
++ if (of_property_read_u32(np, "reg-offset", &prop) == 0) { |
347 |
++ if (prop >= port->mapsize) { |
348 |
++ dev_warn(&ofdev->dev, "reg-offset %u exceeds region size %pa\n", |
349 |
++ prop, &port->mapsize); |
350 |
++ ret = -EINVAL; |
351 |
++ goto err_unprepare; |
352 |
++ } |
353 |
++ |
354 |
+ port->mapbase += prop; |
355 |
++ port->mapsize -= prop; |
356 |
++ } |
357 |
+ |
358 |
+ /* Compatibility with the deprecated pxa driver and 8250_pxa drivers. */ |
359 |
+ if (of_device_is_compatible(np, "mrvl,mmp-uart")) |
360 |
+@@ -132,7 +141,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, |
361 |
+ dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", |
362 |
+ prop); |
363 |
+ ret = -EINVAL; |
364 |
+- goto out; |
365 |
++ goto err_dispose; |
366 |
+ } |
367 |
+ } |
368 |
+ |
369 |
+@@ -162,7 +171,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev, |
370 |
+ port->handle_irq = fsl8250_handle_irq; |
371 |
+ |
372 |
+ return 0; |
373 |
+-out: |
374 |
++err_dispose: |
375 |
++ irq_dispose_mapping(port->irq); |
376 |
++err_unprepare: |
377 |
+ if (info->clk) |
378 |
+ clk_disable_unprepare(info->clk); |
379 |
+ return ret; |
380 |
+@@ -194,7 +205,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) |
381 |
+ port_type = (unsigned long)match->data; |
382 |
+ ret = of_platform_serial_setup(ofdev, port_type, &port, info); |
383 |
+ if (ret) |
384 |
+- goto out; |
385 |
++ goto err_free; |
386 |
+ |
387 |
+ switch (port_type) { |
388 |
+ case PORT_8250 ... PORT_MAX_8250: |
389 |
+@@ -228,15 +239,18 @@ static int of_platform_serial_probe(struct platform_device *ofdev) |
390 |
+ break; |
391 |
+ } |
392 |
+ if (ret < 0) |
393 |
+- goto out; |
394 |
++ goto err_dispose; |
395 |
+ |
396 |
+ info->type = port_type; |
397 |
+ info->line = ret; |
398 |
+ platform_set_drvdata(ofdev, info); |
399 |
+ return 0; |
400 |
+-out: |
401 |
+- kfree(info); |
402 |
++err_dispose: |
403 |
+ irq_dispose_mapping(port.irq); |
404 |
++ if (info->clk) |
405 |
++ clk_disable_unprepare(info->clk); |
406 |
++err_free: |
407 |
++ kfree(info); |
408 |
+ return ret; |
409 |
+ } |
410 |
+ |
411 |
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c |
412 |
+index 58c4b745eae13..ccc47594064f2 100644 |
413 |
+--- a/drivers/usb/dwc3/gadget.c |
414 |
++++ b/drivers/usb/dwc3/gadget.c |
415 |
+@@ -2904,9 +2904,11 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt) |
416 |
+ unsigned long flags; |
417 |
+ irqreturn_t ret = IRQ_NONE; |
418 |
+ |
419 |
++ local_bh_disable(); |
420 |
+ spin_lock_irqsave(&dwc->lock, flags); |
421 |
+ ret = dwc3_process_event_buf(evt); |
422 |
+ spin_unlock_irqrestore(&dwc->lock, flags); |
423 |
++ local_bh_enable(); |
424 |
+ |
425 |
+ return ret; |
426 |
+ } |
427 |
+diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c |
428 |
+index a912b6b9153fd..1e5c2cbe99947 100644 |
429 |
+--- a/drivers/usb/gadget/function/rndis.c |
430 |
++++ b/drivers/usb/gadget/function/rndis.c |
431 |
+@@ -924,6 +924,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v) |
432 |
+ params->resp_avail = resp_avail; |
433 |
+ params->v = v; |
434 |
+ INIT_LIST_HEAD(¶ms->resp_queue); |
435 |
++ spin_lock_init(¶ms->resp_lock); |
436 |
+ pr_debug("%s: configNr = %d\n", __func__, i); |
437 |
+ |
438 |
+ return params; |
439 |
+@@ -1017,12 +1018,14 @@ void rndis_free_response(struct rndis_params *params, u8 *buf) |
440 |
+ { |
441 |
+ rndis_resp_t *r, *n; |
442 |
+ |
443 |
++ spin_lock(¶ms->resp_lock); |
444 |
+ list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) { |
445 |
+ if (r->buf == buf) { |
446 |
+ list_del(&r->list); |
447 |
+ kfree(r); |
448 |
+ } |
449 |
+ } |
450 |
++ spin_unlock(¶ms->resp_lock); |
451 |
+ } |
452 |
+ EXPORT_SYMBOL_GPL(rndis_free_response); |
453 |
+ |
454 |
+@@ -1032,14 +1035,17 @@ u8 *rndis_get_next_response(struct rndis_params *params, u32 *length) |
455 |
+ |
456 |
+ if (!length) return NULL; |
457 |
+ |
458 |
++ spin_lock(¶ms->resp_lock); |
459 |
+ list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) { |
460 |
+ if (!r->send) { |
461 |
+ r->send = 1; |
462 |
+ *length = r->length; |
463 |
++ spin_unlock(¶ms->resp_lock); |
464 |
+ return r->buf; |
465 |
+ } |
466 |
+ } |
467 |
+ |
468 |
++ spin_unlock(¶ms->resp_lock); |
469 |
+ return NULL; |
470 |
+ } |
471 |
+ EXPORT_SYMBOL_GPL(rndis_get_next_response); |
472 |
+@@ -1056,7 +1062,9 @@ static rndis_resp_t *rndis_add_response(struct rndis_params *params, u32 length) |
473 |
+ r->length = length; |
474 |
+ r->send = 0; |
475 |
+ |
476 |
++ spin_lock(¶ms->resp_lock); |
477 |
+ list_add_tail(&r->list, ¶ms->resp_queue); |
478 |
++ spin_unlock(¶ms->resp_lock); |
479 |
+ return r; |
480 |
+ } |
481 |
+ |
482 |
+diff --git a/drivers/usb/gadget/function/rndis.h b/drivers/usb/gadget/function/rndis.h |
483 |
+index ef92eb66d8adf..a389df725a29e 100644 |
484 |
+--- a/drivers/usb/gadget/function/rndis.h |
485 |
++++ b/drivers/usb/gadget/function/rndis.h |
486 |
+@@ -194,6 +194,7 @@ typedef struct rndis_params |
487 |
+ void (*resp_avail)(void *v); |
488 |
+ void *v; |
489 |
+ struct list_head resp_queue; |
490 |
++ spinlock_t resp_lock; |
491 |
+ } rndis_params; |
492 |
+ |
493 |
+ /* RNDIS Message parser and other useless functions */ |
494 |
+diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c |
495 |
+index 588e2531b8b81..b4cc04b6ae036 100644 |
496 |
+--- a/drivers/usb/gadget/udc/udc-xilinx.c |
497 |
++++ b/drivers/usb/gadget/udc/udc-xilinx.c |
498 |
+@@ -1620,6 +1620,8 @@ static void xudc_getstatus(struct xusb_udc *udc) |
499 |
+ break; |
500 |
+ case USB_RECIP_ENDPOINT: |
501 |
+ epnum = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK; |
502 |
++ if (epnum >= XUSB_MAX_ENDPOINTS) |
503 |
++ goto stall; |
504 |
+ target_ep = &udc->ep[epnum]; |
505 |
+ epcfgreg = udc->read_fn(udc->addr + target_ep->offset); |
506 |
+ halt = epcfgreg & XUSB_EP_CFG_STALL_MASK; |
507 |
+@@ -1687,6 +1689,10 @@ static void xudc_set_clear_feature(struct xusb_udc *udc) |
508 |
+ case USB_RECIP_ENDPOINT: |
509 |
+ if (!udc->setup.wValue) { |
510 |
+ endpoint = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK; |
511 |
++ if (endpoint >= XUSB_MAX_ENDPOINTS) { |
512 |
++ xudc_ep0_stall(udc); |
513 |
++ return; |
514 |
++ } |
515 |
+ target_ep = &udc->ep[endpoint]; |
516 |
+ outinbit = udc->setup.wIndex & USB_ENDPOINT_DIR_MASK; |
517 |
+ outinbit = outinbit >> 7; |
518 |
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c |
519 |
+index 2df61fff8ae32..a08369cb3462f 100644 |
520 |
+--- a/drivers/usb/host/xhci.c |
521 |
++++ b/drivers/usb/host/xhci.c |
522 |
+@@ -1397,9 +1397,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) |
523 |
+ struct urb_priv *urb_priv; |
524 |
+ int size, i; |
525 |
+ |
526 |
+- if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, |
527 |
+- true, true, __func__) <= 0) |
528 |
++ if (!urb) |
529 |
+ return -EINVAL; |
530 |
++ ret = xhci_check_args(hcd, urb->dev, urb->ep, |
531 |
++ true, true, __func__); |
532 |
++ if (ret <= 0) |
533 |
++ return ret ? ret : -EINVAL; |
534 |
+ |
535 |
+ slot_id = urb->dev->slot_id; |
536 |
+ ep_index = xhci_get_endpoint_index(&urb->ep->desc); |
537 |
+@@ -3031,7 +3034,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, |
538 |
+ return -EINVAL; |
539 |
+ ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); |
540 |
+ if (ret <= 0) |
541 |
+- return -EINVAL; |
542 |
++ return ret ? ret : -EINVAL; |
543 |
+ if (usb_ss_max_streams(&ep->ss_ep_comp) == 0) { |
544 |
+ xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion" |
545 |
+ " descriptor for ep 0x%x does not support streams\n", |
546 |
+diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c |
547 |
+index a8573da2717a1..a2337d15233fc 100644 |
548 |
+--- a/drivers/usb/serial/ch341.c |
549 |
++++ b/drivers/usb/serial/ch341.c |
550 |
+@@ -70,7 +70,6 @@ |
551 |
+ |
552 |
+ |
553 |
+ static const struct usb_device_id id_table[] = { |
554 |
+- { USB_DEVICE(0x1a86, 0x5512) }, |
555 |
+ { USB_DEVICE(0x1a86, 0x5523) }, |
556 |
+ { USB_DEVICE(0x1a86, 0x7522) }, |
557 |
+ { USB_DEVICE(0x1a86, 0x7523) }, |
558 |
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c |
559 |
+index 4c3ff0706554f..c5d0d9e2bff2d 100644 |
560 |
+--- a/drivers/usb/serial/option.c |
561 |
++++ b/drivers/usb/serial/option.c |
562 |
+@@ -201,6 +201,8 @@ static void option_instat_callback(struct urb *urb); |
563 |
+ |
564 |
+ #define DELL_PRODUCT_5821E 0x81d7 |
565 |
+ #define DELL_PRODUCT_5821E_ESIM 0x81e0 |
566 |
++#define DELL_PRODUCT_5829E_ESIM 0x81e4 |
567 |
++#define DELL_PRODUCT_5829E 0x81e6 |
568 |
+ |
569 |
+ #define KYOCERA_VENDOR_ID 0x0c88 |
570 |
+ #define KYOCERA_PRODUCT_KPC650 0x17da |
571 |
+@@ -1058,6 +1060,10 @@ static const struct usb_device_id option_ids[] = { |
572 |
+ .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, |
573 |
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5821E_ESIM), |
574 |
+ .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, |
575 |
++ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E), |
576 |
++ .driver_info = RSVD(0) | RSVD(6) }, |
577 |
++ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM), |
578 |
++ .driver_info = RSVD(0) | RSVD(6) }, |
579 |
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ |
580 |
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
581 |
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, |
582 |
+@@ -1249,10 +1255,16 @@ static const struct usb_device_id option_ids[] = { |
583 |
+ .driver_info = NCTRL(2) }, |
584 |
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff), /* Telit LE910-S1 (ECM) */ |
585 |
+ .driver_info = NCTRL(2) }, |
586 |
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701a, 0xff), /* Telit LE910R1 (RNDIS) */ |
587 |
++ .driver_info = NCTRL(2) }, |
588 |
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701b, 0xff), /* Telit LE910R1 (ECM) */ |
589 |
++ .driver_info = NCTRL(2) }, |
590 |
+ { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ |
591 |
+ .driver_info = NCTRL(0) | ZLP }, |
592 |
+ { USB_DEVICE(TELIT_VENDOR_ID, 0x9200), /* Telit LE910S1 flashing device */ |
593 |
+ .driver_info = NCTRL(0) | ZLP }, |
594 |
++ { USB_DEVICE(TELIT_VENDOR_ID, 0x9201), /* Telit LE910R1 flashing device */ |
595 |
++ .driver_info = NCTRL(0) | ZLP }, |
596 |
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
597 |
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), |
598 |
+ .driver_info = RSVD(1) }, |
599 |
+diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c |
600 |
+index e282e8174a5d9..d054702c8fbe3 100644 |
601 |
+--- a/drivers/vhost/vsock.c |
602 |
++++ b/drivers/vhost/vsock.c |
603 |
+@@ -484,16 +484,18 @@ err: |
604 |
+ return ret; |
605 |
+ } |
606 |
+ |
607 |
+-static int vhost_vsock_stop(struct vhost_vsock *vsock) |
608 |
++static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner) |
609 |
+ { |
610 |
+ size_t i; |
611 |
+- int ret; |
612 |
++ int ret = 0; |
613 |
+ |
614 |
+ mutex_lock(&vsock->dev.mutex); |
615 |
+ |
616 |
+- ret = vhost_dev_check_owner(&vsock->dev); |
617 |
+- if (ret) |
618 |
+- goto err; |
619 |
++ if (check_owner) { |
620 |
++ ret = vhost_dev_check_owner(&vsock->dev); |
621 |
++ if (ret) |
622 |
++ goto err; |
623 |
++ } |
624 |
+ |
625 |
+ for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { |
626 |
+ struct vhost_virtqueue *vq = &vsock->vqs[i]; |
627 |
+@@ -611,7 +613,12 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) |
628 |
+ * inefficient. Room for improvement here. */ |
629 |
+ vsock_for_each_connected_socket(vhost_vsock_reset_orphans); |
630 |
+ |
631 |
+- vhost_vsock_stop(vsock); |
632 |
++ /* Don't check the owner, because we are in the release path, so we |
633 |
++ * need to stop the vsock device in any case. |
634 |
++ * vhost_vsock_stop() can not fail in this case, so we don't need to |
635 |
++ * check the return code. |
636 |
++ */ |
637 |
++ vhost_vsock_stop(vsock, false); |
638 |
+ vhost_vsock_flush(vsock); |
639 |
+ vhost_dev_stop(&vsock->dev); |
640 |
+ |
641 |
+@@ -709,7 +716,7 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl, |
642 |
+ if (start) |
643 |
+ return vhost_vsock_start(vsock); |
644 |
+ else |
645 |
+- return vhost_vsock_stop(vsock); |
646 |
++ return vhost_vsock_stop(vsock, true); |
647 |
+ case VHOST_GET_FEATURES: |
648 |
+ features = VHOST_VSOCK_FEATURES; |
649 |
+ if (copy_to_user(argp, &features, sizeof(features))) |
650 |
+diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c |
651 |
+index c875f246cb0e9..ccb49caed502c 100644 |
652 |
+--- a/fs/configfs/dir.c |
653 |
++++ b/fs/configfs/dir.c |
654 |
+@@ -50,6 +50,14 @@ DECLARE_RWSEM(configfs_rename_sem); |
655 |
+ */ |
656 |
+ DEFINE_SPINLOCK(configfs_dirent_lock); |
657 |
+ |
658 |
++/* |
659 |
++ * All of link_obj/unlink_obj/link_group/unlink_group require that |
660 |
++ * subsys->su_mutex is held. |
661 |
++ * But parent configfs_subsystem is NULL when config_item is root. |
662 |
++ * Use this mutex when config_item is root. |
663 |
++ */ |
664 |
++static DEFINE_MUTEX(configfs_subsystem_mutex); |
665 |
++ |
666 |
+ static void configfs_d_iput(struct dentry * dentry, |
667 |
+ struct inode * inode) |
668 |
+ { |
669 |
+@@ -1937,7 +1945,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) |
670 |
+ group->cg_item.ci_name = group->cg_item.ci_namebuf; |
671 |
+ |
672 |
+ sd = root->d_fsdata; |
673 |
++ mutex_lock(&configfs_subsystem_mutex); |
674 |
+ link_group(to_config_group(sd->s_element), group); |
675 |
++ mutex_unlock(&configfs_subsystem_mutex); |
676 |
+ |
677 |
+ inode_lock_nested(d_inode(root), I_MUTEX_PARENT); |
678 |
+ |
679 |
+@@ -1962,7 +1972,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) |
680 |
+ inode_unlock(d_inode(root)); |
681 |
+ |
682 |
+ if (err) { |
683 |
++ mutex_lock(&configfs_subsystem_mutex); |
684 |
+ unlink_group(group); |
685 |
++ mutex_unlock(&configfs_subsystem_mutex); |
686 |
+ configfs_release_fs(); |
687 |
+ } |
688 |
+ put_fragment(frag); |
689 |
+@@ -2008,7 +2020,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) |
690 |
+ |
691 |
+ dput(dentry); |
692 |
+ |
693 |
++ mutex_lock(&configfs_subsystem_mutex); |
694 |
+ unlink_group(group); |
695 |
++ mutex_unlock(&configfs_subsystem_mutex); |
696 |
+ configfs_release_fs(); |
697 |
+ } |
698 |
+ |
699 |
+diff --git a/fs/file.c b/fs/file.c |
700 |
+index 0e31a66207e86..be0792c0a2313 100644 |
701 |
+--- a/fs/file.c |
702 |
++++ b/fs/file.c |
703 |
+@@ -692,28 +692,69 @@ void do_close_on_exec(struct files_struct *files) |
704 |
+ spin_unlock(&files->file_lock); |
705 |
+ } |
706 |
+ |
707 |
+-static struct file *__fget(unsigned int fd, fmode_t mask, unsigned int refs) |
708 |
++static inline struct file *__fget_files_rcu(struct files_struct *files, |
709 |
++ unsigned int fd, fmode_t mask, unsigned int refs) |
710 |
+ { |
711 |
+- struct files_struct *files = current->files; |
712 |
+- struct file *file; |
713 |
++ for (;;) { |
714 |
++ struct file *file; |
715 |
++ struct fdtable *fdt = rcu_dereference_raw(files->fdt); |
716 |
++ struct file __rcu **fdentry; |
717 |
+ |
718 |
+- rcu_read_lock(); |
719 |
+-loop: |
720 |
+- file = fcheck_files(files, fd); |
721 |
+- if (file) { |
722 |
+- /* File object ref couldn't be taken. |
723 |
+- * dup2() atomicity guarantee is the reason |
724 |
+- * we loop to catch the new file (or NULL pointer) |
725 |
++ if (unlikely(fd >= fdt->max_fds)) |
726 |
++ return NULL; |
727 |
++ |
728 |
++ fdentry = fdt->fd + array_index_nospec(fd, fdt->max_fds); |
729 |
++ file = rcu_dereference_raw(*fdentry); |
730 |
++ if (unlikely(!file)) |
731 |
++ return NULL; |
732 |
++ |
733 |
++ if (unlikely(file->f_mode & mask)) |
734 |
++ return NULL; |
735 |
++ |
736 |
++ /* |
737 |
++ * Ok, we have a file pointer. However, because we do |
738 |
++ * this all locklessly under RCU, we may be racing with |
739 |
++ * that file being closed. |
740 |
++ * |
741 |
++ * Such a race can take two forms: |
742 |
++ * |
743 |
++ * (a) the file ref already went down to zero, |
744 |
++ * and get_file_rcu_many() fails. Just try |
745 |
++ * again: |
746 |
++ */ |
747 |
++ if (unlikely(!get_file_rcu_many(file, refs))) |
748 |
++ continue; |
749 |
++ |
750 |
++ /* |
751 |
++ * (b) the file table entry has changed under us. |
752 |
++ * Note that we don't need to re-check the 'fdt->fd' |
753 |
++ * pointer having changed, because it always goes |
754 |
++ * hand-in-hand with 'fdt'. |
755 |
++ * |
756 |
++ * If so, we need to put our refs and try again. |
757 |
+ */ |
758 |
+- if (file->f_mode & mask) |
759 |
+- file = NULL; |
760 |
+- else if (!get_file_rcu_many(file, refs)) |
761 |
+- goto loop; |
762 |
+- else if (__fcheck_files(files, fd) != file) { |
763 |
++ if (unlikely(rcu_dereference_raw(files->fdt) != fdt) || |
764 |
++ unlikely(rcu_dereference_raw(*fdentry) != file)) { |
765 |
+ fput_many(file, refs); |
766 |
+- goto loop; |
767 |
++ continue; |
768 |
+ } |
769 |
++ |
770 |
++ /* |
771 |
++ * Ok, we have a ref to the file, and checked that it |
772 |
++ * still exists. |
773 |
++ */ |
774 |
++ return file; |
775 |
+ } |
776 |
++} |
777 |
++ |
778 |
++ |
779 |
++static struct file *__fget(unsigned int fd, fmode_t mask, unsigned int refs) |
780 |
++{ |
781 |
++ struct files_struct *files = current->files; |
782 |
++ struct file *file; |
783 |
++ |
784 |
++ rcu_read_lock(); |
785 |
++ file = __fget_files_rcu(files, fd, mask, refs); |
786 |
+ rcu_read_unlock(); |
787 |
+ |
788 |
+ return file; |
789 |
+diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c |
790 |
+index e00594ad99724..b56d1cfe429e9 100644 |
791 |
+--- a/fs/tracefs/inode.c |
792 |
++++ b/fs/tracefs/inode.c |
793 |
+@@ -265,7 +265,6 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) |
794 |
+ if (!gid_valid(gid)) |
795 |
+ return -EINVAL; |
796 |
+ opts->gid = gid; |
797 |
+- set_gid(tracefs_mount->mnt_root, gid); |
798 |
+ break; |
799 |
+ case Opt_mode: |
800 |
+ if (match_octal(&args[0], &option)) |
801 |
+@@ -292,7 +291,9 @@ static int tracefs_apply_options(struct super_block *sb) |
802 |
+ inode->i_mode |= opts->mode; |
803 |
+ |
804 |
+ inode->i_uid = opts->uid; |
805 |
+- inode->i_gid = opts->gid; |
806 |
++ |
807 |
++ /* Set all the group ids to the mount option */ |
808 |
++ set_gid(sb->s_root, opts->gid); |
809 |
+ |
810 |
+ return 0; |
811 |
+ } |
812 |
+diff --git a/include/net/checksum.h b/include/net/checksum.h |
813 |
+index 5c30891e84e51..5c59b6386dff2 100644 |
814 |
+--- a/include/net/checksum.h |
815 |
++++ b/include/net/checksum.h |
816 |
+@@ -143,6 +143,11 @@ static inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new) |
817 |
+ *sum = ~csum16_add(csum16_sub(~(*sum), old), new); |
818 |
+ } |
819 |
+ |
820 |
++static inline void csum_replace(__wsum *csum, __wsum old, __wsum new) |
821 |
++{ |
822 |
++ *csum = csum_add(csum_sub(*csum, old), new); |
823 |
++} |
824 |
++ |
825 |
+ struct sk_buff; |
826 |
+ void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, |
827 |
+ __be32 from, __be32 to, bool pseudohdr); |
828 |
+diff --git a/mm/memblock.c b/mm/memblock.c |
829 |
+index e43065b13c08c..9f4e78dd2aa1b 100644 |
830 |
+--- a/mm/memblock.c |
831 |
++++ b/mm/memblock.c |
832 |
+@@ -272,14 +272,20 @@ void __init memblock_discard(void) |
833 |
+ addr = __pa(memblock.reserved.regions); |
834 |
+ size = PAGE_ALIGN(sizeof(struct memblock_region) * |
835 |
+ memblock.reserved.max); |
836 |
+- __memblock_free_late(addr, size); |
837 |
++ if (memblock_reserved_in_slab) |
838 |
++ kfree(memblock.reserved.regions); |
839 |
++ else |
840 |
++ __memblock_free_late(addr, size); |
841 |
+ } |
842 |
+ |
843 |
+ if (memblock.memory.regions != memblock_memory_init_regions) { |
844 |
+ addr = __pa(memblock.memory.regions); |
845 |
+ size = PAGE_ALIGN(sizeof(struct memblock_region) * |
846 |
+ memblock.memory.max); |
847 |
+- __memblock_free_late(addr, size); |
848 |
++ if (memblock_memory_in_slab) |
849 |
++ kfree(memblock.memory.regions); |
850 |
++ else |
851 |
++ __memblock_free_late(addr, size); |
852 |
+ } |
853 |
+ } |
854 |
+ #endif |
855 |
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c |
856 |
+index 0e34f5ad62162..41d328a93790f 100644 |
857 |
+--- a/net/core/skbuff.c |
858 |
++++ b/net/core/skbuff.c |
859 |
+@@ -1716,7 +1716,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) |
860 |
+ /* Free pulled out fragments. */ |
861 |
+ while ((list = skb_shinfo(skb)->frag_list) != insp) { |
862 |
+ skb_shinfo(skb)->frag_list = list->next; |
863 |
+- kfree_skb(list); |
864 |
++ consume_skb(list); |
865 |
+ } |
866 |
+ /* And insert new clone at head. */ |
867 |
+ if (clone) { |
868 |
+@@ -4951,7 +4951,7 @@ static int pskb_carve_frag_list(struct sk_buff *skb, |
869 |
+ /* Free pulled out fragments. */ |
870 |
+ while ((list = shinfo->frag_list) != insp) { |
871 |
+ shinfo->frag_list = list->next; |
872 |
+- kfree_skb(list); |
873 |
++ consume_skb(list); |
874 |
+ } |
875 |
+ /* And insert new clone at head. */ |
876 |
+ if (clone) { |
877 |
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c |
878 |
+index a8563745980b4..8f2fb14fd4f71 100644 |
879 |
+--- a/net/ipv4/af_inet.c |
880 |
++++ b/net/ipv4/af_inet.c |
881 |
+@@ -1238,8 +1238,11 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb, |
882 |
+ } |
883 |
+ |
884 |
+ ops = rcu_dereference(inet_offloads[proto]); |
885 |
+- if (likely(ops && ops->callbacks.gso_segment)) |
886 |
++ if (likely(ops && ops->callbacks.gso_segment)) { |
887 |
+ segs = ops->callbacks.gso_segment(skb, features); |
888 |
++ if (!segs) |
889 |
++ skb->network_header = skb_mac_header(skb) + nhoff - skb->head; |
890 |
++ } |
891 |
+ |
892 |
+ if (IS_ERR_OR_NULL(segs)) |
893 |
+ goto out; |
894 |
+diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c |
895 |
+index a36ae90bf6132..87763302bce2c 100644 |
896 |
+--- a/net/ipv6/ip6_offload.c |
897 |
++++ b/net/ipv6/ip6_offload.c |
898 |
+@@ -96,6 +96,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, |
899 |
+ if (likely(ops && ops->callbacks.gso_segment)) { |
900 |
+ skb_reset_transport_header(skb); |
901 |
+ segs = ops->callbacks.gso_segment(skb, features); |
902 |
++ if (!segs) |
903 |
++ skb->network_header = skb_mac_header(skb) + nhoff - skb->head; |
904 |
+ } |
905 |
+ |
906 |
+ if (IS_ERR_OR_NULL(segs)) |
907 |
+diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c |
908 |
+index 5fa7b2569a3ab..4d9b9d959fafb 100644 |
909 |
+--- a/net/openvswitch/actions.c |
910 |
++++ b/net/openvswitch/actions.c |
911 |
+@@ -391,12 +391,43 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto, |
912 |
+ memcpy(addr, new_addr, sizeof(__be32[4])); |
913 |
+ } |
914 |
+ |
915 |
+-static void set_ipv6_fl(struct ipv6hdr *nh, u32 fl, u32 mask) |
916 |
++static void set_ipv6_dsfield(struct sk_buff *skb, struct ipv6hdr *nh, u8 ipv6_tclass, u8 mask) |
917 |
+ { |
918 |
++ u8 old_ipv6_tclass = ipv6_get_dsfield(nh); |
919 |
++ |
920 |
++ ipv6_tclass = OVS_MASKED(old_ipv6_tclass, ipv6_tclass, mask); |
921 |
++ |
922 |
++ if (skb->ip_summed == CHECKSUM_COMPLETE) |
923 |
++ csum_replace(&skb->csum, (__force __wsum)(old_ipv6_tclass << 12), |
924 |
++ (__force __wsum)(ipv6_tclass << 12)); |
925 |
++ |
926 |
++ ipv6_change_dsfield(nh, ~mask, ipv6_tclass); |
927 |
++} |
928 |
++ |
929 |
++static void set_ipv6_fl(struct sk_buff *skb, struct ipv6hdr *nh, u32 fl, u32 mask) |
930 |
++{ |
931 |
++ u32 ofl; |
932 |
++ |
933 |
++ ofl = nh->flow_lbl[0] << 16 | nh->flow_lbl[1] << 8 | nh->flow_lbl[2]; |
934 |
++ fl = OVS_MASKED(ofl, fl, mask); |
935 |
++ |
936 |
+ /* Bits 21-24 are always unmasked, so this retains their values. */ |
937 |
+- OVS_SET_MASKED(nh->flow_lbl[0], (u8)(fl >> 16), (u8)(mask >> 16)); |
938 |
+- OVS_SET_MASKED(nh->flow_lbl[1], (u8)(fl >> 8), (u8)(mask >> 8)); |
939 |
+- OVS_SET_MASKED(nh->flow_lbl[2], (u8)fl, (u8)mask); |
940 |
++ nh->flow_lbl[0] = (u8)(fl >> 16); |
941 |
++ nh->flow_lbl[1] = (u8)(fl >> 8); |
942 |
++ nh->flow_lbl[2] = (u8)fl; |
943 |
++ |
944 |
++ if (skb->ip_summed == CHECKSUM_COMPLETE) |
945 |
++ csum_replace(&skb->csum, (__force __wsum)htonl(ofl), (__force __wsum)htonl(fl)); |
946 |
++} |
947 |
++ |
948 |
++static void set_ipv6_ttl(struct sk_buff *skb, struct ipv6hdr *nh, u8 new_ttl, u8 mask) |
949 |
++{ |
950 |
++ new_ttl = OVS_MASKED(nh->hop_limit, new_ttl, mask); |
951 |
++ |
952 |
++ if (skb->ip_summed == CHECKSUM_COMPLETE) |
953 |
++ csum_replace(&skb->csum, (__force __wsum)(nh->hop_limit << 8), |
954 |
++ (__force __wsum)(new_ttl << 8)); |
955 |
++ nh->hop_limit = new_ttl; |
956 |
+ } |
957 |
+ |
958 |
+ static void set_ip_ttl(struct sk_buff *skb, struct iphdr *nh, u8 new_ttl, |
959 |
+@@ -514,18 +545,17 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, |
960 |
+ } |
961 |
+ } |
962 |
+ if (mask->ipv6_tclass) { |
963 |
+- ipv6_change_dsfield(nh, ~mask->ipv6_tclass, key->ipv6_tclass); |
964 |
++ set_ipv6_dsfield(skb, nh, key->ipv6_tclass, mask->ipv6_tclass); |
965 |
+ flow_key->ip.tos = ipv6_get_dsfield(nh); |
966 |
+ } |
967 |
+ if (mask->ipv6_label) { |
968 |
+- set_ipv6_fl(nh, ntohl(key->ipv6_label), |
969 |
++ set_ipv6_fl(skb, nh, ntohl(key->ipv6_label), |
970 |
+ ntohl(mask->ipv6_label)); |
971 |
+ flow_key->ipv6.label = |
972 |
+ *(__be32 *)nh & htonl(IPV6_FLOWINFO_FLOWLABEL); |
973 |
+ } |
974 |
+ if (mask->ipv6_hlimit) { |
975 |
+- OVS_SET_MASKED(nh->hop_limit, key->ipv6_hlimit, |
976 |
+- mask->ipv6_hlimit); |
977 |
++ set_ipv6_ttl(skb, nh, key->ipv6_hlimit, mask->ipv6_hlimit); |
978 |
+ flow_key->ip.ttl = nh->hop_limit; |
979 |
+ } |
980 |
+ return 0; |