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