1 |
commit: 94c6ca333405e69c23dd1c0a2ccc86236f50e833 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Jun 25 19:42:33 2022 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Jun 25 19:42:33 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=94c6ca33 |
7 |
|
8 |
Linux patch 5.18.7 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1006_linux-5.18.7.patch | 779 ++++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 783 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 84b72755..17ef0755 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -67,6 +67,10 @@ Patch: 1005_linux-5.18.6.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 5.18.6 |
23 |
|
24 |
+Patch: 1006_linux-5.18.7.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.18.7 |
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/1006_linux-5.18.7.patch b/1006_linux-5.18.7.patch |
33 |
new file mode 100644 |
34 |
index 00000000..ec6938d8 |
35 |
--- /dev/null |
36 |
+++ b/1006_linux-5.18.7.patch |
37 |
@@ -0,0 +1,779 @@ |
38 |
+diff --git a/Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml b/Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml |
39 |
+index 80914b93638e4..24c5e38584528 100644 |
40 |
+--- a/Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml |
41 |
++++ b/Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml |
42 |
+@@ -24,15 +24,29 @@ properties: |
43 |
+ reg: |
44 |
+ maxItems: 1 |
45 |
+ |
46 |
++ clocks: |
47 |
++ maxItems: 1 |
48 |
++ description: |
49 |
++ The SFP clock. Typically, this is the platform clock divided by 4. |
50 |
++ |
51 |
++ clock-names: |
52 |
++ const: sfp |
53 |
++ |
54 |
+ required: |
55 |
+ - compatible |
56 |
+ - reg |
57 |
++ - clock-names |
58 |
++ - clocks |
59 |
+ |
60 |
+ unevaluatedProperties: false |
61 |
+ |
62 |
+ examples: |
63 |
+ - | |
64 |
++ #include <dt-bindings/clock/fsl,qoriq-clockgen.h> |
65 |
+ efuse@1e80000 { |
66 |
+ compatible = "fsl,ls1028a-sfp"; |
67 |
+ reg = <0x1e80000 0x8000>; |
68 |
++ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL |
69 |
++ QORIQ_CLK_PLL_DIV(4)>; |
70 |
++ clock-names = "sfp"; |
71 |
+ }; |
72 |
+diff --git a/Makefile b/Makefile |
73 |
+index 27850d452d652..61d63068553c8 100644 |
74 |
+--- a/Makefile |
75 |
++++ b/Makefile |
76 |
+@@ -1,7 +1,7 @@ |
77 |
+ # SPDX-License-Identifier: GPL-2.0 |
78 |
+ VERSION = 5 |
79 |
+ PATCHLEVEL = 18 |
80 |
+-SUBLEVEL = 6 |
81 |
++SUBLEVEL = 7 |
82 |
+ EXTRAVERSION = |
83 |
+ NAME = Superb Owl |
84 |
+ |
85 |
+diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c |
86 |
+index 697df02362af1..4909dcd762e8c 100644 |
87 |
+--- a/arch/s390/mm/pgtable.c |
88 |
++++ b/arch/s390/mm/pgtable.c |
89 |
+@@ -748,7 +748,7 @@ void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
90 |
+ pgste_val(pgste) |= PGSTE_GR_BIT | PGSTE_GC_BIT; |
91 |
+ ptev = pte_val(*ptep); |
92 |
+ if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE)) |
93 |
+- page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1); |
94 |
++ page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 0); |
95 |
+ pgste_set_unlock(ptep, pgste); |
96 |
+ preempt_enable(); |
97 |
+ } |
98 |
+diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h |
99 |
+index 34c9dbb6a47d6..686a9d75a0e41 100644 |
100 |
+--- a/arch/x86/boot/boot.h |
101 |
++++ b/arch/x86/boot/boot.h |
102 |
+@@ -110,66 +110,78 @@ typedef unsigned int addr_t; |
103 |
+ |
104 |
+ static inline u8 rdfs8(addr_t addr) |
105 |
+ { |
106 |
++ u8 *ptr = (u8 *)absolute_pointer(addr); |
107 |
+ u8 v; |
108 |
+- asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); |
109 |
++ asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*ptr)); |
110 |
+ return v; |
111 |
+ } |
112 |
+ static inline u16 rdfs16(addr_t addr) |
113 |
+ { |
114 |
++ u16 *ptr = (u16 *)absolute_pointer(addr); |
115 |
+ u16 v; |
116 |
+- asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); |
117 |
++ asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*ptr)); |
118 |
+ return v; |
119 |
+ } |
120 |
+ static inline u32 rdfs32(addr_t addr) |
121 |
+ { |
122 |
++ u32 *ptr = (u32 *)absolute_pointer(addr); |
123 |
+ u32 v; |
124 |
+- asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); |
125 |
++ asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*ptr)); |
126 |
+ return v; |
127 |
+ } |
128 |
+ |
129 |
+ static inline void wrfs8(u8 v, addr_t addr) |
130 |
+ { |
131 |
+- asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "qi" (v)); |
132 |
++ u8 *ptr = (u8 *)absolute_pointer(addr); |
133 |
++ asm volatile("movb %1,%%fs:%0" : "+m" (*ptr) : "qi" (v)); |
134 |
+ } |
135 |
+ static inline void wrfs16(u16 v, addr_t addr) |
136 |
+ { |
137 |
+- asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "ri" (v)); |
138 |
++ u16 *ptr = (u16 *)absolute_pointer(addr); |
139 |
++ asm volatile("movw %1,%%fs:%0" : "+m" (*ptr) : "ri" (v)); |
140 |
+ } |
141 |
+ static inline void wrfs32(u32 v, addr_t addr) |
142 |
+ { |
143 |
+- asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "ri" (v)); |
144 |
++ u32 *ptr = (u32 *)absolute_pointer(addr); |
145 |
++ asm volatile("movl %1,%%fs:%0" : "+m" (*ptr) : "ri" (v)); |
146 |
+ } |
147 |
+ |
148 |
+ static inline u8 rdgs8(addr_t addr) |
149 |
+ { |
150 |
++ u8 *ptr = (u8 *)absolute_pointer(addr); |
151 |
+ u8 v; |
152 |
+- asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); |
153 |
++ asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*ptr)); |
154 |
+ return v; |
155 |
+ } |
156 |
+ static inline u16 rdgs16(addr_t addr) |
157 |
+ { |
158 |
++ u16 *ptr = (u16 *)absolute_pointer(addr); |
159 |
+ u16 v; |
160 |
+- asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); |
161 |
++ asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*ptr)); |
162 |
+ return v; |
163 |
+ } |
164 |
+ static inline u32 rdgs32(addr_t addr) |
165 |
+ { |
166 |
++ u32 *ptr = (u32 *)absolute_pointer(addr); |
167 |
+ u32 v; |
168 |
+- asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); |
169 |
++ asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*ptr)); |
170 |
+ return v; |
171 |
+ } |
172 |
+ |
173 |
+ static inline void wrgs8(u8 v, addr_t addr) |
174 |
+ { |
175 |
+- asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "qi" (v)); |
176 |
++ u8 *ptr = (u8 *)absolute_pointer(addr); |
177 |
++ asm volatile("movb %1,%%gs:%0" : "+m" (*ptr) : "qi" (v)); |
178 |
+ } |
179 |
+ static inline void wrgs16(u16 v, addr_t addr) |
180 |
+ { |
181 |
+- asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "ri" (v)); |
182 |
++ u16 *ptr = (u16 *)absolute_pointer(addr); |
183 |
++ asm volatile("movw %1,%%gs:%0" : "+m" (*ptr) : "ri" (v)); |
184 |
+ } |
185 |
+ static inline void wrgs32(u32 v, addr_t addr) |
186 |
+ { |
187 |
+- asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "ri" (v)); |
188 |
++ u32 *ptr = (u32 *)absolute_pointer(addr); |
189 |
++ asm volatile("movl %1,%%gs:%0" : "+m" (*ptr) : "ri" (v)); |
190 |
+ } |
191 |
+ |
192 |
+ /* Note: these only return true/false, not a signed return value! */ |
193 |
+diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c |
194 |
+index e3add857c2c9d..c421af5a3cdce 100644 |
195 |
+--- a/arch/x86/boot/main.c |
196 |
++++ b/arch/x86/boot/main.c |
197 |
+@@ -33,7 +33,7 @@ static void copy_boot_params(void) |
198 |
+ u16 cl_offset; |
199 |
+ }; |
200 |
+ const struct old_cmdline * const oldcmd = |
201 |
+- (const struct old_cmdline *)OLD_CL_ADDRESS; |
202 |
++ absolute_pointer(OLD_CL_ADDRESS); |
203 |
+ |
204 |
+ BUILD_BUG_ON(sizeof(boot_params) != 4096); |
205 |
+ memcpy(&boot_params.hdr, &hdr, sizeof(hdr)); |
206 |
+diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c |
207 |
+index b04a6a7bf5669..435dc00d04e5d 100644 |
208 |
+--- a/drivers/net/ethernet/sun/cassini.c |
209 |
++++ b/drivers/net/ethernet/sun/cassini.c |
210 |
+@@ -1313,7 +1313,7 @@ static void cas_init_rx_dma(struct cas *cp) |
211 |
+ writel(val, cp->regs + REG_RX_PAGE_SIZE); |
212 |
+ |
213 |
+ /* enable the header parser if desired */ |
214 |
+- if (CAS_HP_FIRMWARE == cas_prog_null) |
215 |
++ if (&CAS_HP_FIRMWARE[0] == &cas_prog_null[0]) |
216 |
+ return; |
217 |
+ |
218 |
+ val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS); |
219 |
+@@ -3780,7 +3780,7 @@ static void cas_reset(struct cas *cp, int blkflag) |
220 |
+ |
221 |
+ /* program header parser */ |
222 |
+ if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) || |
223 |
+- (CAS_HP_ALT_FIRMWARE == cas_prog_null)) { |
224 |
++ (&CAS_HP_ALT_FIRMWARE[0] == &cas_prog_null[0])) { |
225 |
+ cas_load_firmware(cp, CAS_HP_FIRMWARE); |
226 |
+ } else { |
227 |
+ cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE); |
228 |
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c |
229 |
+index 51fe51bb05041..15e6a6aded319 100644 |
230 |
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c |
231 |
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c |
232 |
+@@ -2386,10 +2386,7 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) |
233 |
+ rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, |
234 |
+ "Just Read IQK Matrix reg for channel:%d....\n", |
235 |
+ channel); |
236 |
+- if ((rtlphy->iqk_matrix[indexforchannel]. |
237 |
+- value[0] != NULL) |
238 |
+- /*&&(regea4 != 0) */) |
239 |
+- _rtl92d_phy_patha_fill_iqk_matrix(hw, true, |
240 |
++ _rtl92d_phy_patha_fill_iqk_matrix(hw, true, |
241 |
+ rtlphy->iqk_matrix[ |
242 |
+ indexforchannel].value, 0, |
243 |
+ (rtlphy->iqk_matrix[ |
244 |
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c b/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c |
245 |
+index c6b032f95d2e4..4627847c6daab 100644 |
246 |
+--- a/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c |
247 |
++++ b/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c |
248 |
+@@ -372,8 +372,6 @@ bool ipc_protocol_dl_td_prepare(struct iosm_protocol *ipc_protocol, |
249 |
+ struct sk_buff *ipc_protocol_dl_td_process(struct iosm_protocol *ipc_protocol, |
250 |
+ struct ipc_pipe *pipe) |
251 |
+ { |
252 |
+- u32 tail = |
253 |
+- le32_to_cpu(ipc_protocol->p_ap_shm->tail_array[pipe->pipe_nr]); |
254 |
+ struct ipc_protocol_td *p_td; |
255 |
+ struct sk_buff *skb; |
256 |
+ |
257 |
+@@ -403,14 +401,6 @@ struct sk_buff *ipc_protocol_dl_td_process(struct iosm_protocol *ipc_protocol, |
258 |
+ goto ret; |
259 |
+ } |
260 |
+ |
261 |
+- if (!IPC_CB(skb)) { |
262 |
+- dev_err(ipc_protocol->dev, "pipe# %d, tail: %d skb_cb is NULL", |
263 |
+- pipe->pipe_nr, tail); |
264 |
+- ipc_pcie_kfree_skb(ipc_protocol->pcie, skb); |
265 |
+- skb = NULL; |
266 |
+- goto ret; |
267 |
+- } |
268 |
+- |
269 |
+ if (p_td->buffer.address != IPC_CB(skb)->mapping) { |
270 |
+ dev_err(ipc_protocol->dev, "invalid buf=%llx or skb=%p", |
271 |
+ (unsigned long long)p_td->buffer.address, skb->data); |
272 |
+diff --git a/fs/io_uring.c b/fs/io_uring.c |
273 |
+index 3d123ca028c97..68aab48838e41 100644 |
274 |
+--- a/fs/io_uring.c |
275 |
++++ b/fs/io_uring.c |
276 |
+@@ -1647,7 +1647,7 @@ static inline void io_req_track_inflight(struct io_kiocb *req) |
277 |
+ { |
278 |
+ if (!(req->flags & REQ_F_INFLIGHT)) { |
279 |
+ req->flags |= REQ_F_INFLIGHT; |
280 |
+- atomic_inc(¤t->io_uring->inflight_tracked); |
281 |
++ atomic_inc(&req->task->io_uring->inflight_tracked); |
282 |
+ } |
283 |
+ } |
284 |
+ |
285 |
+diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c |
286 |
+index 985e995d2a398..4f897e1095470 100644 |
287 |
+--- a/fs/notify/fanotify/fanotify.c |
288 |
++++ b/fs/notify/fanotify/fanotify.c |
289 |
+@@ -319,12 +319,8 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, |
290 |
+ return 0; |
291 |
+ } |
292 |
+ |
293 |
+- fsnotify_foreach_iter_type(type) { |
294 |
+- if (!fsnotify_iter_should_report_type(iter_info, type)) |
295 |
+- continue; |
296 |
+- mark = iter_info->marks[type]; |
297 |
+- |
298 |
+- /* Apply ignore mask regardless of ISDIR and ON_CHILD flags */ |
299 |
++ fsnotify_foreach_iter_mark_type(iter_info, mark, type) { |
300 |
++ /* Apply ignore mask regardless of mark's ISDIR flag */ |
301 |
+ marks_ignored_mask |= mark->ignored_mask; |
302 |
+ |
303 |
+ /* |
304 |
+@@ -334,14 +330,6 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, |
305 |
+ if (event_mask & FS_ISDIR && !(mark->mask & FS_ISDIR)) |
306 |
+ continue; |
307 |
+ |
308 |
+- /* |
309 |
+- * If the event is on a child and this mark is on a parent not |
310 |
+- * watching children, don't send it! |
311 |
+- */ |
312 |
+- if (type == FSNOTIFY_ITER_TYPE_PARENT && |
313 |
+- !(mark->mask & FS_EVENT_ON_CHILD)) |
314 |
+- continue; |
315 |
+- |
316 |
+ marks_mask |= mark->mask; |
317 |
+ |
318 |
+ /* Record the mark types of this group that matched the event */ |
319 |
+@@ -849,16 +837,14 @@ out: |
320 |
+ */ |
321 |
+ static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info) |
322 |
+ { |
323 |
++ struct fsnotify_mark *mark; |
324 |
+ int type; |
325 |
+ __kernel_fsid_t fsid = {}; |
326 |
+ |
327 |
+- fsnotify_foreach_iter_type(type) { |
328 |
++ fsnotify_foreach_iter_mark_type(iter_info, mark, type) { |
329 |
+ struct fsnotify_mark_connector *conn; |
330 |
+ |
331 |
+- if (!fsnotify_iter_should_report_type(iter_info, type)) |
332 |
+- continue; |
333 |
+- |
334 |
+- conn = READ_ONCE(iter_info->marks[type]->connector); |
335 |
++ conn = READ_ONCE(mark->connector); |
336 |
+ /* Mark is just getting destroyed or created? */ |
337 |
+ if (!conn) |
338 |
+ continue; |
339 |
+diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c |
340 |
+index 70a8516b78bc5..6d63423cd4928 100644 |
341 |
+--- a/fs/notify/fsnotify.c |
342 |
++++ b/fs/notify/fsnotify.c |
343 |
+@@ -290,22 +290,15 @@ static int fsnotify_handle_event(struct fsnotify_group *group, __u32 mask, |
344 |
+ } |
345 |
+ |
346 |
+ if (parent_mark) { |
347 |
+- /* |
348 |
+- * parent_mark indicates that the parent inode is watching |
349 |
+- * children and interested in this event, which is an event |
350 |
+- * possible on child. But is *this mark* watching children and |
351 |
+- * interested in this event? |
352 |
+- */ |
353 |
+- if (parent_mark->mask & FS_EVENT_ON_CHILD) { |
354 |
+- ret = fsnotify_handle_inode_event(group, parent_mark, mask, |
355 |
+- data, data_type, dir, name, 0); |
356 |
+- if (ret) |
357 |
+- return ret; |
358 |
+- } |
359 |
+- if (!inode_mark) |
360 |
+- return 0; |
361 |
++ ret = fsnotify_handle_inode_event(group, parent_mark, mask, |
362 |
++ data, data_type, dir, name, 0); |
363 |
++ if (ret) |
364 |
++ return ret; |
365 |
+ } |
366 |
+ |
367 |
++ if (!inode_mark) |
368 |
++ return 0; |
369 |
++ |
370 |
+ if (mask & FS_EVENT_ON_CHILD) { |
371 |
+ /* |
372 |
+ * Some events can be sent on both parent dir and child marks |
373 |
+@@ -335,31 +328,23 @@ static int send_to_group(__u32 mask, const void *data, int data_type, |
374 |
+ struct fsnotify_mark *mark; |
375 |
+ int type; |
376 |
+ |
377 |
+- if (WARN_ON(!iter_info->report_mask)) |
378 |
++ if (!iter_info->report_mask) |
379 |
+ return 0; |
380 |
+ |
381 |
+ /* clear ignored on inode modification */ |
382 |
+ if (mask & FS_MODIFY) { |
383 |
+- fsnotify_foreach_iter_type(type) { |
384 |
+- if (!fsnotify_iter_should_report_type(iter_info, type)) |
385 |
+- continue; |
386 |
+- mark = iter_info->marks[type]; |
387 |
+- if (mark && |
388 |
+- !(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) |
389 |
++ fsnotify_foreach_iter_mark_type(iter_info, mark, type) { |
390 |
++ if (!(mark->flags & |
391 |
++ FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) |
392 |
+ mark->ignored_mask = 0; |
393 |
+ } |
394 |
+ } |
395 |
+ |
396 |
+- fsnotify_foreach_iter_type(type) { |
397 |
+- if (!fsnotify_iter_should_report_type(iter_info, type)) |
398 |
+- continue; |
399 |
+- mark = iter_info->marks[type]; |
400 |
+- /* does the object mark tell us to do something? */ |
401 |
+- if (mark) { |
402 |
+- group = mark->group; |
403 |
+- marks_mask |= mark->mask; |
404 |
+- marks_ignored_mask |= mark->ignored_mask; |
405 |
+- } |
406 |
++ /* Are any of the group marks interested in this event? */ |
407 |
++ fsnotify_foreach_iter_mark_type(iter_info, mark, type) { |
408 |
++ group = mark->group; |
409 |
++ marks_mask |= mark->mask; |
410 |
++ marks_ignored_mask |= mark->ignored_mask; |
411 |
+ } |
412 |
+ |
413 |
+ pr_debug("%s: group=%p mask=%x marks_mask=%x marks_ignored_mask=%x data=%p data_type=%d dir=%p cookie=%d\n", |
414 |
+@@ -403,11 +388,11 @@ static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark) |
415 |
+ |
416 |
+ /* |
417 |
+ * iter_info is a multi head priority queue of marks. |
418 |
+- * Pick a subset of marks from queue heads, all with the |
419 |
+- * same group and set the report_mask for selected subset. |
420 |
+- * Returns the report_mask of the selected subset. |
421 |
++ * Pick a subset of marks from queue heads, all with the same group |
422 |
++ * and set the report_mask to a subset of the selected marks. |
423 |
++ * Returns false if there are no more groups to iterate. |
424 |
+ */ |
425 |
+-static unsigned int fsnotify_iter_select_report_types( |
426 |
++static bool fsnotify_iter_select_report_types( |
427 |
+ struct fsnotify_iter_info *iter_info) |
428 |
+ { |
429 |
+ struct fsnotify_group *max_prio_group = NULL; |
430 |
+@@ -423,30 +408,48 @@ static unsigned int fsnotify_iter_select_report_types( |
431 |
+ } |
432 |
+ |
433 |
+ if (!max_prio_group) |
434 |
+- return 0; |
435 |
++ return false; |
436 |
+ |
437 |
+ /* Set the report mask for marks from same group as max prio group */ |
438 |
++ iter_info->current_group = max_prio_group; |
439 |
+ iter_info->report_mask = 0; |
440 |
+ fsnotify_foreach_iter_type(type) { |
441 |
+ mark = iter_info->marks[type]; |
442 |
+- if (mark && |
443 |
+- fsnotify_compare_groups(max_prio_group, mark->group) == 0) |
444 |
++ if (mark && mark->group == iter_info->current_group) { |
445 |
++ /* |
446 |
++ * FSNOTIFY_ITER_TYPE_PARENT indicates that this inode |
447 |
++ * is watching children and interested in this event, |
448 |
++ * which is an event possible on child. |
449 |
++ * But is *this mark* watching children? |
450 |
++ */ |
451 |
++ if (type == FSNOTIFY_ITER_TYPE_PARENT && |
452 |
++ !(mark->mask & FS_EVENT_ON_CHILD)) |
453 |
++ continue; |
454 |
++ |
455 |
+ fsnotify_iter_set_report_type(iter_info, type); |
456 |
++ } |
457 |
+ } |
458 |
+ |
459 |
+- return iter_info->report_mask; |
460 |
++ return true; |
461 |
+ } |
462 |
+ |
463 |
+ /* |
464 |
+- * Pop from iter_info multi head queue, the marks that were iterated in the |
465 |
++ * Pop from iter_info multi head queue, the marks that belong to the group of |
466 |
+ * current iteration step. |
467 |
+ */ |
468 |
+ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info) |
469 |
+ { |
470 |
++ struct fsnotify_mark *mark; |
471 |
+ int type; |
472 |
+ |
473 |
++ /* |
474 |
++ * We cannot use fsnotify_foreach_iter_mark_type() here because we |
475 |
++ * may need to advance a mark of type X that belongs to current_group |
476 |
++ * but was not selected for reporting. |
477 |
++ */ |
478 |
+ fsnotify_foreach_iter_type(type) { |
479 |
+- if (fsnotify_iter_should_report_type(iter_info, type)) |
480 |
++ mark = iter_info->marks[type]; |
481 |
++ if (mark && mark->group == iter_info->current_group) |
482 |
+ iter_info->marks[type] = |
483 |
+ fsnotify_next_mark(iter_info->marks[type]); |
484 |
+ } |
485 |
+diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c |
486 |
+index 1c2ece9611287..15a4c7c07a3bf 100644 |
487 |
+--- a/fs/zonefs/super.c |
488 |
++++ b/fs/zonefs/super.c |
489 |
+@@ -72,15 +72,51 @@ static inline void zonefs_i_size_write(struct inode *inode, loff_t isize) |
490 |
+ zi->i_flags &= ~ZONEFS_ZONE_OPEN; |
491 |
+ } |
492 |
+ |
493 |
+-static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, |
494 |
+- unsigned int flags, struct iomap *iomap, |
495 |
+- struct iomap *srcmap) |
496 |
++static int zonefs_read_iomap_begin(struct inode *inode, loff_t offset, |
497 |
++ loff_t length, unsigned int flags, |
498 |
++ struct iomap *iomap, struct iomap *srcmap) |
499 |
+ { |
500 |
+ struct zonefs_inode_info *zi = ZONEFS_I(inode); |
501 |
+ struct super_block *sb = inode->i_sb; |
502 |
+ loff_t isize; |
503 |
+ |
504 |
+- /* All I/Os should always be within the file maximum size */ |
505 |
++ /* |
506 |
++ * All blocks are always mapped below EOF. If reading past EOF, |
507 |
++ * act as if there is a hole up to the file maximum size. |
508 |
++ */ |
509 |
++ mutex_lock(&zi->i_truncate_mutex); |
510 |
++ iomap->bdev = inode->i_sb->s_bdev; |
511 |
++ iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize); |
512 |
++ isize = i_size_read(inode); |
513 |
++ if (iomap->offset >= isize) { |
514 |
++ iomap->type = IOMAP_HOLE; |
515 |
++ iomap->addr = IOMAP_NULL_ADDR; |
516 |
++ iomap->length = length; |
517 |
++ } else { |
518 |
++ iomap->type = IOMAP_MAPPED; |
519 |
++ iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset; |
520 |
++ iomap->length = isize - iomap->offset; |
521 |
++ } |
522 |
++ mutex_unlock(&zi->i_truncate_mutex); |
523 |
++ |
524 |
++ trace_zonefs_iomap_begin(inode, iomap); |
525 |
++ |
526 |
++ return 0; |
527 |
++} |
528 |
++ |
529 |
++static const struct iomap_ops zonefs_read_iomap_ops = { |
530 |
++ .iomap_begin = zonefs_read_iomap_begin, |
531 |
++}; |
532 |
++ |
533 |
++static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset, |
534 |
++ loff_t length, unsigned int flags, |
535 |
++ struct iomap *iomap, struct iomap *srcmap) |
536 |
++{ |
537 |
++ struct zonefs_inode_info *zi = ZONEFS_I(inode); |
538 |
++ struct super_block *sb = inode->i_sb; |
539 |
++ loff_t isize; |
540 |
++ |
541 |
++ /* All write I/Os should always be within the file maximum size */ |
542 |
+ if (WARN_ON_ONCE(offset + length > zi->i_max_size)) |
543 |
+ return -EIO; |
544 |
+ |
545 |
+@@ -90,7 +126,7 @@ static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, |
546 |
+ * operation. |
547 |
+ */ |
548 |
+ if (WARN_ON_ONCE(zi->i_ztype == ZONEFS_ZTYPE_SEQ && |
549 |
+- (flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT))) |
550 |
++ !(flags & IOMAP_DIRECT))) |
551 |
+ return -EIO; |
552 |
+ |
553 |
+ /* |
554 |
+@@ -99,47 +135,44 @@ static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, |
555 |
+ * write pointer) and unwriten beyond. |
556 |
+ */ |
557 |
+ mutex_lock(&zi->i_truncate_mutex); |
558 |
++ iomap->bdev = inode->i_sb->s_bdev; |
559 |
++ iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize); |
560 |
++ iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset; |
561 |
+ isize = i_size_read(inode); |
562 |
+- if (offset >= isize) |
563 |
++ if (iomap->offset >= isize) { |
564 |
+ iomap->type = IOMAP_UNWRITTEN; |
565 |
+- else |
566 |
++ iomap->length = zi->i_max_size - iomap->offset; |
567 |
++ } else { |
568 |
+ iomap->type = IOMAP_MAPPED; |
569 |
+- if (flags & IOMAP_WRITE) |
570 |
+- length = zi->i_max_size - offset; |
571 |
+- else |
572 |
+- length = min(length, isize - offset); |
573 |
++ iomap->length = isize - iomap->offset; |
574 |
++ } |
575 |
+ mutex_unlock(&zi->i_truncate_mutex); |
576 |
+ |
577 |
+- iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize); |
578 |
+- iomap->length = ALIGN(offset + length, sb->s_blocksize) - iomap->offset; |
579 |
+- iomap->bdev = inode->i_sb->s_bdev; |
580 |
+- iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset; |
581 |
+- |
582 |
+ trace_zonefs_iomap_begin(inode, iomap); |
583 |
+ |
584 |
+ return 0; |
585 |
+ } |
586 |
+ |
587 |
+-static const struct iomap_ops zonefs_iomap_ops = { |
588 |
+- .iomap_begin = zonefs_iomap_begin, |
589 |
++static const struct iomap_ops zonefs_write_iomap_ops = { |
590 |
++ .iomap_begin = zonefs_write_iomap_begin, |
591 |
+ }; |
592 |
+ |
593 |
+ static int zonefs_readpage(struct file *unused, struct page *page) |
594 |
+ { |
595 |
+- return iomap_readpage(page, &zonefs_iomap_ops); |
596 |
++ return iomap_readpage(page, &zonefs_read_iomap_ops); |
597 |
+ } |
598 |
+ |
599 |
+ static void zonefs_readahead(struct readahead_control *rac) |
600 |
+ { |
601 |
+- iomap_readahead(rac, &zonefs_iomap_ops); |
602 |
++ iomap_readahead(rac, &zonefs_read_iomap_ops); |
603 |
+ } |
604 |
+ |
605 |
+ /* |
606 |
+ * Map blocks for page writeback. This is used only on conventional zone files, |
607 |
+ * which implies that the page range can only be within the fixed inode size. |
608 |
+ */ |
609 |
+-static int zonefs_map_blocks(struct iomap_writepage_ctx *wpc, |
610 |
+- struct inode *inode, loff_t offset) |
611 |
++static int zonefs_write_map_blocks(struct iomap_writepage_ctx *wpc, |
612 |
++ struct inode *inode, loff_t offset) |
613 |
+ { |
614 |
+ struct zonefs_inode_info *zi = ZONEFS_I(inode); |
615 |
+ |
616 |
+@@ -153,12 +186,12 @@ static int zonefs_map_blocks(struct iomap_writepage_ctx *wpc, |
617 |
+ offset < wpc->iomap.offset + wpc->iomap.length) |
618 |
+ return 0; |
619 |
+ |
620 |
+- return zonefs_iomap_begin(inode, offset, zi->i_max_size - offset, |
621 |
+- IOMAP_WRITE, &wpc->iomap, NULL); |
622 |
++ return zonefs_write_iomap_begin(inode, offset, zi->i_max_size - offset, |
623 |
++ IOMAP_WRITE, &wpc->iomap, NULL); |
624 |
+ } |
625 |
+ |
626 |
+ static const struct iomap_writeback_ops zonefs_writeback_ops = { |
627 |
+- .map_blocks = zonefs_map_blocks, |
628 |
++ .map_blocks = zonefs_write_map_blocks, |
629 |
+ }; |
630 |
+ |
631 |
+ static int zonefs_writepage(struct page *page, struct writeback_control *wbc) |
632 |
+@@ -188,7 +221,8 @@ static int zonefs_swap_activate(struct swap_info_struct *sis, |
633 |
+ return -EINVAL; |
634 |
+ } |
635 |
+ |
636 |
+- return iomap_swapfile_activate(sis, swap_file, span, &zonefs_iomap_ops); |
637 |
++ return iomap_swapfile_activate(sis, swap_file, span, |
638 |
++ &zonefs_read_iomap_ops); |
639 |
+ } |
640 |
+ |
641 |
+ static const struct address_space_operations zonefs_file_aops = { |
642 |
+@@ -607,7 +641,7 @@ static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf) |
643 |
+ |
644 |
+ /* Serialize against truncates */ |
645 |
+ filemap_invalidate_lock_shared(inode->i_mapping); |
646 |
+- ret = iomap_page_mkwrite(vmf, &zonefs_iomap_ops); |
647 |
++ ret = iomap_page_mkwrite(vmf, &zonefs_write_iomap_ops); |
648 |
+ filemap_invalidate_unlock_shared(inode->i_mapping); |
649 |
+ |
650 |
+ sb_end_pagefault(inode->i_sb); |
651 |
+@@ -860,7 +894,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) |
652 |
+ if (append) |
653 |
+ ret = zonefs_file_dio_append(iocb, from); |
654 |
+ else |
655 |
+- ret = iomap_dio_rw(iocb, from, &zonefs_iomap_ops, |
656 |
++ ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops, |
657 |
+ &zonefs_write_dio_ops, 0, 0); |
658 |
+ if (zi->i_ztype == ZONEFS_ZTYPE_SEQ && |
659 |
+ (ret > 0 || ret == -EIOCBQUEUED)) { |
660 |
+@@ -902,7 +936,7 @@ static ssize_t zonefs_file_buffered_write(struct kiocb *iocb, |
661 |
+ if (ret <= 0) |
662 |
+ goto inode_unlock; |
663 |
+ |
664 |
+- ret = iomap_file_buffered_write(iocb, from, &zonefs_iomap_ops); |
665 |
++ ret = iomap_file_buffered_write(iocb, from, &zonefs_write_iomap_ops); |
666 |
+ if (ret > 0) |
667 |
+ iocb->ki_pos += ret; |
668 |
+ else if (ret == -EIO) |
669 |
+@@ -995,7 +1029,7 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) |
670 |
+ goto inode_unlock; |
671 |
+ } |
672 |
+ file_accessed(iocb->ki_filp); |
673 |
+- ret = iomap_dio_rw(iocb, to, &zonefs_iomap_ops, |
674 |
++ ret = iomap_dio_rw(iocb, to, &zonefs_read_iomap_ops, |
675 |
+ &zonefs_read_dio_ops, 0, 0); |
676 |
+ } else { |
677 |
+ ret = generic_file_read_iter(iocb, to); |
678 |
+diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h |
679 |
+index 0805b74cae441..beb9c99fea07d 100644 |
680 |
+--- a/include/linux/fsnotify_backend.h |
681 |
++++ b/include/linux/fsnotify_backend.h |
682 |
+@@ -370,6 +370,7 @@ static inline bool fsnotify_valid_obj_type(unsigned int obj_type) |
683 |
+ |
684 |
+ struct fsnotify_iter_info { |
685 |
+ struct fsnotify_mark *marks[FSNOTIFY_ITER_TYPE_COUNT]; |
686 |
++ struct fsnotify_group *current_group; |
687 |
+ unsigned int report_mask; |
688 |
+ int srcu_idx; |
689 |
+ }; |
690 |
+@@ -386,20 +387,31 @@ static inline void fsnotify_iter_set_report_type( |
691 |
+ iter_info->report_mask |= (1U << iter_type); |
692 |
+ } |
693 |
+ |
694 |
+-static inline void fsnotify_iter_set_report_type_mark( |
695 |
+- struct fsnotify_iter_info *iter_info, int iter_type, |
696 |
+- struct fsnotify_mark *mark) |
697 |
++static inline struct fsnotify_mark *fsnotify_iter_mark( |
698 |
++ struct fsnotify_iter_info *iter_info, int iter_type) |
699 |
+ { |
700 |
+- iter_info->marks[iter_type] = mark; |
701 |
+- iter_info->report_mask |= (1U << iter_type); |
702 |
++ if (fsnotify_iter_should_report_type(iter_info, iter_type)) |
703 |
++ return iter_info->marks[iter_type]; |
704 |
++ return NULL; |
705 |
++} |
706 |
++ |
707 |
++static inline int fsnotify_iter_step(struct fsnotify_iter_info *iter, int type, |
708 |
++ struct fsnotify_mark **markp) |
709 |
++{ |
710 |
++ while (type < FSNOTIFY_ITER_TYPE_COUNT) { |
711 |
++ *markp = fsnotify_iter_mark(iter, type); |
712 |
++ if (*markp) |
713 |
++ break; |
714 |
++ type++; |
715 |
++ } |
716 |
++ return type; |
717 |
+ } |
718 |
+ |
719 |
+ #define FSNOTIFY_ITER_FUNCS(name, NAME) \ |
720 |
+ static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \ |
721 |
+ struct fsnotify_iter_info *iter_info) \ |
722 |
+ { \ |
723 |
+- return (iter_info->report_mask & (1U << FSNOTIFY_ITER_TYPE_##NAME)) ? \ |
724 |
+- iter_info->marks[FSNOTIFY_ITER_TYPE_##NAME] : NULL; \ |
725 |
++ return fsnotify_iter_mark(iter_info, FSNOTIFY_ITER_TYPE_##NAME); \ |
726 |
+ } |
727 |
+ |
728 |
+ FSNOTIFY_ITER_FUNCS(inode, INODE) |
729 |
+@@ -409,6 +421,11 @@ FSNOTIFY_ITER_FUNCS(sb, SB) |
730 |
+ |
731 |
+ #define fsnotify_foreach_iter_type(type) \ |
732 |
+ for (type = 0; type < FSNOTIFY_ITER_TYPE_COUNT; type++) |
733 |
++#define fsnotify_foreach_iter_mark_type(iter, mark, type) \ |
734 |
++ for (type = 0; \ |
735 |
++ type = fsnotify_iter_step(iter, type, &mark), \ |
736 |
++ type < FSNOTIFY_ITER_TYPE_COUNT; \ |
737 |
++ type++) |
738 |
+ |
739 |
+ /* |
740 |
+ * fsnotify_connp_t is what we embed in objects which connector can be attached |
741 |
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c |
742 |
+index 0918a39279f6c..feef799884d1f 100644 |
743 |
+--- a/kernel/bpf/btf.c |
744 |
++++ b/kernel/bpf/btf.c |
745 |
+@@ -5769,6 +5769,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, |
746 |
+ struct bpf_reg_state *regs, |
747 |
+ bool ptr_to_mem_ok) |
748 |
+ { |
749 |
++ enum bpf_prog_type prog_type = resolve_prog_type(env->prog); |
750 |
+ struct bpf_verifier_log *log = &env->log; |
751 |
+ u32 i, nargs, ref_id, ref_obj_id = 0; |
752 |
+ bool is_kfunc = btf_is_kernel(btf); |
753 |
+@@ -5834,8 +5835,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, |
754 |
+ if (ret < 0) |
755 |
+ return ret; |
756 |
+ |
757 |
+- if (btf_get_prog_ctx_type(log, btf, t, |
758 |
+- env->prog->type, i)) { |
759 |
++ if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) { |
760 |
+ /* If function expects ctx type in BTF check that caller |
761 |
+ * is passing PTR_TO_CTX. |
762 |
+ */ |
763 |
+diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c |
764 |
+index d9aad15e0d242..02bb8cbf91949 100644 |
765 |
+--- a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c |
766 |
++++ b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c |
767 |
+@@ -395,6 +395,18 @@ static void test_func_map_prog_compatibility(void) |
768 |
+ "./test_attach_probe.o"); |
769 |
+ } |
770 |
+ |
771 |
++static void test_func_replace_global_func(void) |
772 |
++{ |
773 |
++ const char *prog_name[] = { |
774 |
++ "freplace/test_pkt_access", |
775 |
++ }; |
776 |
++ |
777 |
++ test_fexit_bpf2bpf_common("./freplace_global_func.o", |
778 |
++ "./test_pkt_access.o", |
779 |
++ ARRAY_SIZE(prog_name), |
780 |
++ prog_name, false, NULL); |
781 |
++} |
782 |
++ |
783 |
+ /* NOTE: affect other tests, must run in serial mode */ |
784 |
+ void serial_test_fexit_bpf2bpf(void) |
785 |
+ { |
786 |
+@@ -416,4 +428,6 @@ void serial_test_fexit_bpf2bpf(void) |
787 |
+ test_func_replace_multi(); |
788 |
+ if (test__start_subtest("fmod_ret_freplace")) |
789 |
+ test_fmod_ret_freplace(); |
790 |
++ if (test__start_subtest("func_replace_global_func")) |
791 |
++ test_func_replace_global_func(); |
792 |
+ } |
793 |
+diff --git a/tools/testing/selftests/bpf/progs/freplace_global_func.c b/tools/testing/selftests/bpf/progs/freplace_global_func.c |
794 |
+new file mode 100644 |
795 |
+index 0000000000000..96cb61a6ce87a |
796 |
+--- /dev/null |
797 |
++++ b/tools/testing/selftests/bpf/progs/freplace_global_func.c |
798 |
+@@ -0,0 +1,18 @@ |
799 |
++// SPDX-License-Identifier: GPL-2.0 |
800 |
++#include <linux/bpf.h> |
801 |
++#include <bpf/bpf_helpers.h> |
802 |
++ |
803 |
++__noinline |
804 |
++int test_ctx_global_func(struct __sk_buff *skb) |
805 |
++{ |
806 |
++ volatile int retval = 1; |
807 |
++ return retval; |
808 |
++} |
809 |
++ |
810 |
++SEC("freplace/test_pkt_access") |
811 |
++int new_test_pkt_access(struct __sk_buff *skb) |
812 |
++{ |
813 |
++ return test_ctx_global_func(skb); |
814 |
++} |
815 |
++ |
816 |
++char _license[] SEC("license") = "GPL"; |