Contents of /trunk/kernel-alx/patches-5.4/0276-5.4.177-all-fixes.patch
Parent Directory | Revision Log
Revision 3635 -
(show annotations)
(download)
Mon Oct 24 12:34:12 2022 UTC (23 months ago) by niro
File size: 15062 byte(s)
Mon Oct 24 12:34:12 2022 UTC (23 months ago) by niro
File size: 15062 byte(s)
-sync kernel patches
1 | diff --git a/Documentation/accounting/psi.rst b/Documentation/accounting/psi.rst |
2 | index 621111ce57401..28c0461ba2e1b 100644 |
3 | --- a/Documentation/accounting/psi.rst |
4 | +++ b/Documentation/accounting/psi.rst |
5 | @@ -90,7 +90,8 @@ Triggers can be set on more than one psi metric and more than one trigger |
6 | for the same psi metric can be specified. However for each trigger a separate |
7 | file descriptor is required to be able to poll it separately from others, |
8 | therefore for each trigger a separate open() syscall should be made even |
9 | -when opening the same psi interface file. |
10 | +when opening the same psi interface file. Write operations to a file descriptor |
11 | +with an already existing psi trigger will fail with EBUSY. |
12 | |
13 | Monitors activate only when system enters stall state for the monitored |
14 | psi metric and deactivates upon exit from the stall state. While system is |
15 | diff --git a/Makefile b/Makefile |
16 | index b23aa51ada93e..324939b64d7b7 100644 |
17 | --- a/Makefile |
18 | +++ b/Makefile |
19 | @@ -1,7 +1,7 @@ |
20 | # SPDX-License-Identifier: GPL-2.0 |
21 | VERSION = 5 |
22 | PATCHLEVEL = 4 |
23 | -SUBLEVEL = 176 |
24 | +SUBLEVEL = 177 |
25 | EXTRAVERSION = |
26 | NAME = Kleptomaniac Octopus |
27 | |
28 | diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c |
29 | index da8c2c4aca7ef..0442d7e1cd20b 100644 |
30 | --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c |
31 | +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c |
32 | @@ -721,7 +721,9 @@ static void xgbe_stop_timers(struct xgbe_prv_data *pdata) |
33 | if (!channel->tx_ring) |
34 | break; |
35 | |
36 | + /* Deactivate the Tx timer */ |
37 | del_timer_sync(&channel->tx_timer); |
38 | + channel->tx_timer_active = 0; |
39 | } |
40 | } |
41 | |
42 | @@ -2765,6 +2767,14 @@ read_again: |
43 | buf2_len = xgbe_rx_buf2_len(rdata, packet, len); |
44 | len += buf2_len; |
45 | |
46 | + if (buf2_len > rdata->rx.buf.dma_len) { |
47 | + /* Hardware inconsistency within the descriptors |
48 | + * that has resulted in a length underflow. |
49 | + */ |
50 | + error = 1; |
51 | + goto skip_data; |
52 | + } |
53 | + |
54 | if (!skb) { |
55 | skb = xgbe_create_skb(pdata, napi, rdata, |
56 | buf1_len); |
57 | @@ -2794,8 +2804,10 @@ skip_data: |
58 | if (!last || context_next) |
59 | goto read_again; |
60 | |
61 | - if (!skb) |
62 | + if (!skb || error) { |
63 | + dev_kfree_skb(skb); |
64 | goto next_packet; |
65 | + } |
66 | |
67 | /* Be sure we don't exceed the configured MTU */ |
68 | max_len = netdev->mtu + ETH_HLEN; |
69 | diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c |
70 | index 345576f1a7470..73ad78f47763c 100644 |
71 | --- a/drivers/net/usb/ipheth.c |
72 | +++ b/drivers/net/usb/ipheth.c |
73 | @@ -121,7 +121,7 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone) |
74 | if (tx_buf == NULL) |
75 | goto free_rx_urb; |
76 | |
77 | - rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE, |
78 | + rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, |
79 | GFP_KERNEL, &rx_urb->transfer_dma); |
80 | if (rx_buf == NULL) |
81 | goto free_tx_buf; |
82 | @@ -146,7 +146,7 @@ error_nomem: |
83 | |
84 | static void ipheth_free_urbs(struct ipheth_device *iphone) |
85 | { |
86 | - usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf, |
87 | + usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf, |
88 | iphone->rx_urb->transfer_dma); |
89 | usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, |
90 | iphone->tx_urb->transfer_dma); |
91 | @@ -317,7 +317,7 @@ static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) |
92 | |
93 | usb_fill_bulk_urb(dev->rx_urb, udev, |
94 | usb_rcvbulkpipe(udev, dev->bulk_in), |
95 | - dev->rx_buf, IPHETH_BUF_SIZE, |
96 | + dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, |
97 | ipheth_rcvbulk_callback, |
98 | dev); |
99 | dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
100 | diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c |
101 | index 88b996764ff95..907b8be86ce04 100644 |
102 | --- a/drivers/pci/hotplug/pciehp_hpc.c |
103 | +++ b/drivers/pci/hotplug/pciehp_hpc.c |
104 | @@ -577,6 +577,8 @@ read_status: |
105 | */ |
106 | if (ctrl->power_fault_detected) |
107 | status &= ~PCI_EXP_SLTSTA_PFD; |
108 | + else if (status & PCI_EXP_SLTSTA_PFD) |
109 | + ctrl->power_fault_detected = true; |
110 | |
111 | events |= status; |
112 | if (!events) { |
113 | @@ -586,7 +588,7 @@ read_status: |
114 | } |
115 | |
116 | if (status) { |
117 | - pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events); |
118 | + pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, status); |
119 | |
120 | /* |
121 | * In MSI mode, all event bits must be zero before the port |
122 | @@ -660,8 +662,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) |
123 | } |
124 | |
125 | /* Check Power Fault Detected */ |
126 | - if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { |
127 | - ctrl->power_fault_detected = 1; |
128 | + if (events & PCI_EXP_SLTSTA_PFD) { |
129 | ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl)); |
130 | pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, |
131 | PCI_EXP_SLTCTL_ATTN_IND_ON); |
132 | diff --git a/include/linux/psi.h b/include/linux/psi.h |
133 | index 7b3de73212199..7712b58009276 100644 |
134 | --- a/include/linux/psi.h |
135 | +++ b/include/linux/psi.h |
136 | @@ -31,7 +31,7 @@ void cgroup_move_task(struct task_struct *p, struct css_set *to); |
137 | |
138 | struct psi_trigger *psi_trigger_create(struct psi_group *group, |
139 | char *buf, size_t nbytes, enum psi_res res); |
140 | -void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *t); |
141 | +void psi_trigger_destroy(struct psi_trigger *t); |
142 | |
143 | __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file, |
144 | poll_table *wait); |
145 | diff --git a/include/linux/psi_types.h b/include/linux/psi_types.h |
146 | index 07aaf9b822416..0023052eab23f 100644 |
147 | --- a/include/linux/psi_types.h |
148 | +++ b/include/linux/psi_types.h |
149 | @@ -120,9 +120,6 @@ struct psi_trigger { |
150 | * events to one per window |
151 | */ |
152 | u64 last_event_time; |
153 | - |
154 | - /* Refcounting to prevent premature destruction */ |
155 | - struct kref refcount; |
156 | }; |
157 | |
158 | struct psi_group { |
159 | diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c |
160 | index 2d0ef613ca070..5e465c4b1e64c 100644 |
161 | --- a/kernel/cgroup/cgroup-v1.c |
162 | +++ b/kernel/cgroup/cgroup-v1.c |
163 | @@ -549,6 +549,14 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, |
164 | |
165 | BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); |
166 | |
167 | + /* |
168 | + * Release agent gets called with all capabilities, |
169 | + * require capabilities to set release agent. |
170 | + */ |
171 | + if ((of->file->f_cred->user_ns != &init_user_ns) || |
172 | + !capable(CAP_SYS_ADMIN)) |
173 | + return -EPERM; |
174 | + |
175 | cgrp = cgroup_kn_lock_live(of->kn, false); |
176 | if (!cgrp) |
177 | return -ENODEV; |
178 | @@ -961,6 +969,12 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) |
179 | /* Specifying two release agents is forbidden */ |
180 | if (ctx->release_agent) |
181 | return cg_invalf(fc, "cgroup1: release_agent respecified"); |
182 | + /* |
183 | + * Release agent gets called with all capabilities, |
184 | + * require capabilities to set release agent. |
185 | + */ |
186 | + if ((fc->user_ns != &init_user_ns) || !capable(CAP_SYS_ADMIN)) |
187 | + return cg_invalf(fc, "cgroup1: Setting release_agent not allowed"); |
188 | ctx->release_agent = param->string; |
189 | param->string = NULL; |
190 | break; |
191 | diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c |
192 | index 1904ffcee0f1e..ce1745ac7b8c0 100644 |
193 | --- a/kernel/cgroup/cgroup.c |
194 | +++ b/kernel/cgroup/cgroup.c |
195 | @@ -3659,6 +3659,12 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, |
196 | cgroup_get(cgrp); |
197 | cgroup_kn_unlock(of->kn); |
198 | |
199 | + /* Allow only one trigger per file descriptor */ |
200 | + if (of->priv) { |
201 | + cgroup_put(cgrp); |
202 | + return -EBUSY; |
203 | + } |
204 | + |
205 | psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi; |
206 | new = psi_trigger_create(psi, buf, nbytes, res); |
207 | if (IS_ERR(new)) { |
208 | @@ -3666,8 +3672,7 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, |
209 | return PTR_ERR(new); |
210 | } |
211 | |
212 | - psi_trigger_replace(&of->priv, new); |
213 | - |
214 | + smp_store_release(&of->priv, new); |
215 | cgroup_put(cgrp); |
216 | |
217 | return nbytes; |
218 | @@ -3702,7 +3707,7 @@ static __poll_t cgroup_pressure_poll(struct kernfs_open_file *of, |
219 | |
220 | static void cgroup_pressure_release(struct kernfs_open_file *of) |
221 | { |
222 | - psi_trigger_replace(&of->priv, NULL); |
223 | + psi_trigger_destroy(of->priv); |
224 | } |
225 | #endif /* CONFIG_PSI */ |
226 | |
227 | diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c |
228 | index badfa8f153599..411be8b2e837e 100644 |
229 | --- a/kernel/cgroup/cpuset.c |
230 | +++ b/kernel/cgroup/cpuset.c |
231 | @@ -1558,8 +1558,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, |
232 | * Make sure that subparts_cpus is a subset of cpus_allowed. |
233 | */ |
234 | if (cs->nr_subparts_cpus) { |
235 | - cpumask_andnot(cs->subparts_cpus, cs->subparts_cpus, |
236 | - cs->cpus_allowed); |
237 | + cpumask_and(cs->subparts_cpus, cs->subparts_cpus, cs->cpus_allowed); |
238 | cs->nr_subparts_cpus = cpumask_weight(cs->subparts_cpus); |
239 | } |
240 | spin_unlock_irq(&callback_lock); |
241 | diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c |
242 | index 9154e745f0978..9dd83eb74a9da 100644 |
243 | --- a/kernel/sched/psi.c |
244 | +++ b/kernel/sched/psi.c |
245 | @@ -1046,7 +1046,6 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, |
246 | t->event = 0; |
247 | t->last_event_time = 0; |
248 | init_waitqueue_head(&t->event_wait); |
249 | - kref_init(&t->refcount); |
250 | |
251 | mutex_lock(&group->trigger_lock); |
252 | |
253 | @@ -1079,15 +1078,19 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, |
254 | return t; |
255 | } |
256 | |
257 | -static void psi_trigger_destroy(struct kref *ref) |
258 | +void psi_trigger_destroy(struct psi_trigger *t) |
259 | { |
260 | - struct psi_trigger *t = container_of(ref, struct psi_trigger, refcount); |
261 | - struct psi_group *group = t->group; |
262 | + struct psi_group *group; |
263 | struct kthread_worker *kworker_to_destroy = NULL; |
264 | |
265 | - if (static_branch_likely(&psi_disabled)) |
266 | + /* |
267 | + * We do not check psi_disabled since it might have been disabled after |
268 | + * the trigger got created. |
269 | + */ |
270 | + if (!t) |
271 | return; |
272 | |
273 | + group = t->group; |
274 | /* |
275 | * Wakeup waiters to stop polling. Can happen if cgroup is deleted |
276 | * from under a polling process. |
277 | @@ -1122,9 +1125,9 @@ static void psi_trigger_destroy(struct kref *ref) |
278 | mutex_unlock(&group->trigger_lock); |
279 | |
280 | /* |
281 | - * Wait for both *trigger_ptr from psi_trigger_replace and |
282 | - * poll_kworker RCUs to complete their read-side critical sections |
283 | - * before destroying the trigger and optionally the poll_kworker |
284 | + * Wait for psi_schedule_poll_work RCU to complete its read-side |
285 | + * critical section before destroying the trigger and optionally the |
286 | + * poll_task. |
287 | */ |
288 | synchronize_rcu(); |
289 | /* |
290 | @@ -1146,18 +1149,6 @@ static void psi_trigger_destroy(struct kref *ref) |
291 | kfree(t); |
292 | } |
293 | |
294 | -void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *new) |
295 | -{ |
296 | - struct psi_trigger *old = *trigger_ptr; |
297 | - |
298 | - if (static_branch_likely(&psi_disabled)) |
299 | - return; |
300 | - |
301 | - rcu_assign_pointer(*trigger_ptr, new); |
302 | - if (old) |
303 | - kref_put(&old->refcount, psi_trigger_destroy); |
304 | -} |
305 | - |
306 | __poll_t psi_trigger_poll(void **trigger_ptr, |
307 | struct file *file, poll_table *wait) |
308 | { |
309 | @@ -1167,24 +1158,15 @@ __poll_t psi_trigger_poll(void **trigger_ptr, |
310 | if (static_branch_likely(&psi_disabled)) |
311 | return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; |
312 | |
313 | - rcu_read_lock(); |
314 | - |
315 | - t = rcu_dereference(*(void __rcu __force **)trigger_ptr); |
316 | - if (!t) { |
317 | - rcu_read_unlock(); |
318 | + t = smp_load_acquire(trigger_ptr); |
319 | + if (!t) |
320 | return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; |
321 | - } |
322 | - kref_get(&t->refcount); |
323 | - |
324 | - rcu_read_unlock(); |
325 | |
326 | poll_wait(file, &t->event_wait, wait); |
327 | |
328 | if (cmpxchg(&t->event, 1, 0) == 1) |
329 | ret |= EPOLLPRI; |
330 | |
331 | - kref_put(&t->refcount, psi_trigger_destroy); |
332 | - |
333 | return ret; |
334 | } |
335 | |
336 | @@ -1208,14 +1190,24 @@ static ssize_t psi_write(struct file *file, const char __user *user_buf, |
337 | |
338 | buf[buf_size - 1] = '\0'; |
339 | |
340 | - new = psi_trigger_create(&psi_system, buf, nbytes, res); |
341 | - if (IS_ERR(new)) |
342 | - return PTR_ERR(new); |
343 | - |
344 | seq = file->private_data; |
345 | + |
346 | /* Take seq->lock to protect seq->private from concurrent writes */ |
347 | mutex_lock(&seq->lock); |
348 | - psi_trigger_replace(&seq->private, new); |
349 | + |
350 | + /* Allow only one trigger per file descriptor */ |
351 | + if (seq->private) { |
352 | + mutex_unlock(&seq->lock); |
353 | + return -EBUSY; |
354 | + } |
355 | + |
356 | + new = psi_trigger_create(&psi_system, buf, nbytes, res); |
357 | + if (IS_ERR(new)) { |
358 | + mutex_unlock(&seq->lock); |
359 | + return PTR_ERR(new); |
360 | + } |
361 | + |
362 | + smp_store_release(&seq->private, new); |
363 | mutex_unlock(&seq->lock); |
364 | |
365 | return nbytes; |
366 | @@ -1250,7 +1242,7 @@ static int psi_fop_release(struct inode *inode, struct file *file) |
367 | { |
368 | struct seq_file *seq = file->private_data; |
369 | |
370 | - psi_trigger_replace(&seq->private, NULL); |
371 | + psi_trigger_destroy(seq->private); |
372 | return single_release(inode, file); |
373 | } |
374 | |
375 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
376 | index 55c0f32b9375b..dbc9b2f53649d 100644 |
377 | --- a/net/core/rtnetlink.c |
378 | +++ b/net/core/rtnetlink.c |
379 | @@ -3022,8 +3022,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, |
380 | struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1]; |
381 | unsigned char name_assign_type = NET_NAME_USER; |
382 | struct nlattr *linkinfo[IFLA_INFO_MAX + 1]; |
383 | - const struct rtnl_link_ops *m_ops = NULL; |
384 | - struct net_device *master_dev = NULL; |
385 | + const struct rtnl_link_ops *m_ops; |
386 | + struct net_device *master_dev; |
387 | struct net *net = sock_net(skb->sk); |
388 | const struct rtnl_link_ops *ops; |
389 | struct nlattr *tb[IFLA_MAX + 1]; |
390 | @@ -3063,6 +3063,8 @@ replay: |
391 | dev = NULL; |
392 | } |
393 | |
394 | + master_dev = NULL; |
395 | + m_ops = NULL; |
396 | if (dev) { |
397 | master_dev = netdev_master_upper_dev_get(dev); |
398 | if (master_dev) |
399 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
400 | index 839e1caa57a59..ed11013d4b953 100644 |
401 | --- a/net/packet/af_packet.c |
402 | +++ b/net/packet/af_packet.c |
403 | @@ -1729,7 +1729,10 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) |
404 | err = -ENOSPC; |
405 | if (refcount_read(&match->sk_ref) < PACKET_FANOUT_MAX) { |
406 | __dev_remove_pack(&po->prot_hook); |
407 | - po->fanout = match; |
408 | + |
409 | + /* Paired with packet_setsockopt(PACKET_FANOUT_DATA) */ |
410 | + WRITE_ONCE(po->fanout, match); |
411 | + |
412 | po->rollover = rollover; |
413 | rollover = NULL; |
414 | refcount_set(&match->sk_ref, refcount_read(&match->sk_ref) + 1); |
415 | @@ -3876,7 +3879,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv |
416 | } |
417 | case PACKET_FANOUT_DATA: |
418 | { |
419 | - if (!po->fanout) |
420 | + /* Paired with the WRITE_ONCE() in fanout_add() */ |
421 | + if (!READ_ONCE(po->fanout)) |
422 | return -EINVAL; |
423 | |
424 | return fanout_set_data(po, optval, optlen); |
425 | diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c |
426 | index a4c61205462ac..80205b138d113 100644 |
427 | --- a/net/sched/cls_api.c |
428 | +++ b/net/sched/cls_api.c |
429 | @@ -1928,9 +1928,9 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, |
430 | bool prio_allocate; |
431 | u32 parent; |
432 | u32 chain_index; |
433 | - struct Qdisc *q = NULL; |
434 | + struct Qdisc *q; |
435 | struct tcf_chain_info chain_info; |
436 | - struct tcf_chain *chain = NULL; |
437 | + struct tcf_chain *chain; |
438 | struct tcf_block *block; |
439 | struct tcf_proto *tp; |
440 | unsigned long cl; |
441 | @@ -1958,6 +1958,8 @@ replay: |
442 | tp = NULL; |
443 | cl = 0; |
444 | block = NULL; |
445 | + q = NULL; |
446 | + chain = NULL; |
447 | |
448 | if (prio == 0) { |
449 | /* If no priority is provided by the user, |
450 | @@ -2764,8 +2766,8 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n, |
451 | struct tcmsg *t; |
452 | u32 parent; |
453 | u32 chain_index; |
454 | - struct Qdisc *q = NULL; |
455 | - struct tcf_chain *chain = NULL; |
456 | + struct Qdisc *q; |
457 | + struct tcf_chain *chain; |
458 | struct tcf_block *block; |
459 | unsigned long cl; |
460 | int err; |
461 | @@ -2775,6 +2777,7 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n, |
462 | return -EPERM; |
463 | |
464 | replay: |
465 | + q = NULL; |
466 | err = nlmsg_parse_deprecated(n, sizeof(*t), tca, TCA_MAX, |
467 | rtm_tca_policy, extack); |
468 | if (err < 0) |