1 |
commit: ffcf9f68f9a2e99641b96e1629e477e770e99f48 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Nov 21 20:42:40 2021 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Nov 21 20:42:40 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=ffcf9f68 |
7 |
|
8 |
Linux patch 5.10.81 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1080_linux-5.10.81.patch | 1173 ++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 1177 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 22873d23..f4fa5656 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -363,6 +363,10 @@ Patch: 1079_linux-5.10.80.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 5.10.80 |
23 |
|
24 |
+Patch: 1080_linux-5.10.81.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.10.81 |
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/1080_linux-5.10.81.patch b/1080_linux-5.10.81.patch |
33 |
new file mode 100644 |
34 |
index 00000000..0a03b38e |
35 |
--- /dev/null |
36 |
+++ b/1080_linux-5.10.81.patch |
37 |
@@ -0,0 +1,1173 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index 71fdc74801e0a..1baeadb574f1c 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,7 +1,7 @@ |
43 |
+ # SPDX-License-Identifier: GPL-2.0 |
44 |
+ VERSION = 5 |
45 |
+ PATCHLEVEL = 10 |
46 |
+-SUBLEVEL = 80 |
47 |
++SUBLEVEL = 81 |
48 |
+ EXTRAVERSION = |
49 |
+ NAME = Dare mighty things |
50 |
+ |
51 |
+diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S |
52 |
+index 9c76d50a5654b..3da39140babcf 100644 |
53 |
+--- a/arch/parisc/kernel/entry.S |
54 |
++++ b/arch/parisc/kernel/entry.S |
55 |
+@@ -1849,7 +1849,7 @@ syscall_restore: |
56 |
+ |
57 |
+ /* Are we being ptraced? */ |
58 |
+ LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 |
59 |
+- ldi _TIF_SYSCALL_TRACE_MASK,%r2 |
60 |
++ ldi _TIF_SINGLESTEP|_TIF_BLOCKSTEP,%r2 |
61 |
+ and,COND(=) %r19,%r2,%r0 |
62 |
+ b,n syscall_restore_rfi |
63 |
+ |
64 |
+diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h |
65 |
+index 98b4dae5e8bc8..c1438f9239e46 100644 |
66 |
+--- a/arch/x86/include/asm/insn-eval.h |
67 |
++++ b/arch/x86/include/asm/insn-eval.h |
68 |
+@@ -21,6 +21,7 @@ int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); |
69 |
+ int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs); |
70 |
+ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); |
71 |
+ int insn_get_code_seg_params(struct pt_regs *regs); |
72 |
++unsigned long insn_get_effective_ip(struct pt_regs *regs); |
73 |
+ int insn_fetch_from_user(struct pt_regs *regs, |
74 |
+ unsigned char buf[MAX_INSN_SIZE]); |
75 |
+ int insn_fetch_from_user_inatomic(struct pt_regs *regs, |
76 |
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h |
77 |
+index 50d02db723177..d428d611a43a9 100644 |
78 |
+--- a/arch/x86/include/asm/processor.h |
79 |
++++ b/arch/x86/include/asm/processor.h |
80 |
+@@ -534,6 +534,7 @@ struct thread_struct { |
81 |
+ */ |
82 |
+ unsigned long iopl_emul; |
83 |
+ |
84 |
++ unsigned int iopl_warn:1; |
85 |
+ unsigned int sig_on_uaccess_err:1; |
86 |
+ |
87 |
+ /* Floating point and extended processor state */ |
88 |
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c |
89 |
+index 145a7ac0c19aa..0aa1baf9a3afc 100644 |
90 |
+--- a/arch/x86/kernel/process.c |
91 |
++++ b/arch/x86/kernel/process.c |
92 |
+@@ -138,6 +138,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, |
93 |
+ frame->ret_addr = (unsigned long) ret_from_fork; |
94 |
+ p->thread.sp = (unsigned long) fork_frame; |
95 |
+ p->thread.io_bitmap = NULL; |
96 |
++ p->thread.iopl_warn = 0; |
97 |
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); |
98 |
+ |
99 |
+ #ifdef CONFIG_X86_64 |
100 |
+diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c |
101 |
+index 143fcb8af38f4..2d4ecd50e69b8 100644 |
102 |
+--- a/arch/x86/kernel/traps.c |
103 |
++++ b/arch/x86/kernel/traps.c |
104 |
+@@ -523,6 +523,37 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs, |
105 |
+ |
106 |
+ #define GPFSTR "general protection fault" |
107 |
+ |
108 |
++static bool fixup_iopl_exception(struct pt_regs *regs) |
109 |
++{ |
110 |
++ struct thread_struct *t = ¤t->thread; |
111 |
++ unsigned char byte; |
112 |
++ unsigned long ip; |
113 |
++ |
114 |
++ if (!IS_ENABLED(CONFIG_X86_IOPL_IOPERM) || t->iopl_emul != 3) |
115 |
++ return false; |
116 |
++ |
117 |
++ ip = insn_get_effective_ip(regs); |
118 |
++ if (!ip) |
119 |
++ return false; |
120 |
++ |
121 |
++ if (get_user(byte, (const char __user *)ip)) |
122 |
++ return false; |
123 |
++ |
124 |
++ if (byte != 0xfa && byte != 0xfb) |
125 |
++ return false; |
126 |
++ |
127 |
++ if (!t->iopl_warn && printk_ratelimit()) { |
128 |
++ pr_err("%s[%d] attempts to use CLI/STI, pretending it's a NOP, ip:%lx", |
129 |
++ current->comm, task_pid_nr(current), ip); |
130 |
++ print_vma_addr(KERN_CONT " in ", ip); |
131 |
++ pr_cont("\n"); |
132 |
++ t->iopl_warn = 1; |
133 |
++ } |
134 |
++ |
135 |
++ regs->ip += 1; |
136 |
++ return true; |
137 |
++} |
138 |
++ |
139 |
+ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) |
140 |
+ { |
141 |
+ char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR; |
142 |
+@@ -548,6 +579,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) |
143 |
+ tsk = current; |
144 |
+ |
145 |
+ if (user_mode(regs)) { |
146 |
++ if (fixup_iopl_exception(regs)) |
147 |
++ goto exit; |
148 |
++ |
149 |
+ tsk->thread.error_code = error_code; |
150 |
+ tsk->thread.trap_nr = X86_TRAP_GP; |
151 |
+ |
152 |
+diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c |
153 |
+index bb0b3fe1e0a02..c6a19c88af547 100644 |
154 |
+--- a/arch/x86/lib/insn-eval.c |
155 |
++++ b/arch/x86/lib/insn-eval.c |
156 |
+@@ -1415,7 +1415,7 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) |
157 |
+ } |
158 |
+ } |
159 |
+ |
160 |
+-static unsigned long insn_get_effective_ip(struct pt_regs *regs) |
161 |
++unsigned long insn_get_effective_ip(struct pt_regs *regs) |
162 |
+ { |
163 |
+ unsigned long seg_base = 0; |
164 |
+ |
165 |
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c |
166 |
+index f0fa0c8e7ec60..ee537a9f1d1a4 100644 |
167 |
+--- a/drivers/block/loop.c |
168 |
++++ b/drivers/block/loop.c |
169 |
+@@ -228,19 +228,6 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) |
170 |
+ blk_mq_unfreeze_queue(lo->lo_queue); |
171 |
+ } |
172 |
+ |
173 |
+-/** |
174 |
+- * loop_validate_block_size() - validates the passed in block size |
175 |
+- * @bsize: size to validate |
176 |
+- */ |
177 |
+-static int |
178 |
+-loop_validate_block_size(unsigned short bsize) |
179 |
+-{ |
180 |
+- if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize)) |
181 |
+- return -EINVAL; |
182 |
+- |
183 |
+- return 0; |
184 |
+-} |
185 |
+- |
186 |
+ /** |
187 |
+ * loop_set_size() - sets device size and notifies userspace |
188 |
+ * @lo: struct loop_device to set the size for |
189 |
+@@ -1121,7 +1108,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, |
190 |
+ } |
191 |
+ |
192 |
+ if (config->block_size) { |
193 |
+- error = loop_validate_block_size(config->block_size); |
194 |
++ error = blk_validate_block_size(config->block_size); |
195 |
+ if (error) |
196 |
+ goto out_unlock; |
197 |
+ } |
198 |
+@@ -1617,7 +1604,7 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) |
199 |
+ if (lo->lo_state != Lo_bound) |
200 |
+ return -ENXIO; |
201 |
+ |
202 |
+- err = loop_validate_block_size(arg); |
203 |
++ err = blk_validate_block_size(arg); |
204 |
+ if (err) |
205 |
+ return err; |
206 |
+ |
207 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |
208 |
+index 6ef30252bfe0a..143b2cb13bf94 100644 |
209 |
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |
210 |
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |
211 |
+@@ -21,7 +21,6 @@ |
212 |
+ #include <linux/delay.h> |
213 |
+ #include <linux/mfd/syscon.h> |
214 |
+ #include <linux/regmap.h> |
215 |
+-#include <linux/pm_runtime.h> |
216 |
+ |
217 |
+ #include "stmmac_platform.h" |
218 |
+ |
219 |
+@@ -1336,9 +1335,6 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) |
220 |
+ return ret; |
221 |
+ } |
222 |
+ |
223 |
+- pm_runtime_enable(dev); |
224 |
+- pm_runtime_get_sync(dev); |
225 |
+- |
226 |
+ if (bsp_priv->integrated_phy) |
227 |
+ rk_gmac_integrated_phy_powerup(bsp_priv); |
228 |
+ |
229 |
+@@ -1347,14 +1343,9 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) |
230 |
+ |
231 |
+ static void rk_gmac_powerdown(struct rk_priv_data *gmac) |
232 |
+ { |
233 |
+- struct device *dev = &gmac->pdev->dev; |
234 |
+- |
235 |
+ if (gmac->integrated_phy) |
236 |
+ rk_gmac_integrated_phy_powerdown(gmac); |
237 |
+ |
238 |
+- pm_runtime_put_sync(dev); |
239 |
+- pm_runtime_disable(dev); |
240 |
+- |
241 |
+ phy_power_on(gmac, false); |
242 |
+ gmac_clk_enable(gmac, false); |
243 |
+ } |
244 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h |
245 |
+index 727e68dfaf1c2..a4ca283e02284 100644 |
246 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h |
247 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h |
248 |
+@@ -270,6 +270,7 @@ void stmmac_disable_eee_mode(struct stmmac_priv *priv); |
249 |
+ bool stmmac_eee_init(struct stmmac_priv *priv); |
250 |
+ int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt); |
251 |
+ int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size); |
252 |
++int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled); |
253 |
+ |
254 |
+ #if IS_ENABLED(CONFIG_STMMAC_SELFTESTS) |
255 |
+ void stmmac_selftest_run(struct net_device *dev, |
256 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
257 |
+index 0ac61e7ab43cd..4a75e73f06bbd 100644 |
258 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
259 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
260 |
+@@ -28,6 +28,7 @@ |
261 |
+ #include <linux/if_vlan.h> |
262 |
+ #include <linux/dma-mapping.h> |
263 |
+ #include <linux/slab.h> |
264 |
++#include <linux/pm_runtime.h> |
265 |
+ #include <linux/prefetch.h> |
266 |
+ #include <linux/pinctrl/consumer.h> |
267 |
+ #ifdef CONFIG_DEBUG_FS |
268 |
+@@ -113,6 +114,28 @@ static void stmmac_exit_fs(struct net_device *dev); |
269 |
+ |
270 |
+ #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) |
271 |
+ |
272 |
++int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled) |
273 |
++{ |
274 |
++ int ret = 0; |
275 |
++ |
276 |
++ if (enabled) { |
277 |
++ ret = clk_prepare_enable(priv->plat->stmmac_clk); |
278 |
++ if (ret) |
279 |
++ return ret; |
280 |
++ ret = clk_prepare_enable(priv->plat->pclk); |
281 |
++ if (ret) { |
282 |
++ clk_disable_unprepare(priv->plat->stmmac_clk); |
283 |
++ return ret; |
284 |
++ } |
285 |
++ } else { |
286 |
++ clk_disable_unprepare(priv->plat->stmmac_clk); |
287 |
++ clk_disable_unprepare(priv->plat->pclk); |
288 |
++ } |
289 |
++ |
290 |
++ return ret; |
291 |
++} |
292 |
++EXPORT_SYMBOL_GPL(stmmac_bus_clks_config); |
293 |
++ |
294 |
+ /** |
295 |
+ * stmmac_verify_args - verify the driver parameters. |
296 |
+ * Description: it checks the driver parameters and set a default in case of |
297 |
+@@ -2792,6 +2815,12 @@ static int stmmac_open(struct net_device *dev) |
298 |
+ u32 chan; |
299 |
+ int ret; |
300 |
+ |
301 |
++ ret = pm_runtime_get_sync(priv->device); |
302 |
++ if (ret < 0) { |
303 |
++ pm_runtime_put_noidle(priv->device); |
304 |
++ return ret; |
305 |
++ } |
306 |
++ |
307 |
+ if (priv->hw->pcs != STMMAC_PCS_TBI && |
308 |
+ priv->hw->pcs != STMMAC_PCS_RTBI && |
309 |
+ priv->hw->xpcs == NULL) { |
310 |
+@@ -2800,7 +2829,7 @@ static int stmmac_open(struct net_device *dev) |
311 |
+ netdev_err(priv->dev, |
312 |
+ "%s: Cannot attach to PHY (error: %d)\n", |
313 |
+ __func__, ret); |
314 |
+- return ret; |
315 |
++ goto init_phy_error; |
316 |
+ } |
317 |
+ } |
318 |
+ |
319 |
+@@ -2915,6 +2944,8 @@ init_error: |
320 |
+ free_dma_desc_resources(priv); |
321 |
+ dma_desc_error: |
322 |
+ phylink_disconnect_phy(priv->phylink); |
323 |
++init_phy_error: |
324 |
++ pm_runtime_put(priv->device); |
325 |
+ return ret; |
326 |
+ } |
327 |
+ |
328 |
+@@ -2965,6 +2996,8 @@ static int stmmac_release(struct net_device *dev) |
329 |
+ |
330 |
+ stmmac_release_ptp(priv); |
331 |
+ |
332 |
++ pm_runtime_put(priv->device); |
333 |
++ |
334 |
+ return 0; |
335 |
+ } |
336 |
+ |
337 |
+@@ -4291,12 +4324,21 @@ static int stmmac_set_mac_address(struct net_device *ndev, void *addr) |
338 |
+ struct stmmac_priv *priv = netdev_priv(ndev); |
339 |
+ int ret = 0; |
340 |
+ |
341 |
++ ret = pm_runtime_get_sync(priv->device); |
342 |
++ if (ret < 0) { |
343 |
++ pm_runtime_put_noidle(priv->device); |
344 |
++ return ret; |
345 |
++ } |
346 |
++ |
347 |
+ ret = eth_mac_addr(ndev, addr); |
348 |
+ if (ret) |
349 |
+- return ret; |
350 |
++ goto set_mac_error; |
351 |
+ |
352 |
+ stmmac_set_umac_addr(priv, priv->hw, ndev->dev_addr, 0); |
353 |
+ |
354 |
++set_mac_error: |
355 |
++ pm_runtime_put(priv->device); |
356 |
++ |
357 |
+ return ret; |
358 |
+ } |
359 |
+ |
360 |
+@@ -4616,6 +4658,12 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi |
361 |
+ bool is_double = false; |
362 |
+ int ret; |
363 |
+ |
364 |
++ ret = pm_runtime_get_sync(priv->device); |
365 |
++ if (ret < 0) { |
366 |
++ pm_runtime_put_noidle(priv->device); |
367 |
++ return ret; |
368 |
++ } |
369 |
++ |
370 |
+ if (be16_to_cpu(proto) == ETH_P_8021AD) |
371 |
+ is_double = true; |
372 |
+ |
373 |
+@@ -4624,10 +4672,15 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi |
374 |
+ if (priv->hw->num_vlan) { |
375 |
+ ret = stmmac_del_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid); |
376 |
+ if (ret) |
377 |
+- return ret; |
378 |
++ goto del_vlan_error; |
379 |
+ } |
380 |
+ |
381 |
+- return stmmac_vlan_update(priv, is_double); |
382 |
++ ret = stmmac_vlan_update(priv, is_double); |
383 |
++ |
384 |
++del_vlan_error: |
385 |
++ pm_runtime_put(priv->device); |
386 |
++ |
387 |
++ return ret; |
388 |
+ } |
389 |
+ |
390 |
+ static const struct net_device_ops stmmac_netdev_ops = { |
391 |
+@@ -5066,6 +5119,10 @@ int stmmac_dvr_probe(struct device *device, |
392 |
+ |
393 |
+ stmmac_check_pcs_mode(priv); |
394 |
+ |
395 |
++ pm_runtime_get_noresume(device); |
396 |
++ pm_runtime_set_active(device); |
397 |
++ pm_runtime_enable(device); |
398 |
++ |
399 |
+ if (priv->hw->pcs != STMMAC_PCS_TBI && |
400 |
+ priv->hw->pcs != STMMAC_PCS_RTBI) { |
401 |
+ /* MDIO bus Registration */ |
402 |
+@@ -5103,6 +5160,11 @@ int stmmac_dvr_probe(struct device *device, |
403 |
+ stmmac_init_fs(ndev); |
404 |
+ #endif |
405 |
+ |
406 |
++ /* Let pm_runtime_put() disable the clocks. |
407 |
++ * If CONFIG_PM is not enabled, the clocks will stay powered. |
408 |
++ */ |
409 |
++ pm_runtime_put(device); |
410 |
++ |
411 |
+ return ret; |
412 |
+ |
413 |
+ error_serdes_powerup: |
414 |
+@@ -5152,8 +5214,8 @@ int stmmac_dvr_remove(struct device *dev) |
415 |
+ phylink_destroy(priv->phylink); |
416 |
+ if (priv->plat->stmmac_rst) |
417 |
+ reset_control_assert(priv->plat->stmmac_rst); |
418 |
+- clk_disable_unprepare(priv->plat->pclk); |
419 |
+- clk_disable_unprepare(priv->plat->stmmac_clk); |
420 |
++ pm_runtime_put(dev); |
421 |
++ pm_runtime_disable(dev); |
422 |
+ if (priv->hw->pcs != STMMAC_PCS_TBI && |
423 |
+ priv->hw->pcs != STMMAC_PCS_RTBI) |
424 |
+ stmmac_mdio_unregister(ndev); |
425 |
+@@ -5176,6 +5238,7 @@ int stmmac_suspend(struct device *dev) |
426 |
+ struct net_device *ndev = dev_get_drvdata(dev); |
427 |
+ struct stmmac_priv *priv = netdev_priv(ndev); |
428 |
+ u32 chan; |
429 |
++ int ret; |
430 |
+ |
431 |
+ if (!ndev || !netif_running(ndev)) |
432 |
+ return 0; |
433 |
+@@ -5219,8 +5282,11 @@ int stmmac_suspend(struct device *dev) |
434 |
+ pinctrl_pm_select_sleep_state(priv->device); |
435 |
+ /* Disable clock in case of PWM is off */ |
436 |
+ clk_disable_unprepare(priv->plat->clk_ptp_ref); |
437 |
+- clk_disable_unprepare(priv->plat->pclk); |
438 |
+- clk_disable_unprepare(priv->plat->stmmac_clk); |
439 |
++ ret = pm_runtime_force_suspend(dev); |
440 |
++ if (ret) { |
441 |
++ mutex_unlock(&priv->lock); |
442 |
++ return ret; |
443 |
++ } |
444 |
+ } |
445 |
+ mutex_unlock(&priv->lock); |
446 |
+ |
447 |
+@@ -5286,8 +5352,9 @@ int stmmac_resume(struct device *dev) |
448 |
+ } else { |
449 |
+ pinctrl_pm_select_default_state(priv->device); |
450 |
+ /* enable the clk previously disabled */ |
451 |
+- clk_prepare_enable(priv->plat->stmmac_clk); |
452 |
+- clk_prepare_enable(priv->plat->pclk); |
453 |
++ ret = pm_runtime_force_resume(dev); |
454 |
++ if (ret) |
455 |
++ return ret; |
456 |
+ if (priv->plat->clk_ptp_ref) |
457 |
+ clk_prepare_enable(priv->plat->clk_ptp_ref); |
458 |
+ /* reset the phy so that it's ready */ |
459 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |
460 |
+index 678726c62a8af..7c1a14b256da3 100644 |
461 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |
462 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |
463 |
+@@ -15,6 +15,7 @@ |
464 |
+ #include <linux/iopoll.h> |
465 |
+ #include <linux/mii.h> |
466 |
+ #include <linux/of_mdio.h> |
467 |
++#include <linux/pm_runtime.h> |
468 |
+ #include <linux/phy.h> |
469 |
+ #include <linux/property.h> |
470 |
+ #include <linux/slab.h> |
471 |
+@@ -87,21 +88,29 @@ static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) |
472 |
+ u32 tmp, addr, value = MII_XGMAC_BUSY; |
473 |
+ int ret; |
474 |
+ |
475 |
++ ret = pm_runtime_get_sync(priv->device); |
476 |
++ if (ret < 0) { |
477 |
++ pm_runtime_put_noidle(priv->device); |
478 |
++ return ret; |
479 |
++ } |
480 |
++ |
481 |
+ /* Wait until any existing MII operation is complete */ |
482 |
+ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, |
483 |
+- !(tmp & MII_XGMAC_BUSY), 100, 10000)) |
484 |
+- return -EBUSY; |
485 |
++ !(tmp & MII_XGMAC_BUSY), 100, 10000)) { |
486 |
++ ret = -EBUSY; |
487 |
++ goto err_disable_clks; |
488 |
++ } |
489 |
+ |
490 |
+ if (phyreg & MII_ADDR_C45) { |
491 |
+ phyreg &= ~MII_ADDR_C45; |
492 |
+ |
493 |
+ ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr); |
494 |
+ if (ret) |
495 |
+- return ret; |
496 |
++ goto err_disable_clks; |
497 |
+ } else { |
498 |
+ ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); |
499 |
+ if (ret) |
500 |
+- return ret; |
501 |
++ goto err_disable_clks; |
502 |
+ |
503 |
+ value |= MII_XGMAC_SADDR; |
504 |
+ } |
505 |
+@@ -112,8 +121,10 @@ static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) |
506 |
+ |
507 |
+ /* Wait until any existing MII operation is complete */ |
508 |
+ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, |
509 |
+- !(tmp & MII_XGMAC_BUSY), 100, 10000)) |
510 |
+- return -EBUSY; |
511 |
++ !(tmp & MII_XGMAC_BUSY), 100, 10000)) { |
512 |
++ ret = -EBUSY; |
513 |
++ goto err_disable_clks; |
514 |
++ } |
515 |
+ |
516 |
+ /* Set the MII address register to read */ |
517 |
+ writel(addr, priv->ioaddr + mii_address); |
518 |
+@@ -121,11 +132,18 @@ static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) |
519 |
+ |
520 |
+ /* Wait until any existing MII operation is complete */ |
521 |
+ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, |
522 |
+- !(tmp & MII_XGMAC_BUSY), 100, 10000)) |
523 |
+- return -EBUSY; |
524 |
++ !(tmp & MII_XGMAC_BUSY), 100, 10000)) { |
525 |
++ ret = -EBUSY; |
526 |
++ goto err_disable_clks; |
527 |
++ } |
528 |
+ |
529 |
+ /* Read the data from the MII data register */ |
530 |
+- return readl(priv->ioaddr + mii_data) & GENMASK(15, 0); |
531 |
++ ret = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0); |
532 |
++ |
533 |
++err_disable_clks: |
534 |
++ pm_runtime_put(priv->device); |
535 |
++ |
536 |
++ return ret; |
537 |
+ } |
538 |
+ |
539 |
+ static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr, |
540 |
+@@ -138,21 +156,29 @@ static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr, |
541 |
+ u32 addr, tmp, value = MII_XGMAC_BUSY; |
542 |
+ int ret; |
543 |
+ |
544 |
++ ret = pm_runtime_get_sync(priv->device); |
545 |
++ if (ret < 0) { |
546 |
++ pm_runtime_put_noidle(priv->device); |
547 |
++ return ret; |
548 |
++ } |
549 |
++ |
550 |
+ /* Wait until any existing MII operation is complete */ |
551 |
+ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, |
552 |
+- !(tmp & MII_XGMAC_BUSY), 100, 10000)) |
553 |
+- return -EBUSY; |
554 |
++ !(tmp & MII_XGMAC_BUSY), 100, 10000)) { |
555 |
++ ret = -EBUSY; |
556 |
++ goto err_disable_clks; |
557 |
++ } |
558 |
+ |
559 |
+ if (phyreg & MII_ADDR_C45) { |
560 |
+ phyreg &= ~MII_ADDR_C45; |
561 |
+ |
562 |
+ ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr); |
563 |
+ if (ret) |
564 |
+- return ret; |
565 |
++ goto err_disable_clks; |
566 |
+ } else { |
567 |
+ ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); |
568 |
+ if (ret) |
569 |
+- return ret; |
570 |
++ goto err_disable_clks; |
571 |
+ |
572 |
+ value |= MII_XGMAC_SADDR; |
573 |
+ } |
574 |
+@@ -164,16 +190,23 @@ static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr, |
575 |
+ |
576 |
+ /* Wait until any existing MII operation is complete */ |
577 |
+ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, |
578 |
+- !(tmp & MII_XGMAC_BUSY), 100, 10000)) |
579 |
+- return -EBUSY; |
580 |
++ !(tmp & MII_XGMAC_BUSY), 100, 10000)) { |
581 |
++ ret = -EBUSY; |
582 |
++ goto err_disable_clks; |
583 |
++ } |
584 |
+ |
585 |
+ /* Set the MII address register to write */ |
586 |
+ writel(addr, priv->ioaddr + mii_address); |
587 |
+ writel(value, priv->ioaddr + mii_data); |
588 |
+ |
589 |
+ /* Wait until any existing MII operation is complete */ |
590 |
+- return readl_poll_timeout(priv->ioaddr + mii_data, tmp, |
591 |
+- !(tmp & MII_XGMAC_BUSY), 100, 10000); |
592 |
++ ret = readl_poll_timeout(priv->ioaddr + mii_data, tmp, |
593 |
++ !(tmp & MII_XGMAC_BUSY), 100, 10000); |
594 |
++ |
595 |
++err_disable_clks: |
596 |
++ pm_runtime_put(priv->device); |
597 |
++ |
598 |
++ return ret; |
599 |
+ } |
600 |
+ |
601 |
+ /** |
602 |
+@@ -196,6 +229,12 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) |
603 |
+ int data = 0; |
604 |
+ u32 v; |
605 |
+ |
606 |
++ data = pm_runtime_get_sync(priv->device); |
607 |
++ if (data < 0) { |
608 |
++ pm_runtime_put_noidle(priv->device); |
609 |
++ return data; |
610 |
++ } |
611 |
++ |
612 |
+ value |= (phyaddr << priv->hw->mii.addr_shift) |
613 |
+ & priv->hw->mii.addr_mask; |
614 |
+ value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; |
615 |
+@@ -216,19 +255,26 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) |
616 |
+ } |
617 |
+ |
618 |
+ if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), |
619 |
+- 100, 10000)) |
620 |
+- return -EBUSY; |
621 |
++ 100, 10000)) { |
622 |
++ data = -EBUSY; |
623 |
++ goto err_disable_clks; |
624 |
++ } |
625 |
+ |
626 |
+ writel(data, priv->ioaddr + mii_data); |
627 |
+ writel(value, priv->ioaddr + mii_address); |
628 |
+ |
629 |
+ if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), |
630 |
+- 100, 10000)) |
631 |
+- return -EBUSY; |
632 |
++ 100, 10000)) { |
633 |
++ data = -EBUSY; |
634 |
++ goto err_disable_clks; |
635 |
++ } |
636 |
+ |
637 |
+ /* Read the data from the MII data register */ |
638 |
+ data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK; |
639 |
+ |
640 |
++err_disable_clks: |
641 |
++ pm_runtime_put(priv->device); |
642 |
++ |
643 |
+ return data; |
644 |
+ } |
645 |
+ |
646 |
+@@ -247,10 +293,16 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, |
647 |
+ struct stmmac_priv *priv = netdev_priv(ndev); |
648 |
+ unsigned int mii_address = priv->hw->mii.addr; |
649 |
+ unsigned int mii_data = priv->hw->mii.data; |
650 |
++ int ret, data = phydata; |
651 |
+ u32 value = MII_BUSY; |
652 |
+- int data = phydata; |
653 |
+ u32 v; |
654 |
+ |
655 |
++ ret = pm_runtime_get_sync(priv->device); |
656 |
++ if (ret < 0) { |
657 |
++ pm_runtime_put_noidle(priv->device); |
658 |
++ return ret; |
659 |
++ } |
660 |
++ |
661 |
+ value |= (phyaddr << priv->hw->mii.addr_shift) |
662 |
+ & priv->hw->mii.addr_mask; |
663 |
+ value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; |
664 |
+@@ -275,16 +327,23 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, |
665 |
+ |
666 |
+ /* Wait until any existing MII operation is complete */ |
667 |
+ if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), |
668 |
+- 100, 10000)) |
669 |
+- return -EBUSY; |
670 |
++ 100, 10000)) { |
671 |
++ ret = -EBUSY; |
672 |
++ goto err_disable_clks; |
673 |
++ } |
674 |
+ |
675 |
+ /* Set the MII address register to write */ |
676 |
+ writel(data, priv->ioaddr + mii_data); |
677 |
+ writel(value, priv->ioaddr + mii_address); |
678 |
+ |
679 |
+ /* Wait until any existing MII operation is complete */ |
680 |
+- return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), |
681 |
+- 100, 10000); |
682 |
++ ret = readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), |
683 |
++ 100, 10000); |
684 |
++ |
685 |
++err_disable_clks: |
686 |
++ pm_runtime_put(priv->device); |
687 |
++ |
688 |
++ return ret; |
689 |
+ } |
690 |
+ |
691 |
+ /** |
692 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c |
693 |
+index 48186cd32ce10..035f9aef4308f 100644 |
694 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c |
695 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c |
696 |
+@@ -720,7 +720,6 @@ int stmmac_pltfr_remove(struct platform_device *pdev) |
697 |
+ } |
698 |
+ EXPORT_SYMBOL_GPL(stmmac_pltfr_remove); |
699 |
+ |
700 |
+-#ifdef CONFIG_PM_SLEEP |
701 |
+ /** |
702 |
+ * stmmac_pltfr_suspend |
703 |
+ * @dev: device pointer |
704 |
+@@ -728,7 +727,7 @@ EXPORT_SYMBOL_GPL(stmmac_pltfr_remove); |
705 |
+ * call the main suspend function and then, if required, on some platform, it |
706 |
+ * can call an exit helper. |
707 |
+ */ |
708 |
+-static int stmmac_pltfr_suspend(struct device *dev) |
709 |
++static int __maybe_unused stmmac_pltfr_suspend(struct device *dev) |
710 |
+ { |
711 |
+ int ret; |
712 |
+ struct net_device *ndev = dev_get_drvdata(dev); |
713 |
+@@ -749,7 +748,7 @@ static int stmmac_pltfr_suspend(struct device *dev) |
714 |
+ * the main resume function, on some platforms, it can call own init helper |
715 |
+ * if required. |
716 |
+ */ |
717 |
+-static int stmmac_pltfr_resume(struct device *dev) |
718 |
++static int __maybe_unused stmmac_pltfr_resume(struct device *dev) |
719 |
+ { |
720 |
+ struct net_device *ndev = dev_get_drvdata(dev); |
721 |
+ struct stmmac_priv *priv = netdev_priv(ndev); |
722 |
+@@ -760,10 +759,29 @@ static int stmmac_pltfr_resume(struct device *dev) |
723 |
+ |
724 |
+ return stmmac_resume(dev); |
725 |
+ } |
726 |
+-#endif /* CONFIG_PM_SLEEP */ |
727 |
+ |
728 |
+-SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend, |
729 |
+- stmmac_pltfr_resume); |
730 |
++static int __maybe_unused stmmac_runtime_suspend(struct device *dev) |
731 |
++{ |
732 |
++ struct net_device *ndev = dev_get_drvdata(dev); |
733 |
++ struct stmmac_priv *priv = netdev_priv(ndev); |
734 |
++ |
735 |
++ stmmac_bus_clks_config(priv, false); |
736 |
++ |
737 |
++ return 0; |
738 |
++} |
739 |
++ |
740 |
++static int __maybe_unused stmmac_runtime_resume(struct device *dev) |
741 |
++{ |
742 |
++ struct net_device *ndev = dev_get_drvdata(dev); |
743 |
++ struct stmmac_priv *priv = netdev_priv(ndev); |
744 |
++ |
745 |
++ return stmmac_bus_clks_config(priv, true); |
746 |
++} |
747 |
++ |
748 |
++const struct dev_pm_ops stmmac_pltfr_pm_ops = { |
749 |
++ SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume) |
750 |
++ SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL) |
751 |
++}; |
752 |
+ EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops); |
753 |
+ |
754 |
+ MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support"); |
755 |
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c |
756 |
+index a7a1c74113483..db7475dc601f5 100644 |
757 |
+--- a/drivers/pci/msi.c |
758 |
++++ b/drivers/pci/msi.c |
759 |
+@@ -396,18 +396,6 @@ static void free_msi_irqs(struct pci_dev *dev) |
760 |
+ for (i = 0; i < entry->nvec_used; i++) |
761 |
+ BUG_ON(irq_has_action(entry->irq + i)); |
762 |
+ |
763 |
+- pci_msi_teardown_msi_irqs(dev); |
764 |
+- |
765 |
+- list_for_each_entry_safe(entry, tmp, msi_list, list) { |
766 |
+- if (entry->msi_attrib.is_msix) { |
767 |
+- if (list_is_last(&entry->list, msi_list)) |
768 |
+- iounmap(entry->mask_base); |
769 |
+- } |
770 |
+- |
771 |
+- list_del(&entry->list); |
772 |
+- free_msi_entry(entry); |
773 |
+- } |
774 |
+- |
775 |
+ if (dev->msi_irq_groups) { |
776 |
+ sysfs_remove_groups(&dev->dev.kobj, dev->msi_irq_groups); |
777 |
+ msi_attrs = dev->msi_irq_groups[0]->attrs; |
778 |
+@@ -423,6 +411,18 @@ static void free_msi_irqs(struct pci_dev *dev) |
779 |
+ kfree(dev->msi_irq_groups); |
780 |
+ dev->msi_irq_groups = NULL; |
781 |
+ } |
782 |
++ |
783 |
++ pci_msi_teardown_msi_irqs(dev); |
784 |
++ |
785 |
++ list_for_each_entry_safe(entry, tmp, msi_list, list) { |
786 |
++ if (entry->msi_attrib.is_msix) { |
787 |
++ if (list_is_last(&entry->list, msi_list)) |
788 |
++ iounmap(entry->mask_base); |
789 |
++ } |
790 |
++ |
791 |
++ list_del(&entry->list); |
792 |
++ free_msi_entry(entry); |
793 |
++ } |
794 |
+ } |
795 |
+ |
796 |
+ static void pci_intx_for_msi(struct pci_dev *dev, int enable) |
797 |
+@@ -592,6 +592,9 @@ msi_setup_entry(struct pci_dev *dev, int nvec, struct irq_affinity *affd) |
798 |
+ goto out; |
799 |
+ |
800 |
+ pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
801 |
++ /* Lies, damned lies, and MSIs */ |
802 |
++ if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING) |
803 |
++ control |= PCI_MSI_FLAGS_MASKBIT; |
804 |
+ |
805 |
+ entry->msi_attrib.is_msix = 0; |
806 |
+ entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); |
807 |
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
808 |
+index fb91b2d7b1c59..bb863ddb59bfc 100644 |
809 |
+--- a/drivers/pci/quirks.c |
810 |
++++ b/drivers/pci/quirks.c |
811 |
+@@ -5756,3 +5756,9 @@ static void apex_pci_fixup_class(struct pci_dev *pdev) |
812 |
+ } |
813 |
+ DECLARE_PCI_FIXUP_CLASS_HEADER(0x1ac1, 0x089a, |
814 |
+ PCI_CLASS_NOT_DEFINED, 8, apex_pci_fixup_class); |
815 |
++ |
816 |
++static void nvidia_ion_ahci_fixup(struct pci_dev *pdev) |
817 |
++{ |
818 |
++ pdev->dev_flags |= PCI_DEV_FLAGS_HAS_MSI_MASKING; |
819 |
++} |
820 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0ab8, nvidia_ion_ahci_fixup); |
821 |
+diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c |
822 |
+index 6379f26a335f6..9233f7e744544 100644 |
823 |
+--- a/drivers/thermal/thermal_of.c |
824 |
++++ b/drivers/thermal/thermal_of.c |
825 |
+@@ -89,7 +89,7 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, |
826 |
+ { |
827 |
+ struct __thermal_zone *data = tz->devdata; |
828 |
+ |
829 |
+- if (!data->ops->get_temp) |
830 |
++ if (!data->ops || !data->ops->get_temp) |
831 |
+ return -EINVAL; |
832 |
+ |
833 |
+ return data->ops->get_temp(data->sensor_data, temp); |
834 |
+@@ -186,6 +186,9 @@ static int of_thermal_set_emul_temp(struct thermal_zone_device *tz, |
835 |
+ { |
836 |
+ struct __thermal_zone *data = tz->devdata; |
837 |
+ |
838 |
++ if (!data->ops || !data->ops->set_emul_temp) |
839 |
++ return -EINVAL; |
840 |
++ |
841 |
+ return data->ops->set_emul_temp(data->sensor_data, temp); |
842 |
+ } |
843 |
+ |
844 |
+@@ -194,7 +197,7 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, |
845 |
+ { |
846 |
+ struct __thermal_zone *data = tz->devdata; |
847 |
+ |
848 |
+- if (!data->ops->get_trend) |
849 |
++ if (!data->ops || !data->ops->get_trend) |
850 |
+ return -EINVAL; |
851 |
+ |
852 |
+ return data->ops->get_trend(data->sensor_data, trip, trend); |
853 |
+@@ -301,7 +304,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip, |
854 |
+ if (trip >= data->ntrips || trip < 0) |
855 |
+ return -EDOM; |
856 |
+ |
857 |
+- if (data->ops->set_trip_temp) { |
858 |
++ if (data->ops && data->ops->set_trip_temp) { |
859 |
+ int ret; |
860 |
+ |
861 |
+ ret = data->ops->set_trip_temp(data->sensor_data, trip, temp); |
862 |
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c |
863 |
+index 86fd3bf62af61..8cb2cf612e49b 100644 |
864 |
+--- a/fs/erofs/zdata.c |
865 |
++++ b/fs/erofs/zdata.c |
866 |
+@@ -278,11 +278,10 @@ static inline bool z_erofs_try_inplace_io(struct z_erofs_collector *clt, |
867 |
+ |
868 |
+ /* callers must be with collection lock held */ |
869 |
+ static int z_erofs_attach_page(struct z_erofs_collector *clt, |
870 |
+- struct page *page, |
871 |
+- enum z_erofs_page_type type) |
872 |
++ struct page *page, enum z_erofs_page_type type, |
873 |
++ bool pvec_safereuse) |
874 |
+ { |
875 |
+ int ret; |
876 |
+- bool occupied; |
877 |
+ |
878 |
+ /* give priority for inplaceio */ |
879 |
+ if (clt->mode >= COLLECT_PRIMARY && |
880 |
+@@ -290,10 +289,9 @@ static int z_erofs_attach_page(struct z_erofs_collector *clt, |
881 |
+ z_erofs_try_inplace_io(clt, page)) |
882 |
+ return 0; |
883 |
+ |
884 |
+- ret = z_erofs_pagevec_enqueue(&clt->vector, |
885 |
+- page, type, &occupied); |
886 |
++ ret = z_erofs_pagevec_enqueue(&clt->vector, page, type, |
887 |
++ pvec_safereuse); |
888 |
+ clt->cl->vcnt += (unsigned int)ret; |
889 |
+- |
890 |
+ return ret ? 0 : -EAGAIN; |
891 |
+ } |
892 |
+ |
893 |
+@@ -647,7 +645,8 @@ hitted: |
894 |
+ tight &= (clt->mode >= COLLECT_PRIMARY_FOLLOWED); |
895 |
+ |
896 |
+ retry: |
897 |
+- err = z_erofs_attach_page(clt, page, page_type); |
898 |
++ err = z_erofs_attach_page(clt, page, page_type, |
899 |
++ clt->mode >= COLLECT_PRIMARY_FOLLOWED); |
900 |
+ /* should allocate an additional staging page for pagevec */ |
901 |
+ if (err == -EAGAIN) { |
902 |
+ struct page *const newpage = |
903 |
+@@ -655,7 +654,7 @@ retry: |
904 |
+ |
905 |
+ newpage->mapping = Z_EROFS_MAPPING_STAGING; |
906 |
+ err = z_erofs_attach_page(clt, newpage, |
907 |
+- Z_EROFS_PAGE_TYPE_EXCLUSIVE); |
908 |
++ Z_EROFS_PAGE_TYPE_EXCLUSIVE, true); |
909 |
+ if (!err) |
910 |
+ goto retry; |
911 |
+ } |
912 |
+diff --git a/fs/erofs/zpvec.h b/fs/erofs/zpvec.h |
913 |
+index 1d67cbd387042..52898176ef31d 100644 |
914 |
+--- a/fs/erofs/zpvec.h |
915 |
++++ b/fs/erofs/zpvec.h |
916 |
+@@ -108,12 +108,17 @@ static inline void z_erofs_pagevec_ctor_init(struct z_erofs_pagevec_ctor *ctor, |
917 |
+ static inline bool z_erofs_pagevec_enqueue(struct z_erofs_pagevec_ctor *ctor, |
918 |
+ struct page *page, |
919 |
+ enum z_erofs_page_type type, |
920 |
+- bool *occupied) |
921 |
++ bool pvec_safereuse) |
922 |
+ { |
923 |
+- *occupied = false; |
924 |
+- if (!ctor->next && type) |
925 |
+- if (ctor->index + 1 == ctor->nr) |
926 |
++ if (!ctor->next) { |
927 |
++ /* some pages cannot be reused as pvec safely without I/O */ |
928 |
++ if (type == Z_EROFS_PAGE_TYPE_EXCLUSIVE && !pvec_safereuse) |
929 |
++ type = Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED; |
930 |
++ |
931 |
++ if (type != Z_EROFS_PAGE_TYPE_EXCLUSIVE && |
932 |
++ ctor->index + 1 == ctor->nr) |
933 |
+ return false; |
934 |
++ } |
935 |
+ |
936 |
+ if (ctor->index >= ctor->nr) |
937 |
+ z_erofs_pagevec_ctor_pagedown(ctor, false); |
938 |
+@@ -125,7 +130,6 @@ static inline bool z_erofs_pagevec_enqueue(struct z_erofs_pagevec_ctor *ctor, |
939 |
+ /* should remind that collector->next never equal to 1, 2 */ |
940 |
+ if (type == (uintptr_t)ctor->next) { |
941 |
+ ctor->next = page; |
942 |
+- *occupied = true; |
943 |
+ } |
944 |
+ ctor->pages[ctor->index++] = tagptr_fold(erofs_vtptr_t, page, type); |
945 |
+ return true; |
946 |
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h |
947 |
+index 4ba17736b614f..98fdf5a31fd66 100644 |
948 |
+--- a/include/linux/blkdev.h |
949 |
++++ b/include/linux/blkdev.h |
950 |
+@@ -59,6 +59,14 @@ struct blk_keyslot_manager; |
951 |
+ */ |
952 |
+ #define BLKCG_MAX_POLS 5 |
953 |
+ |
954 |
++static inline int blk_validate_block_size(unsigned int bsize) |
955 |
++{ |
956 |
++ if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize)) |
957 |
++ return -EINVAL; |
958 |
++ |
959 |
++ return 0; |
960 |
++} |
961 |
++ |
962 |
+ typedef void (rq_end_io_fn)(struct request *, blk_status_t); |
963 |
+ |
964 |
+ /* |
965 |
+diff --git a/include/linux/pci.h b/include/linux/pci.h |
966 |
+index a55097b4d9927..4519bd12643f6 100644 |
967 |
+--- a/include/linux/pci.h |
968 |
++++ b/include/linux/pci.h |
969 |
+@@ -227,6 +227,8 @@ enum pci_dev_flags { |
970 |
+ PCI_DEV_FLAGS_NO_FLR_RESET = (__force pci_dev_flags_t) (1 << 10), |
971 |
+ /* Don't use Relaxed Ordering for TLPs directed at this device */ |
972 |
+ PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 11), |
973 |
++ /* Device does honor MSI masking despite saying otherwise */ |
974 |
++ PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12), |
975 |
+ }; |
976 |
+ |
977 |
+ enum pci_irq_reroute_variant { |
978 |
+diff --git a/init/main.c b/init/main.c |
979 |
+index dd26a42e80a87..4fe58ed4aca7b 100644 |
980 |
+--- a/init/main.c |
981 |
++++ b/init/main.c |
982 |
+@@ -380,6 +380,7 @@ static char * __init xbc_make_cmdline(const char *key) |
983 |
+ ret = xbc_snprint_cmdline(new_cmdline, len + 1, root); |
984 |
+ if (ret < 0 || ret > len) { |
985 |
+ pr_err("Failed to print extra kernel cmdline.\n"); |
986 |
++ memblock_free(__pa(new_cmdline), len + 1); |
987 |
+ return NULL; |
988 |
+ } |
989 |
+ |
990 |
+diff --git a/kernel/events/core.c b/kernel/events/core.c |
991 |
+index c811519261710..908417736f4e9 100644 |
992 |
+--- a/kernel/events/core.c |
993 |
++++ b/kernel/events/core.c |
994 |
+@@ -7036,7 +7036,6 @@ void perf_output_sample(struct perf_output_handle *handle, |
995 |
+ static u64 perf_virt_to_phys(u64 virt) |
996 |
+ { |
997 |
+ u64 phys_addr = 0; |
998 |
+- struct page *p = NULL; |
999 |
+ |
1000 |
+ if (!virt) |
1001 |
+ return 0; |
1002 |
+@@ -7055,14 +7054,15 @@ static u64 perf_virt_to_phys(u64 virt) |
1003 |
+ * If failed, leave phys_addr as 0. |
1004 |
+ */ |
1005 |
+ if (current->mm != NULL) { |
1006 |
++ struct page *p; |
1007 |
++ |
1008 |
+ pagefault_disable(); |
1009 |
+- if (get_user_page_fast_only(virt, 0, &p)) |
1010 |
++ if (get_user_page_fast_only(virt, 0, &p)) { |
1011 |
+ phys_addr = page_to_phys(p) + virt % PAGE_SIZE; |
1012 |
++ put_page(p); |
1013 |
++ } |
1014 |
+ pagefault_enable(); |
1015 |
+ } |
1016 |
+- |
1017 |
+- if (p) |
1018 |
+- put_page(p); |
1019 |
+ } |
1020 |
+ |
1021 |
+ return phys_addr; |
1022 |
+diff --git a/scripts/lld-version.sh b/scripts/lld-version.sh |
1023 |
+index d70edb4d8a4f2..f1eeee450a23c 100755 |
1024 |
+--- a/scripts/lld-version.sh |
1025 |
++++ b/scripts/lld-version.sh |
1026 |
+@@ -6,15 +6,32 @@ |
1027 |
+ # Print the linker version of `ld.lld' in a 5 or 6-digit form |
1028 |
+ # such as `100001' for ld.lld 10.0.1 etc. |
1029 |
+ |
1030 |
+-linker_string="$($* --version)" |
1031 |
++set -e |
1032 |
+ |
1033 |
+-if ! ( echo $linker_string | grep -q LLD ); then |
1034 |
++# Convert the version string x.y.z to a canonical 5 or 6-digit form. |
1035 |
++get_canonical_version() |
1036 |
++{ |
1037 |
++ IFS=. |
1038 |
++ set -- $1 |
1039 |
++ |
1040 |
++ # If the 2nd or 3rd field is missing, fill it with a zero. |
1041 |
++ echo $((10000 * $1 + 100 * ${2:-0} + ${3:-0})) |
1042 |
++} |
1043 |
++ |
1044 |
++# Get the first line of the --version output. |
1045 |
++IFS=' |
1046 |
++' |
1047 |
++set -- $(LC_ALL=C "$@" --version) |
1048 |
++ |
1049 |
++# Split the line on spaces. |
1050 |
++IFS=' ' |
1051 |
++set -- $1 |
1052 |
++ |
1053 |
++while [ $# -gt 1 -a "$1" != "LLD" ]; do |
1054 |
++ shift |
1055 |
++done |
1056 |
++if [ "$1" = LLD ]; then |
1057 |
++ echo $(get_canonical_version ${2%-*}) |
1058 |
++else |
1059 |
+ echo 0 |
1060 |
+- exit 1 |
1061 |
+ fi |
1062 |
+- |
1063 |
+-VERSION=$(echo $linker_string | cut -d ' ' -f 2) |
1064 |
+-MAJOR=$(echo $VERSION | cut -d . -f 1) |
1065 |
+-MINOR=$(echo $VERSION | cut -d . -f 2) |
1066 |
+-PATCHLEVEL=$(echo $VERSION | cut -d . -f 3) |
1067 |
+-printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL |
1068 |
+diff --git a/security/Kconfig b/security/Kconfig |
1069 |
+index 7561f6f99f1d2..0548db16c49dc 100644 |
1070 |
+--- a/security/Kconfig |
1071 |
++++ b/security/Kconfig |
1072 |
+@@ -191,6 +191,9 @@ config HARDENED_USERCOPY_PAGESPAN |
1073 |
+ config FORTIFY_SOURCE |
1074 |
+ bool "Harden common str/mem functions against buffer overflows" |
1075 |
+ depends on ARCH_HAS_FORTIFY_SOURCE |
1076 |
++ # https://bugs.llvm.org/show_bug.cgi?id=50322 |
1077 |
++ # https://bugs.llvm.org/show_bug.cgi?id=41459 |
1078 |
++ depends on !CC_IS_CLANG |
1079 |
+ help |
1080 |
+ Detect overflows of buffers in common string and memory functions |
1081 |
+ where the compiler can determine and validate the buffer sizes. |
1082 |
+diff --git a/tools/testing/selftests/x86/iopl.c b/tools/testing/selftests/x86/iopl.c |
1083 |
+index bab2f6e06b63d..7e3e09c1abac6 100644 |
1084 |
+--- a/tools/testing/selftests/x86/iopl.c |
1085 |
++++ b/tools/testing/selftests/x86/iopl.c |
1086 |
+@@ -85,48 +85,88 @@ static void expect_gp_outb(unsigned short port) |
1087 |
+ printf("[OK]\toutb to 0x%02hx failed\n", port); |
1088 |
+ } |
1089 |
+ |
1090 |
+-static bool try_cli(void) |
1091 |
++#define RET_FAULTED 0 |
1092 |
++#define RET_FAIL 1 |
1093 |
++#define RET_EMUL 2 |
1094 |
++ |
1095 |
++static int try_cli(void) |
1096 |
+ { |
1097 |
++ unsigned long flags; |
1098 |
++ |
1099 |
+ sethandler(SIGSEGV, sigsegv, SA_RESETHAND); |
1100 |
+ if (sigsetjmp(jmpbuf, 1) != 0) { |
1101 |
+- return false; |
1102 |
++ return RET_FAULTED; |
1103 |
+ } else { |
1104 |
+- asm volatile ("cli"); |
1105 |
+- return true; |
1106 |
++ asm volatile("cli; pushf; pop %[flags]" |
1107 |
++ : [flags] "=rm" (flags)); |
1108 |
++ |
1109 |
++ /* X86_FLAGS_IF */ |
1110 |
++ if (!(flags & (1 << 9))) |
1111 |
++ return RET_FAIL; |
1112 |
++ else |
1113 |
++ return RET_EMUL; |
1114 |
+ } |
1115 |
+ clearhandler(SIGSEGV); |
1116 |
+ } |
1117 |
+ |
1118 |
+-static bool try_sti(void) |
1119 |
++static int try_sti(bool irqs_off) |
1120 |
+ { |
1121 |
++ unsigned long flags; |
1122 |
++ |
1123 |
+ sethandler(SIGSEGV, sigsegv, SA_RESETHAND); |
1124 |
+ if (sigsetjmp(jmpbuf, 1) != 0) { |
1125 |
+- return false; |
1126 |
++ return RET_FAULTED; |
1127 |
+ } else { |
1128 |
+- asm volatile ("sti"); |
1129 |
+- return true; |
1130 |
++ asm volatile("sti; pushf; pop %[flags]" |
1131 |
++ : [flags] "=rm" (flags)); |
1132 |
++ |
1133 |
++ /* X86_FLAGS_IF */ |
1134 |
++ if (irqs_off && (flags & (1 << 9))) |
1135 |
++ return RET_FAIL; |
1136 |
++ else |
1137 |
++ return RET_EMUL; |
1138 |
+ } |
1139 |
+ clearhandler(SIGSEGV); |
1140 |
+ } |
1141 |
+ |
1142 |
+-static void expect_gp_sti(void) |
1143 |
++static void expect_gp_sti(bool irqs_off) |
1144 |
+ { |
1145 |
+- if (try_sti()) { |
1146 |
++ int ret = try_sti(irqs_off); |
1147 |
++ |
1148 |
++ switch (ret) { |
1149 |
++ case RET_FAULTED: |
1150 |
++ printf("[OK]\tSTI faulted\n"); |
1151 |
++ break; |
1152 |
++ case RET_EMUL: |
1153 |
++ printf("[OK]\tSTI NOPped\n"); |
1154 |
++ break; |
1155 |
++ default: |
1156 |
+ printf("[FAIL]\tSTI worked\n"); |
1157 |
+ nerrs++; |
1158 |
+- } else { |
1159 |
+- printf("[OK]\tSTI faulted\n"); |
1160 |
+ } |
1161 |
+ } |
1162 |
+ |
1163 |
+-static void expect_gp_cli(void) |
1164 |
++/* |
1165 |
++ * Returns whether it managed to disable interrupts. |
1166 |
++ */ |
1167 |
++static bool test_cli(void) |
1168 |
+ { |
1169 |
+- if (try_cli()) { |
1170 |
++ int ret = try_cli(); |
1171 |
++ |
1172 |
++ switch (ret) { |
1173 |
++ case RET_FAULTED: |
1174 |
++ printf("[OK]\tCLI faulted\n"); |
1175 |
++ break; |
1176 |
++ case RET_EMUL: |
1177 |
++ printf("[OK]\tCLI NOPped\n"); |
1178 |
++ break; |
1179 |
++ default: |
1180 |
+ printf("[FAIL]\tCLI worked\n"); |
1181 |
+ nerrs++; |
1182 |
+- } else { |
1183 |
+- printf("[OK]\tCLI faulted\n"); |
1184 |
++ return true; |
1185 |
+ } |
1186 |
++ |
1187 |
++ return false; |
1188 |
+ } |
1189 |
+ |
1190 |
+ int main(void) |
1191 |
+@@ -152,8 +192,7 @@ int main(void) |
1192 |
+ } |
1193 |
+ |
1194 |
+ /* Make sure that CLI/STI are blocked even with IOPL level 3 */ |
1195 |
+- expect_gp_cli(); |
1196 |
+- expect_gp_sti(); |
1197 |
++ expect_gp_sti(test_cli()); |
1198 |
+ expect_ok_outb(0x80); |
1199 |
+ |
1200 |
+ /* Establish an I/O bitmap to test the restore */ |
1201 |
+@@ -204,8 +243,7 @@ int main(void) |
1202 |
+ printf("[RUN]\tparent: write to 0x80 (should fail)\n"); |
1203 |
+ |
1204 |
+ expect_gp_outb(0x80); |
1205 |
+- expect_gp_cli(); |
1206 |
+- expect_gp_sti(); |
1207 |
++ expect_gp_sti(test_cli()); |
1208 |
+ |
1209 |
+ /* Test the capability checks. */ |
1210 |
+ printf("\tiopl(3)\n"); |