From: Greg Kroah-Hartman Date: Mon, 29 Jul 2024 12:44:15 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.1.103~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7fd27ea14a92e50c29f64998fd36c1ed825296b4;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch binder-fix-hang-of-unregistered-readers.patch dev-parport-fix-the-array-out-of-bounds-risk.patch efi-libstub-zero-initialize-heap-allocated-struct-screen_info.patch f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch f2fs-use-meta-inode-for-gc-of-atomic-file.patch f2fs-use-meta-inode-for-gc-of-cow-file.patch fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch hostfs-fix-dev_t-handling.patch hwrng-amd-convert-pcibios_-return-codes-to-errnos.patch nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch parisc-fix-warning-at-drivers-pci-msi-msi.h-121.patch pci-dw-rockchip-fix-initial-perst-gpio-value.patch pci-hv-return-zero-not-garbage-when-reading-pci_interrupt_pin.patch pci-loongson-enable-msi-in-ls7a-root-complex.patch pci-rockchip-use-gpiod_out_low-flag-while-requesting-ep_gpio.patch scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch tools-memory-model-fix-bug-in-lock.cat.patch --- diff --git a/queue-6.6/asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch b/queue-6.6/asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch new file mode 100644 index 00000000000..6f15c775e1d --- /dev/null +++ b/queue-6.6/asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch @@ -0,0 +1,40 @@ +From e62599902327d27687693f6e5253a5d56583db58 Mon Sep 17 00:00:00 2001 +From: Herve Codina +Date: Mon, 1 Jul 2024 13:30:28 +0200 +Subject: ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value + +From: Herve Codina + +commit e62599902327d27687693f6e5253a5d56583db58 upstream. + +devm_kasprintf() can return a NULL pointer on failure but this returned +value is not checked. + +Fix this lack and check the returned value. + +Fixes: 075c7125b11c ("ASoC: fsl: Add support for QMC audio") +Cc: stable@vger.kernel.org +Signed-off-by: Herve Codina +Link: https://patch.msgid.link/20240701113038.55144-2-herve.codina@bootlin.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/fsl/fsl_qmc_audio.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c +index bfaaa451735b..dd90ef16fa97 100644 +--- a/sound/soc/fsl/fsl_qmc_audio.c ++++ b/sound/soc/fsl/fsl_qmc_audio.c +@@ -604,6 +604,8 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node * + + qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d", + np->parent->name, qmc_dai->id); ++ if (!qmc_dai->name) ++ return -ENOMEM; + + qmc_dai->qmc_chan = devm_qmc_chan_get_byphandle(qmc_audio->dev, np, + "fsl,qmc-chan"); +-- +2.45.2 + diff --git a/queue-6.6/binder-fix-hang-of-unregistered-readers.patch b/queue-6.6/binder-fix-hang-of-unregistered-readers.patch new file mode 100644 index 00000000000..45280480fdd --- /dev/null +++ b/queue-6.6/binder-fix-hang-of-unregistered-readers.patch @@ -0,0 +1,51 @@ +From 31643d84b8c3d9c846aa0e20bc033e46c68c7e7d Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 11 Jul 2024 20:14:51 +0000 +Subject: binder: fix hang of unregistered readers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Carlos Llamas + +commit 31643d84b8c3d9c846aa0e20bc033e46c68c7e7d upstream. + +With the introduction of binder_available_for_proc_work_ilocked() in +commit 1b77e9dcc3da ("ANDROID: binder: remove proc waitqueue") a binder +thread can only "wait_for_proc_work" after its thread->looper has been +marked as BINDER_LOOPER_STATE_{ENTERED|REGISTERED}. + +This means an unregistered reader risks waiting indefinitely for work +since it never gets added to the proc->waiting_threads. If there are no +further references to its waitqueue either the task will hang. The same +applies to readers using the (e)poll interface. + +I couldn't find the rationale behind this restriction. So this patch +restores the previous behavior of allowing unregistered threads to +"wait_for_proc_work". Note that an error message for this scenario, +which had previously become unreachable, is now re-enabled. + +Fixes: 1b77e9dcc3da ("ANDROID: binder: remove proc waitqueue") +Cc: stable@vger.kernel.org +Cc: Martijn Coenen +Cc: Arve Hjønnevåg +Signed-off-by: Carlos Llamas +Link: https://lore.kernel.org/r/20240711201452.2017543-1-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -570,9 +570,7 @@ static bool binder_has_work(struct binde + static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread) + { + return !thread->transaction_stack && +- binder_worklist_empty_ilocked(&thread->todo) && +- (thread->looper & (BINDER_LOOPER_STATE_ENTERED | +- BINDER_LOOPER_STATE_REGISTERED)); ++ binder_worklist_empty_ilocked(&thread->todo); + } + + static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc, diff --git a/queue-6.6/dev-parport-fix-the-array-out-of-bounds-risk.patch b/queue-6.6/dev-parport-fix-the-array-out-of-bounds-risk.patch new file mode 100644 index 00000000000..c06616de8ac --- /dev/null +++ b/queue-6.6/dev-parport-fix-the-array-out-of-bounds-risk.patch @@ -0,0 +1,125 @@ +From ab11dac93d2d568d151b1918d7b84c2d02bacbd5 Mon Sep 17 00:00:00 2001 +From: tuhaowen +Date: Mon, 8 Jul 2024 16:04:30 +0800 +Subject: dev/parport: fix the array out-of-bounds risk + +From: tuhaowen + +commit ab11dac93d2d568d151b1918d7b84c2d02bacbd5 upstream. + +Fixed array out-of-bounds issues caused by sprintf +by replacing it with snprintf for safer data copying, +ensuring the destination buffer is not overflowed. + +Below is the stack trace I encountered during the actual issue: + +[ 66.575408s] [pid:5118,cpu4,QThread,4]Kernel panic - not syncing: stack-protector: +Kernel stack is corrupted in: do_hardware_base_addr+0xcc/0xd0 [parport] +[ 66.575408s] [pid:5118,cpu4,QThread,5]CPU: 4 PID: 5118 Comm: +QThread Tainted: G S W O 5.10.97-arm64-desktop #7100.57021.2 +[ 66.575439s] [pid:5118,cpu4,QThread,6]TGID: 5087 Comm: EFileApp +[ 66.575439s] [pid:5118,cpu4,QThread,7]Hardware name: HUAWEI HUAWEI QingYun +PGUX-W515x-B081/SP1PANGUXM, BIOS 1.00.07 04/29/2024 +[ 66.575439s] [pid:5118,cpu4,QThread,8]Call trace: +[ 66.575469s] [pid:5118,cpu4,QThread,9] dump_backtrace+0x0/0x1c0 +[ 66.575469s] [pid:5118,cpu4,QThread,0] show_stack+0x14/0x20 +[ 66.575469s] [pid:5118,cpu4,QThread,1] dump_stack+0xd4/0x10c +[ 66.575500s] [pid:5118,cpu4,QThread,2] panic+0x1d8/0x3bc +[ 66.575500s] [pid:5118,cpu4,QThread,3] __stack_chk_fail+0x2c/0x38 +[ 66.575500s] [pid:5118,cpu4,QThread,4] do_hardware_base_addr+0xcc/0xd0 [parport] + +Signed-off-by: tuhaowen +Cc: stable +Link: https://lore.kernel.org/r/20240708080430.8221-1-tuhaowen@uniontech.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/parport/procfs.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/parport/procfs.c ++++ b/drivers/parport/procfs.c +@@ -58,12 +58,12 @@ static int do_active_device(struct ctl_t + + for (dev = port->devices; dev ; dev = dev->next) { + if(dev == port->cad) { +- len += sprintf(buffer, "%s\n", dev->name); ++ len += snprintf(buffer, sizeof(buffer), "%s\n", dev->name); + } + } + + if(!len) { +- len += sprintf(buffer, "%s\n", "none"); ++ len += snprintf(buffer, sizeof(buffer), "%s\n", "none"); + } + + if (len > *lenp) +@@ -94,19 +94,19 @@ static int do_autoprobe(struct ctl_table + } + + if ((str = info->class_name) != NULL) +- len += sprintf (buffer + len, "CLASS:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); + + if ((str = info->model) != NULL) +- len += sprintf (buffer + len, "MODEL:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); + + if ((str = info->mfr) != NULL) +- len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); + + if ((str = info->description) != NULL) +- len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); + + if ((str = info->cmdset) != NULL) +- len += sprintf (buffer + len, "COMMAND SET:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); + + if (len > *lenp) + len = *lenp; +@@ -124,7 +124,7 @@ static int do_hardware_base_addr(struct + void *result, size_t *lenp, loff_t *ppos) + { + struct parport *port = (struct parport *)table->extra1; +- char buffer[20]; ++ char buffer[64]; + int len = 0; + + if (*ppos) { +@@ -135,7 +135,7 @@ static int do_hardware_base_addr(struct + if (write) /* permissions prevent this anyway */ + return -EACCES; + +- len += sprintf (buffer, "%lu\t%lu\n", port->base, port->base_hi); ++ len += snprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); + + if (len > *lenp) + len = *lenp; +@@ -162,7 +162,7 @@ static int do_hardware_irq(struct ctl_ta + if (write) /* permissions prevent this anyway */ + return -EACCES; + +- len += sprintf (buffer, "%d\n", port->irq); ++ len += snprintf (buffer, sizeof(buffer), "%d\n", port->irq); + + if (len > *lenp) + len = *lenp; +@@ -189,7 +189,7 @@ static int do_hardware_dma(struct ctl_ta + if (write) /* permissions prevent this anyway */ + return -EACCES; + +- len += sprintf (buffer, "%d\n", port->dma); ++ len += snprintf (buffer, sizeof(buffer), "%d\n", port->dma); + + if (len > *lenp) + len = *lenp; +@@ -220,7 +220,7 @@ static int do_hardware_modes(struct ctl_ + #define printmode(x) \ + do { \ + if (port->modes & PARPORT_MODE_##x) \ +- len += sprintf(buffer + len, "%s%s", f++ ? "," : "", #x); \ ++ len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ + } while (0) + int f = 0; + printmode(PCSPP); diff --git a/queue-6.6/efi-libstub-zero-initialize-heap-allocated-struct-screen_info.patch b/queue-6.6/efi-libstub-zero-initialize-heap-allocated-struct-screen_info.patch new file mode 100644 index 00000000000..8f0e77fe74e --- /dev/null +++ b/queue-6.6/efi-libstub-zero-initialize-heap-allocated-struct-screen_info.patch @@ -0,0 +1,32 @@ +From ee8b8f5d83eb2c9caaebcf633310905ee76856e9 Mon Sep 17 00:00:00 2001 +From: Qiang Ma +Date: Wed, 17 Jul 2024 15:00:43 +0800 +Subject: efi/libstub: Zero initialize heap allocated struct screen_info + +From: Qiang Ma + +commit ee8b8f5d83eb2c9caaebcf633310905ee76856e9 upstream. + +After calling uefi interface allocate_pool to apply for memory, we +should clear 0 to prevent the possibility of using random values. + +Signed-off-by: Qiang Ma +Cc: # v6.6+ +Fixes: 732ea9db9d8a ("efi: libstub: Move screen_info handling to common code") +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/libstub/screen_info.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/firmware/efi/libstub/screen_info.c ++++ b/drivers/firmware/efi/libstub/screen_info.c +@@ -32,6 +32,8 @@ struct screen_info *__alloc_screen_info( + if (status != EFI_SUCCESS) + return NULL; + ++ memset(si, 0, sizeof(*si)); ++ + status = efi_bs_call(install_configuration_table, + &screen_info_guid, si); + if (status == EFI_SUCCESS) diff --git a/queue-6.6/f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch b/queue-6.6/f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch new file mode 100644 index 00000000000..cdb828bbceb --- /dev/null +++ b/queue-6.6/f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch @@ -0,0 +1,58 @@ +From a8eb3de28e7a365690c61161e7a07a4fc7c60bbf Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Mon, 3 Jun 2024 09:07:45 +0800 +Subject: f2fs: fix return value of f2fs_convert_inline_inode() + +From: Chao Yu + +commit a8eb3de28e7a365690c61161e7a07a4fc7c60bbf upstream. + +If device is readonly, make f2fs_convert_inline_inode() +return EROFS instead of zero, otherwise it may trigger +panic during writeback of inline inode's dirty page as +below: + + f2fs_write_single_data_page+0xbb6/0x1e90 fs/f2fs/data.c:2888 + f2fs_write_cache_pages fs/f2fs/data.c:3187 [inline] + __f2fs_write_data_pages fs/f2fs/data.c:3342 [inline] + f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3369 + do_writepages+0x359/0x870 mm/page-writeback.c:2634 + filemap_fdatawrite_wbc+0x125/0x180 mm/filemap.c:397 + __filemap_fdatawrite_range mm/filemap.c:430 [inline] + file_write_and_wait_range+0x1aa/0x290 mm/filemap.c:788 + f2fs_do_sync_file+0x68a/0x1ae0 fs/f2fs/file.c:276 + generic_write_sync include/linux/fs.h:2806 [inline] + f2fs_file_write_iter+0x7bd/0x24e0 fs/f2fs/file.c:4977 + call_write_iter include/linux/fs.h:2114 [inline] + new_sync_write fs/read_write.c:497 [inline] + vfs_write+0xa72/0xc90 fs/read_write.c:590 + ksys_write+0x1a0/0x2c0 fs/read_write.c:643 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Cc: stable@vger.kernel.org +Reported-by: syzbot+848062ba19c8782ca5c8@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000d103ce06174d7ec3@google.com +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/inline.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -203,8 +203,10 @@ int f2fs_convert_inline_inode(struct ino + struct page *ipage, *page; + int err = 0; + +- if (!f2fs_has_inline_data(inode) || +- f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb)) ++ if (f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb)) ++ return -EROFS; ++ ++ if (!f2fs_has_inline_data(inode)) + return 0; + + err = f2fs_dquot_initialize(inode); diff --git a/queue-6.6/f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch b/queue-6.6/f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch new file mode 100644 index 00000000000..b5fa717f660 --- /dev/null +++ b/queue-6.6/f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch @@ -0,0 +1,79 @@ +From 192b8fb8d1c8ca3c87366ebbef599fa80bb626b8 Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Tue, 4 Jun 2024 15:56:36 +0800 +Subject: f2fs: fix to don't dirty inode for readonly filesystem + +From: Chao Yu + +commit 192b8fb8d1c8ca3c87366ebbef599fa80bb626b8 upstream. + +syzbot reports f2fs bug as below: + +kernel BUG at fs/f2fs/inode.c:933! +RIP: 0010:f2fs_evict_inode+0x1576/0x1590 fs/f2fs/inode.c:933 +Call Trace: + evict+0x2a4/0x620 fs/inode.c:664 + dispose_list fs/inode.c:697 [inline] + evict_inodes+0x5f8/0x690 fs/inode.c:747 + generic_shutdown_super+0x9d/0x2c0 fs/super.c:675 + kill_block_super+0x44/0x90 fs/super.c:1667 + kill_f2fs_super+0x303/0x3b0 fs/f2fs/super.c:4894 + deactivate_locked_super+0xc1/0x130 fs/super.c:484 + cleanup_mnt+0x426/0x4c0 fs/namespace.c:1256 + task_work_run+0x24a/0x300 kernel/task_work.c:180 + ptrace_notify+0x2cd/0x380 kernel/signal.c:2399 + ptrace_report_syscall include/linux/ptrace.h:411 [inline] + ptrace_report_syscall_exit include/linux/ptrace.h:473 [inline] + syscall_exit_work kernel/entry/common.c:251 [inline] + syscall_exit_to_user_mode_prepare kernel/entry/common.c:278 [inline] + __syscall_exit_to_user_mode_work kernel/entry/common.c:283 [inline] + syscall_exit_to_user_mode+0x15c/0x280 kernel/entry/common.c:296 + do_syscall_64+0x50/0x110 arch/x86/entry/common.c:88 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +The root cause is: +- do_sys_open + - f2fs_lookup + - __f2fs_find_entry + - f2fs_i_depth_write + - f2fs_mark_inode_dirty_sync + - f2fs_dirty_inode + - set_inode_flag(inode, FI_DIRTY_INODE) + +- umount + - kill_f2fs_super + - kill_block_super + - generic_shutdown_super + - sync_filesystem + : sb is readonly, skip sync_filesystem() + - evict_inodes + - iput + - f2fs_evict_inode + - f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE)) + : trigger kernel panic + +When we try to repair i_current_depth in readonly filesystem, let's +skip dirty inode to avoid panic in later f2fs_evict_inode(). + +Cc: stable@vger.kernel.org +Reported-by: syzbot+31e4659a3fe953aec2f4@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000e890bc0609a55cff@google.com +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/inode.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -29,6 +29,9 @@ void f2fs_mark_inode_dirty_sync(struct i + if (is_inode_flag_set(inode, FI_NEW_INODE)) + return; + ++ if (f2fs_readonly(F2FS_I_SB(inode)->sb)) ++ return; ++ + if (f2fs_inode_dirtied(inode, sync)) + return; + diff --git a/queue-6.6/f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch b/queue-6.6/f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch new file mode 100644 index 00000000000..ab2b93edaa8 --- /dev/null +++ b/queue-6.6/f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch @@ -0,0 +1,39 @@ +From 5c8764f8679e659c5cb295af7d32279002d13735 Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Thu, 23 May 2024 21:29:48 +0800 +Subject: f2fs: fix to force buffered IO on inline_data inode + +From: Chao Yu + +commit 5c8764f8679e659c5cb295af7d32279002d13735 upstream. + +It will return all zero data when DIO reading from inline_data inode, it +is because f2fs_iomap_begin() assign iomap->type w/ IOMAP_HOLE incorrectly +for this case. + +We can let iomap framework handle inline data via assigning iomap->type +and iomap->inline_data correctly, however, it will be a little bit +complicated when handling race case in between direct IO and buffered IO. + +So, let's force to use buffered IO to fix this issue. + +Cc: stable@vger.kernel.org +Reported-by: Barry Song +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/file.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -803,6 +803,8 @@ static bool f2fs_force_buffered_io(struc + return true; + if (f2fs_compressed_file(inode)) + return true; ++ if (f2fs_has_inline_data(inode)) ++ return true; + + /* disallow direct IO if any of devices has unaligned blksize */ + if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize) diff --git a/queue-6.6/f2fs-use-meta-inode-for-gc-of-atomic-file.patch b/queue-6.6/f2fs-use-meta-inode-for-gc-of-atomic-file.patch new file mode 100644 index 00000000000..8362a57adf4 --- /dev/null +++ b/queue-6.6/f2fs-use-meta-inode-for-gc-of-atomic-file.patch @@ -0,0 +1,148 @@ +From b40a2b00370931b0c50148681dd7364573e52e6b Mon Sep 17 00:00:00 2001 +From: Sunmin Jeong +Date: Wed, 10 Jul 2024 20:51:17 +0900 +Subject: f2fs: use meta inode for GC of atomic file + +From: Sunmin Jeong + +commit b40a2b00370931b0c50148681dd7364573e52e6b upstream. + +The page cache of the atomic file keeps new data pages which will be +stored in the COW file. It can also keep old data pages when GCing the +atomic file. In this case, new data can be overwritten by old data if a +GC thread sets the old data page as dirty after new data page was +evicted. + +Also, since all writes to the atomic file are redirected to COW inodes, +GC for the atomic file is not working well as below. + +f2fs_gc(gc_type=FG_GC) + - select A as a victim segment + do_garbage_collect + - iget atomic file's inode for block B + move_data_page + f2fs_do_write_data_page + - use dn of cow inode + - set fio->old_blkaddr from cow inode + - seg_freed is 0 since block B is still valid + - goto gc_more and A is selected as victim again + +To solve the problem, let's separate GC writes and updates in the atomic +file by using the meta inode for GC writes. + +Fixes: 3db1de0e582c ("f2fs: change the current atomic write way") +Cc: stable@vger.kernel.org #v5.19+ +Reviewed-by: Sungjong Seo +Reviewed-by: Yeongjin Gil +Signed-off-by: Sunmin Jeong +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/data.c | 4 ++-- + fs/f2fs/f2fs.h | 7 ++++++- + fs/f2fs/gc.c | 6 +++--- + fs/f2fs/segment.c | 6 +++--- + 4 files changed, 14 insertions(+), 9 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2672,7 +2672,7 @@ got_it: + } + + /* wait for GCed page writeback via META_MAPPING */ +- if (fio->post_read) ++ if (fio->meta_gc) + f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); + + /* +@@ -2768,7 +2768,7 @@ int f2fs_write_single_data_page(struct p + .submitted = 0, + .compr_blocks = compr_blocks, + .need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY, +- .post_read = f2fs_post_read_required(inode) ? 1 : 0, ++ .meta_gc = f2fs_meta_inode_gc_required(inode) ? 1 : 0, + .io_type = io_type, + .io_wbc = wbc, + .bio = bio, +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -1204,7 +1204,7 @@ struct f2fs_io_info { + unsigned int in_list:1; /* indicate fio is in io_list */ + unsigned int is_por:1; /* indicate IO is from recovery or not */ + unsigned int encrypted:1; /* indicate file is encrypted */ +- unsigned int post_read:1; /* require post read */ ++ unsigned int meta_gc:1; /* require meta inode GC */ + enum iostat_type io_type; /* io type */ + struct writeback_control *io_wbc; /* writeback control */ + struct bio **bio; /* bio for ipu */ +@@ -4255,6 +4255,11 @@ static inline bool f2fs_post_read_requir + f2fs_compressed_file(inode); + } + ++static inline bool f2fs_meta_inode_gc_required(struct inode *inode) ++{ ++ return f2fs_post_read_required(inode) || f2fs_is_atomic_file(inode); ++} ++ + /* + * compress.c + */ +--- a/fs/f2fs/gc.c ++++ b/fs/f2fs/gc.c +@@ -1576,7 +1576,7 @@ next_step: + start_bidx = f2fs_start_bidx_of_node(nofs, inode) + + ofs_in_node; + +- if (f2fs_post_read_required(inode)) { ++ if (f2fs_meta_inode_gc_required(inode)) { + int err = ra_data_block(inode, start_bidx); + + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); +@@ -1627,7 +1627,7 @@ next_step: + + start_bidx = f2fs_start_bidx_of_node(nofs, inode) + + ofs_in_node; +- if (f2fs_post_read_required(inode)) ++ if (f2fs_meta_inode_gc_required(inode)) + err = move_data_block(inode, start_bidx, + gc_type, segno, off); + else +@@ -1635,7 +1635,7 @@ next_step: + segno, off); + + if (!err && (gc_type == FG_GC || +- f2fs_post_read_required(inode))) ++ f2fs_meta_inode_gc_required(inode))) + submitted++; + + if (locked) { +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -3659,7 +3659,7 @@ int f2fs_inplace_write_data(struct f2fs_ + goto drop_bio; + } + +- if (fio->post_read) ++ if (fio->meta_gc) + f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1); + + stat_inc_inplace_blocks(fio->sbi); +@@ -3825,7 +3825,7 @@ void f2fs_wait_on_block_writeback(struct + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct page *cpage; + +- if (!f2fs_post_read_required(inode)) ++ if (!f2fs_meta_inode_gc_required(inode)) + return; + + if (!__is_valid_data_blkaddr(blkaddr)) +@@ -3844,7 +3844,7 @@ void f2fs_wait_on_block_writeback_range( + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + block_t i; + +- if (!f2fs_post_read_required(inode)) ++ if (!f2fs_meta_inode_gc_required(inode)) + return; + + for (i = 0; i < len; i++) diff --git a/queue-6.6/f2fs-use-meta-inode-for-gc-of-cow-file.patch b/queue-6.6/f2fs-use-meta-inode-for-gc-of-cow-file.patch new file mode 100644 index 00000000000..35ca9dc0572 --- /dev/null +++ b/queue-6.6/f2fs-use-meta-inode-for-gc-of-cow-file.patch @@ -0,0 +1,148 @@ +From f18d0076933689775fe7faeeb10ee93ff01be6ab Mon Sep 17 00:00:00 2001 +From: Sunmin Jeong +Date: Wed, 10 Jul 2024 20:51:43 +0900 +Subject: f2fs: use meta inode for GC of COW file + +From: Sunmin Jeong + +commit f18d0076933689775fe7faeeb10ee93ff01be6ab upstream. + +In case of the COW file, new updates and GC writes are already +separated to page caches of the atomic file and COW file. As some cases +that use the meta inode for GC, there are some race issues between a +foreground thread and GC thread. + +To handle them, we need to take care when to invalidate and wait +writeback of GC pages in COW files as the case of using the meta inode. +Also, a pointer from the COW inode to the original inode is required to +check the state of original pages. + +For the former, we can solve the problem by using the meta inode for GC +of COW files. Then let's get a page from the original inode in +move_data_block when GCing the COW file to avoid race condition. + +Fixes: 3db1de0e582c ("f2fs: change the current atomic write way") +Cc: stable@vger.kernel.org #v5.19+ +Reviewed-by: Sungjong Seo +Reviewed-by: Yeongjin Gil +Signed-off-by: Sunmin Jeong +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/data.c | 2 +- + fs/f2fs/f2fs.h | 13 +++++++++++-- + fs/f2fs/file.c | 3 +++ + fs/f2fs/gc.c | 7 +++++-- + fs/f2fs/inline.c | 2 +- + fs/f2fs/inode.c | 3 ++- + 6 files changed, 23 insertions(+), 7 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2586,7 +2586,7 @@ bool f2fs_should_update_outplace(struct + return true; + if (IS_NOQUOTA(inode)) + return true; +- if (f2fs_is_atomic_file(inode)) ++ if (f2fs_used_in_atomic_write(inode)) + return true; + + /* swap file is migrating in aligned write mode */ +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -836,7 +836,11 @@ struct f2fs_inode_info { + struct task_struct *atomic_write_task; /* store atomic write task */ + struct extent_tree *extent_tree[NR_EXTENT_CACHES]; + /* cached extent_tree entry */ +- struct inode *cow_inode; /* copy-on-write inode for atomic write */ ++ union { ++ struct inode *cow_inode; /* copy-on-write inode for atomic write */ ++ struct inode *atomic_inode; ++ /* point to atomic_inode, available only for cow_inode */ ++ }; + + /* avoid racing between foreground op and gc */ + struct f2fs_rwsem i_gc_rwsem[2]; +@@ -4255,9 +4259,14 @@ static inline bool f2fs_post_read_requir + f2fs_compressed_file(inode); + } + ++static inline bool f2fs_used_in_atomic_write(struct inode *inode) ++{ ++ return f2fs_is_atomic_file(inode) || f2fs_is_cow_file(inode); ++} ++ + static inline bool f2fs_meta_inode_gc_required(struct inode *inode) + { +- return f2fs_post_read_required(inode) || f2fs_is_atomic_file(inode); ++ return f2fs_post_read_required(inode) || f2fs_used_in_atomic_write(inode); + } + + /* +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -2119,6 +2119,9 @@ static int f2fs_ioc_start_atomic_write(s + + set_inode_flag(fi->cow_inode, FI_COW_FILE); + clear_inode_flag(fi->cow_inode, FI_INLINE_DATA); ++ ++ /* Set the COW inode's atomic_inode to the atomic inode */ ++ F2FS_I(fi->cow_inode)->atomic_inode = inode; + } else { + /* Reuse the already created COW inode */ + ret = f2fs_do_truncate_blocks(fi->cow_inode, 0, true); +--- a/fs/f2fs/gc.c ++++ b/fs/f2fs/gc.c +@@ -1171,7 +1171,8 @@ static bool is_alive(struct f2fs_sb_info + static int ra_data_block(struct inode *inode, pgoff_t index) + { + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); +- struct address_space *mapping = inode->i_mapping; ++ struct address_space *mapping = f2fs_is_cow_file(inode) ? ++ F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping; + struct dnode_of_data dn; + struct page *page; + struct f2fs_io_info fio = { +@@ -1262,6 +1263,8 @@ put_page: + static int move_data_block(struct inode *inode, block_t bidx, + int gc_type, unsigned int segno, int off) + { ++ struct address_space *mapping = f2fs_is_cow_file(inode) ? ++ F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping; + struct f2fs_io_info fio = { + .sbi = F2FS_I_SB(inode), + .ino = inode->i_ino, +@@ -1284,7 +1287,7 @@ static int move_data_block(struct inode + CURSEG_ALL_DATA_ATGC : CURSEG_COLD_DATA; + + /* do not read out */ +- page = f2fs_grab_cache_page(inode->i_mapping, bidx, false); ++ page = f2fs_grab_cache_page(mapping, bidx, false); + if (!page) + return -ENOMEM; + +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -16,7 +16,7 @@ + + static bool support_inline_data(struct inode *inode) + { +- if (f2fs_is_atomic_file(inode)) ++ if (f2fs_used_in_atomic_write(inode)) + return false; + if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) + return false; +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -816,8 +816,9 @@ void f2fs_evict_inode(struct inode *inod + + f2fs_abort_atomic_write(inode, true); + +- if (fi->cow_inode) { ++ if (fi->cow_inode && f2fs_is_cow_file(fi->cow_inode)) { + clear_inode_flag(fi->cow_inode, FI_COW_FILE); ++ F2FS_I(fi->cow_inode)->atomic_inode = NULL; + iput(fi->cow_inode); + fi->cow_inode = NULL; + } diff --git a/queue-6.6/fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch b/queue-6.6/fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch new file mode 100644 index 00000000000..2d345c6d1ee --- /dev/null +++ b/queue-6.6/fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch @@ -0,0 +1,36 @@ +From 2fef55d8f78383c8e6d6d4c014b9597375132696 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Wed, 29 May 2024 14:40:52 +0800 +Subject: fs/ntfs3: Update log->page_{mask,bits} if log->page_size changed + +From: Huacai Chen + +commit 2fef55d8f78383c8e6d6d4c014b9597375132696 upstream. + +If an NTFS file system is mounted to another system with different +PAGE_SIZE from the original system, log->page_size will change in +log_replay(), but log->page_{mask,bits} don't change correspondingly. +This will cause a panic because "u32 bytes = log->page_size - page_off" +will get a negative value in the later read_log_page(). + +Cc: stable@vger.kernel.org +Fixes: b46acd6a6a627d876898e ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Huacai Chen +Signed-off-by: Konstantin Komarov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3922,6 +3922,9 @@ check_restart_area: + goto out; + } + ++ log->page_mask = log->page_size - 1; ++ log->page_bits = blksize_bits(log->page_size); ++ + /* If the file size has shrunk then we won't mount it. */ + if (log->l_size < le64_to_cpu(ra2->l_size)) { + err = -EINVAL; diff --git a/queue-6.6/hostfs-fix-dev_t-handling.patch b/queue-6.6/hostfs-fix-dev_t-handling.patch new file mode 100644 index 00000000000..bb5cac3695b --- /dev/null +++ b/queue-6.6/hostfs-fix-dev_t-handling.patch @@ -0,0 +1,98 @@ +From 267ed02c2121b75e0eaaa338240453b576039e4a Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 2 Jul 2024 09:24:41 +0200 +Subject: hostfs: fix dev_t handling + +From: Johannes Berg + +commit 267ed02c2121b75e0eaaa338240453b576039e4a upstream. + +dev_t is a kernel type and may have different definitions +in kernel and userspace. On 32-bit x86 this currently makes +the stat structure being 4 bytes longer in the user code, +causing stack corruption. + +However, this is (potentially) not the only problem, since +dev_t is a different type on user/kernel side, so we don't +know that the major/minor encoding isn't also different. +Decode/encode it instead to address both problems. + +Cc: stable@vger.kernel.org +Fixes: 74ce793bcbde ("hostfs: Fix ephemeral inodes") +Link: https://patch.msgid.link/20240702092440.acc960585dd5.Id0767e12f562a69c6cd3c3262dc3d765db350cf6@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + fs/hostfs/hostfs.h | 7 ++++--- + fs/hostfs/hostfs_kern.c | 10 ++++++---- + fs/hostfs/hostfs_user.c | 7 ++++--- + 3 files changed, 14 insertions(+), 10 deletions(-) + +--- a/fs/hostfs/hostfs.h ++++ b/fs/hostfs/hostfs.h +@@ -63,9 +63,10 @@ struct hostfs_stat { + struct hostfs_timespec atime, mtime, ctime; + unsigned int blksize; + unsigned long long blocks; +- unsigned int maj; +- unsigned int min; +- dev_t dev; ++ struct { ++ unsigned int maj; ++ unsigned int min; ++ } rdev, dev; + }; + + extern int stat_file(const char *path, struct hostfs_stat *p, int fd); +--- a/fs/hostfs/hostfs_kern.c ++++ b/fs/hostfs/hostfs_kern.c +@@ -526,10 +526,11 @@ static int hostfs_inode_update(struct in + static int hostfs_inode_set(struct inode *ino, void *data) + { + struct hostfs_stat *st = data; +- dev_t rdev; ++ dev_t dev, rdev; + + /* Reencode maj and min with the kernel encoding.*/ +- rdev = MKDEV(st->maj, st->min); ++ rdev = MKDEV(st->rdev.maj, st->rdev.min); ++ dev = MKDEV(st->dev.maj, st->dev.min); + + switch (st->mode & S_IFMT) { + case S_IFLNK: +@@ -555,7 +556,7 @@ static int hostfs_inode_set(struct inode + return -EIO; + } + +- HOSTFS_I(ino)->dev = st->dev; ++ HOSTFS_I(ino)->dev = dev; + ino->i_ino = st->ino; + ino->i_mode = st->mode; + return hostfs_inode_update(ino, st); +@@ -564,8 +565,9 @@ static int hostfs_inode_set(struct inode + static int hostfs_inode_test(struct inode *inode, void *data) + { + const struct hostfs_stat *st = data; ++ dev_t dev = MKDEV(st->dev.maj, st->dev.min); + +- return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == st->dev; ++ return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == dev; + } + + static struct inode *hostfs_iget(struct super_block *sb, char *name) +--- a/fs/hostfs/hostfs_user.c ++++ b/fs/hostfs/hostfs_user.c +@@ -34,9 +34,10 @@ static void stat64_to_hostfs(const struc + p->mtime.tv_nsec = 0; + p->blksize = buf->st_blksize; + p->blocks = buf->st_blocks; +- p->maj = os_major(buf->st_rdev); +- p->min = os_minor(buf->st_rdev); +- p->dev = buf->st_dev; ++ p->rdev.maj = os_major(buf->st_rdev); ++ p->rdev.min = os_minor(buf->st_rdev); ++ p->dev.maj = os_major(buf->st_dev); ++ p->dev.min = os_minor(buf->st_dev); + } + + int stat_file(const char *path, struct hostfs_stat *p, int fd) diff --git a/queue-6.6/hwrng-amd-convert-pcibios_-return-codes-to-errnos.patch b/queue-6.6/hwrng-amd-convert-pcibios_-return-codes-to-errnos.patch new file mode 100644 index 00000000000..718fda7c1a6 --- /dev/null +++ b/queue-6.6/hwrng-amd-convert-pcibios_-return-codes-to-errnos.patch @@ -0,0 +1,42 @@ +From 14cba6ace79627a57fb9058582b03f0ed3832390 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Mon, 27 May 2024 16:26:15 +0300 +Subject: hwrng: amd - Convert PCIBIOS_* return codes to errnos +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +commit 14cba6ace79627a57fb9058582b03f0ed3832390 upstream. + +amd_rng_mod_init() uses pci_read_config_dword() that returns PCIBIOS_* +codes. The return code is then returned as is but amd_rng_mod_init() is +a module_init() function that should return normal errnos. + +Convert PCIBIOS_* returns code using pcibios_err_to_errno() into normal +errno before returning it. + +Fixes: 96d63c0297cc ("[PATCH] Add AMD HW RNG driver") +Cc: stable@vger.kernel.org +Signed-off-by: Ilpo Järvinen +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/hw_random/amd-rng.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/char/hw_random/amd-rng.c ++++ b/drivers/char/hw_random/amd-rng.c +@@ -143,8 +143,10 @@ static int __init amd_rng_mod_init(void) + + found: + err = pci_read_config_dword(pdev, 0x58, &pmbase); +- if (err) ++ if (err) { ++ err = pcibios_err_to_errno(err); + goto put_dev; ++ } + + pmbase &= 0x0000FF00; + if (pmbase == 0) { diff --git a/queue-6.6/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch b/queue-6.6/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch new file mode 100644 index 00000000000..0acb7380769 --- /dev/null +++ b/queue-6.6/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch @@ -0,0 +1,97 @@ +From 4811f7af6090e8f5a398fbdd766f903ef6c0d787 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Thu, 25 Jul 2024 14:20:07 +0900 +Subject: nilfs2: handle inconsistent state in nilfs_btnode_create_block() + +From: Ryusuke Konishi + +commit 4811f7af6090e8f5a398fbdd766f903ef6c0d787 upstream. + +Syzbot reported that a buffer state inconsistency was detected in +nilfs_btnode_create_block(), triggering a kernel bug. + +It is not appropriate to treat this inconsistency as a bug; it can occur +if the argument block address (the buffer index of the newly created +block) is a virtual block number and has been reallocated due to +corruption of the bitmap used to manage its allocation state. + +So, modify nilfs_btnode_create_block() and its callers to treat it as a +possible filesystem error, rather than triggering a kernel bug. + +Link: https://lkml.kernel.org/r/20240725052007.4562-1-konishi.ryusuke@gmail.com +Fixes: a60be987d45d ("nilfs2: B-tree node cache") +Signed-off-by: Ryusuke Konishi +Reported-by: syzbot+89cc4f2324ed37988b60@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=89cc4f2324ed37988b60 +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nilfs2/btnode.c | 25 ++++++++++++++++++++----- + fs/nilfs2/btree.c | 4 ++-- + 2 files changed, 22 insertions(+), 7 deletions(-) + +--- a/fs/nilfs2/btnode.c ++++ b/fs/nilfs2/btnode.c +@@ -51,12 +51,21 @@ nilfs_btnode_create_block(struct address + + bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node)); + if (unlikely(!bh)) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) || + buffer_dirty(bh))) { +- brelse(bh); +- BUG(); ++ /* ++ * The block buffer at the specified new address was already ++ * in use. This can happen if it is a virtual block number ++ * and has been reallocated due to corruption of the bitmap ++ * used to manage its allocation state (if not, the buffer ++ * clearing of an abandoned b-tree node is missing somewhere). ++ */ ++ nilfs_error(inode->i_sb, ++ "state inconsistency probably due to duplicate use of b-tree node block address %llu (ino=%lu)", ++ (unsigned long long)blocknr, inode->i_ino); ++ goto failed; + } + memset(bh->b_data, 0, i_blocksize(inode)); + bh->b_bdev = inode->i_sb->s_bdev; +@@ -67,6 +76,12 @@ nilfs_btnode_create_block(struct address + unlock_page(bh->b_page); + put_page(bh->b_page); + return bh; ++ ++failed: ++ folio_unlock(bh->b_folio); ++ folio_put(bh->b_folio); ++ brelse(bh); ++ return ERR_PTR(-EIO); + } + + int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, +@@ -217,8 +232,8 @@ retry: + } + + nbh = nilfs_btnode_create_block(btnc, newkey); +- if (!nbh) +- return -ENOMEM; ++ if (IS_ERR(nbh)) ++ return PTR_ERR(nbh); + + BUG_ON(nbh == obh); + ctxt->newbh = nbh; +--- a/fs/nilfs2/btree.c ++++ b/fs/nilfs2/btree.c +@@ -63,8 +63,8 @@ static int nilfs_btree_get_new_block(con + struct buffer_head *bh; + + bh = nilfs_btnode_create_block(btnc, ptr); +- if (!bh) +- return -ENOMEM; ++ if (IS_ERR(bh)) ++ return PTR_ERR(bh); + + set_buffer_nilfs_volatile(bh); + *bhp = bh; diff --git a/queue-6.6/parisc-fix-warning-at-drivers-pci-msi-msi.h-121.patch b/queue-6.6/parisc-fix-warning-at-drivers-pci-msi-msi.h-121.patch new file mode 100644 index 00000000000..a9cb9b4feb6 --- /dev/null +++ b/queue-6.6/parisc-fix-warning-at-drivers-pci-msi-msi.h-121.patch @@ -0,0 +1,39 @@ +From 4c29ab84cfec17081aae7a7a28f8d2c93c42dcae Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Mon, 1 Jul 2024 09:42:41 -0400 +Subject: parisc: Fix warning at drivers/pci/msi/msi.h:121 + +From: John David Anglin + +commit 4c29ab84cfec17081aae7a7a28f8d2c93c42dcae upstream. + +Fix warning at drivers/pci/msi/msi.h:121. + +Recently, I added a PCI to PCIe bridge adaptor and a PCIe NVME card +to my rp3440. Then, I noticed this warning at boot: + + WARNING: CPU: 0 PID: 10 at drivers/pci/msi/msi.h:121 pci_msi_setup_msi_irqs+0x68/0x90 + CPU: 0 PID: 10 Comm: kworker/u32:0 Not tainted 6.9.7-parisc64 #1 Debian 6.9.7-1 + Hardware name: 9000/800/rp3440 + Workqueue: async async_run_entry_fn + +We need to select PCI_MSI_ARCH_FALLBACKS when PCI_MSI is selected. + +Signed-off-by: John David Anglin +Cc: stable@vger.kernel.org # v6.0+ +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman +--- + arch/parisc/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -83,6 +83,7 @@ config PARISC + select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS + select TRACE_IRQFLAGS_SUPPORT + select HAVE_FUNCTION_DESCRIPTORS if 64BIT ++ select PCI_MSI_ARCH_FALLBACKS if PCI_MSI + + help + The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/queue-6.6/pci-dw-rockchip-fix-initial-perst-gpio-value.patch b/queue-6.6/pci-dw-rockchip-fix-initial-perst-gpio-value.patch new file mode 100644 index 00000000000..7b470be29ab --- /dev/null +++ b/queue-6.6/pci-dw-rockchip-fix-initial-perst-gpio-value.patch @@ -0,0 +1,81 @@ +From 28b8d7793b8573563b3d45321376f36168d77b1e Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Wed, 17 Apr 2024 18:42:26 +0200 +Subject: PCI: dw-rockchip: Fix initial PERST# GPIO value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Cassel + +commit 28b8d7793b8573563b3d45321376f36168d77b1e upstream. + +PERST# is active low according to the PCIe specification. + +However, the existing pcie-dw-rockchip.c driver does: + + gpiod_set_value(..., 0); msleep(100); gpiod_set_value(..., 1); + +when asserting + deasserting PERST#. + +This is of course wrong, but because all the device trees for this +compatible string have also incorrectly marked this GPIO as ACTIVE_HIGH: + + $ git grep -B 10 reset-gpios arch/arm64/boot/dts/rockchip/rk3568* + $ git grep -B 10 reset-gpios arch/arm64/boot/dts/rockchip/rk3588* + +The actual toggling of PERST# is correct, and we cannot change it anyway, +since that would break device tree compatibility. + +However, this driver does request the GPIO to be initialized as +GPIOD_OUT_HIGH, which does cause a silly sequence where PERST# gets +toggled back and forth for no good reason. + +Fix this by requesting the GPIO to be initialized as GPIOD_OUT_LOW (which +for this driver means PERST# asserted). + +This will avoid an unnecessary signal change where PERST# gets deasserted +(by devm_gpiod_get_optional()) and then gets asserted (by +rockchip_pcie_start_link()) just a few instructions later. + +Before patch, debug prints on EP side, when booting RC: + + [ 845.606810] pci: PERST# asserted by host! + [ 852.483985] pci: PERST# de-asserted by host! + [ 852.503041] pci: PERST# asserted by host! + [ 852.610318] pci: PERST# de-asserted by host! + +After patch, debug prints on EP side, when booting RC: + + [ 125.107921] pci: PERST# asserted by host! + [ 132.111429] pci: PERST# de-asserted by host! + +This extra, very short, PERST# assertion + deassertion has been reported to +cause issues with certain WLAN controllers, e.g. RTL8822CE. + +Fixes: 0e898eb8df4e ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver") +Link: https://lore.kernel.org/linux-pci/20240417164227.398901-1-cassel@kernel.org +Tested-by: Heiko Stuebner +Tested-by: Jianfeng Liu +Signed-off-by: Niklas Cassel +Signed-off-by: Krzysztof Wilczyński +Signed-off-by: Bjorn Helgaas +Reviewed-by: Heiko Stuebner +Reviewed-by: Manivannan Sadhasivam +Cc: stable@vger.kernel.org # v5.15+ +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/dwc/pcie-dw-rockchip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c ++++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c +@@ -240,7 +240,7 @@ static int rockchip_pcie_resource_get(st + return PTR_ERR(rockchip->apb_base); + + rockchip->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", +- GPIOD_OUT_HIGH); ++ GPIOD_OUT_LOW); + if (IS_ERR(rockchip->rst_gpio)) + return PTR_ERR(rockchip->rst_gpio); + diff --git a/queue-6.6/pci-hv-return-zero-not-garbage-when-reading-pci_interrupt_pin.patch b/queue-6.6/pci-hv-return-zero-not-garbage-when-reading-pci_interrupt_pin.patch new file mode 100644 index 00000000000..e8b346e564d --- /dev/null +++ b/queue-6.6/pci-hv-return-zero-not-garbage-when-reading-pci_interrupt_pin.patch @@ -0,0 +1,48 @@ +From fea93a3e5d5e6a09eb153866d2ce60ea3287a70d Mon Sep 17 00:00:00 2001 +From: Wei Liu +Date: Mon, 1 Jul 2024 20:26:05 +0000 +Subject: PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Wei Liu + +commit fea93a3e5d5e6a09eb153866d2ce60ea3287a70d upstream. + +The intent of the code snippet is to always return 0 for both +PCI_INTERRUPT_LINE and PCI_INTERRUPT_PIN. + +The check misses PCI_INTERRUPT_PIN. This patch fixes that. + +This is discovered by this call in VFIO: + + pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin); + +The old code does not set *val to 0 because it misses the check for +PCI_INTERRUPT_PIN. Garbage is returned in that case. + +Fixes: 4daace0d8ce8 ("PCI: hv: Add paravirtual PCI front-end for Microsoft Hyper-V VMs") +Link: https://lore.kernel.org/linux-pci/20240701202606.129606-1-wei.liu@kernel.org +Signed-off-by: Wei Liu +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: Michael Kelley +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-hyperv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/pci/controller/pci-hyperv.c ++++ b/drivers/pci/controller/pci-hyperv.c +@@ -1137,8 +1137,8 @@ static void _hv_pcifront_read_config(str + PCI_CAPABILITY_LIST) { + /* ROM BARs are unimplemented */ + *val = 0; +- } else if (where >= PCI_INTERRUPT_LINE && where + size <= +- PCI_INTERRUPT_PIN) { ++ } else if ((where >= PCI_INTERRUPT_LINE && where + size <= PCI_INTERRUPT_PIN) || ++ (where >= PCI_INTERRUPT_PIN && where + size <= PCI_MIN_GNT)) { + /* + * Interrupt Line and Interrupt PIN are hard-wired to zero + * because this front-end only supports message-signaled diff --git a/queue-6.6/pci-loongson-enable-msi-in-ls7a-root-complex.patch b/queue-6.6/pci-loongson-enable-msi-in-ls7a-root-complex.patch new file mode 100644 index 00000000000..e6669dfa32f --- /dev/null +++ b/queue-6.6/pci-loongson-enable-msi-in-ls7a-root-complex.patch @@ -0,0 +1,60 @@ +From a4bbcac11d3cea85822af8b40daed7e96bca5068 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Wed, 12 Jun 2024 14:53:15 +0800 +Subject: PCI: loongson: Enable MSI in LS7A Root Complex +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Huacai Chen + +commit a4bbcac11d3cea85822af8b40daed7e96bca5068 upstream. + +The LS7A chipset can be used as part of a PCIe Root Complex with +Loongson-3C6000 and similar CPUs. In this case, DEV_LS7A_PCIE_PORT5 has a +PCI_CLASS_BRIDGE_HOST class code, and it is a Type 0 Function whose config +space provides access to Root Complex registers. + +The DEV_LS7A_PCIE_PORT5 has an MSI Capability, and its MSI Enable bit must +be set before other devices below the Root Complex can use MSI. This is +not the standard PCI behavior of MSI Enable, so the normal PCI MSI code +does not set it. + +Set the DEV_LS7A_PCIE_PORT5 MSI Enable bit via a quirk so other devices +below the Root Complex can use MSI. + +[kwilczynski: exit early to reduce indentation; commit log] +Link: https://lore.kernel.org/linux-pci/20240612065315.2048110-1-chenhuacai@loongson.cn +Signed-off-by: Sheng Wu +Signed-off-by: Huacai Chen +Signed-off-by: Krzysztof Wilczyński +[bhelgaas: commit log] +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-loongson.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/pci/controller/pci-loongson.c ++++ b/drivers/pci/controller/pci-loongson.c +@@ -163,6 +163,19 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LO + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_HDMI, loongson_pci_pin_quirk); + ++static void loongson_pci_msi_quirk(struct pci_dev *dev) ++{ ++ u16 val, class = dev->class >> 8; ++ ++ if (class != PCI_CLASS_BRIDGE_HOST) ++ return; ++ ++ pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &val); ++ val |= PCI_MSI_FLAGS_ENABLE; ++ pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, val); ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_PCIE_PORT5, loongson_pci_msi_quirk); ++ + static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) + { + struct pci_config_window *cfg; diff --git a/queue-6.6/pci-rockchip-use-gpiod_out_low-flag-while-requesting-ep_gpio.patch b/queue-6.6/pci-rockchip-use-gpiod_out_low-flag-while-requesting-ep_gpio.patch new file mode 100644 index 00000000000..d381bab7dee --- /dev/null +++ b/queue-6.6/pci-rockchip-use-gpiod_out_low-flag-while-requesting-ep_gpio.patch @@ -0,0 +1,83 @@ +From 840b7a5edf88fe678c60dee88a135647c0ea4375 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam +Date: Tue, 16 Apr 2024 11:12:35 +0530 +Subject: PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Manivannan Sadhasivam + +commit 840b7a5edf88fe678c60dee88a135647c0ea4375 upstream. + +Rockchip platforms use 'GPIO_ACTIVE_HIGH' flag in the devicetree definition +for ep_gpio. This means, whatever the logical value set by the driver for +the ep_gpio, physical line will output the same logic level. + +For instance, + + gpiod_set_value_cansleep(rockchip->ep_gpio, 0); --> Level low + gpiod_set_value_cansleep(rockchip->ep_gpio, 1); --> Level high + +But while requesting the ep_gpio, GPIOD_OUT_HIGH flag is currently used. +Now, this also causes the physical line to output 'high' creating trouble +for endpoint devices during host reboot. + +When host reboot happens, the ep_gpio will initially output 'low' due to +the GPIO getting reset to its POR value. Then during host controller probe, +it will output 'high' due to GPIOD_OUT_HIGH flag. Then during +rockchip_pcie_host_init_port(), it will first output 'low' and then 'high' +indicating the completion of controller initialization. + +On the endpoint side, each output 'low' of ep_gpio is accounted for PERST# +assert and 'high' for PERST# deassert. With the above mentioned flow during +host reboot, endpoint will witness below state changes for PERST#: + + (1) PERST# assert - GPIO POR state + (2) PERST# deassert - GPIOD_OUT_HIGH while requesting GPIO + (3) PERST# assert - rockchip_pcie_host_init_port() + (4) PERST# deassert - rockchip_pcie_host_init_port() + +Now the time interval between (2) and (3) is very short as both happen +during the driver probe(), and this results in a race in the endpoint. +Because, before completing the PERST# deassertion in (2), endpoint got +another PERST# assert in (3). + +A proper way to fix this issue is to change the GPIOD_OUT_HIGH flag in (2) +to GPIOD_OUT_LOW. Because the usual convention is to request the GPIO with +a state corresponding to its 'initial/default' value and let the driver +change the state of the GPIO when required. + +As per that, the ep_gpio should be requested with GPIOD_OUT_LOW as it +corresponds to the POR value of '0' (PERST# assert in the endpoint). Then +the driver can change the state of the ep_gpio later in +rockchip_pcie_host_init_port() as per the initialization sequence. + +This fixes the firmware crash issue in Qcom based modems connected to +Rockpro64 based board. + +Fixes: e77f847df54c ("PCI: rockchip: Add Rockchip PCIe controller support") +Closes: https://lore.kernel.org/mhi/20240402045647.GG2933@thinkpad/ +Link: https://lore.kernel.org/linux-pci/20240416-pci-rockchip-perst-fix-v1-1-4800b1d4d954@linaro.org +Reported-by: Slark Xiao +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Krzysztof Wilczyński +Signed-off-by: Bjorn Helgaas +Reviewed-by: Niklas Cassel +Cc: stable@vger.kernel.org # v4.9 +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pcie-rockchip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/pcie-rockchip.c ++++ b/drivers/pci/controller/pcie-rockchip.c +@@ -121,7 +121,7 @@ int rockchip_pcie_parse_dt(struct rockch + + if (rockchip->is_rc) { + rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep", +- GPIOD_OUT_HIGH); ++ GPIOD_OUT_LOW); + if (IS_ERR(rockchip->ep_gpio)) + return dev_err_probe(dev, PTR_ERR(rockchip->ep_gpio), + "failed to get ep GPIO\n"); diff --git a/queue-6.6/scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch b/queue-6.6/scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch new file mode 100644 index 00000000000..8915780ac4c --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch @@ -0,0 +1,39 @@ +From ce2065c4cc4f05635413f63f6dc038d7d4842e31 Mon Sep 17 00:00:00 2001 +From: Saurav Kashyap +Date: Wed, 10 Jul 2024 22:40:50 +0530 +Subject: scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds + +From: Saurav Kashyap + +commit ce2065c4cc4f05635413f63f6dc038d7d4842e31 upstream. + +Firmware only supports single DSDs in ELS Pass-through IOCB (0x53h), sg cnt +is decided by the SCSI ML. User is not aware of the cause of an acutal +error. + +Return the appropriate return code that will be decoded by API and +application and proper error message will be displayed to user. + +Fixes: 6e98016ca077 ("[SCSI] qla2xxx: Re-organized BSG interface specific code.") +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240710171057.35066-5-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_bsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -324,7 +324,7 @@ qla2x00_process_els(struct bsg_job *bsg_ + "request_sg_cnt=%x reply_sg_cnt=%x.\n", + bsg_job->request_payload.sg_cnt, + bsg_job->reply_payload.sg_cnt); +- rval = -EPERM; ++ rval = -ENOBUFS; + goto done; + } + diff --git a/queue-6.6/series b/queue-6.6/series index baefefd1330..10ee3cffa5f 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -420,3 +420,23 @@ alsa-ump-force-1-group-for-midi1-fbs.patch alsa-usb-audio-fix-microphone-sound-on-hd-webcam.patch alsa-usb-audio-move-hd-webcam-quirk-to-the-right-place.patch alsa-usb-audio-add-a-quirk-for-sonix-hd-usb-camera.patch +tools-memory-model-fix-bug-in-lock.cat.patch +hwrng-amd-convert-pcibios_-return-codes-to-errnos.patch +parisc-fix-warning-at-drivers-pci-msi-msi.h-121.patch +pci-hv-return-zero-not-garbage-when-reading-pci_interrupt_pin.patch +pci-dw-rockchip-fix-initial-perst-gpio-value.patch +pci-rockchip-use-gpiod_out_low-flag-while-requesting-ep_gpio.patch +pci-loongson-enable-msi-in-ls7a-root-complex.patch +binder-fix-hang-of-unregistered-readers.patch +dev-parport-fix-the-array-out-of-bounds-risk.patch +hostfs-fix-dev_t-handling.patch +efi-libstub-zero-initialize-heap-allocated-struct-screen_info.patch +fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch +scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch +asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch +f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch +f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch +f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch +f2fs-use-meta-inode-for-gc-of-atomic-file.patch +f2fs-use-meta-inode-for-gc-of-cow-file.patch +nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch diff --git a/queue-6.6/tools-memory-model-fix-bug-in-lock.cat.patch b/queue-6.6/tools-memory-model-fix-bug-in-lock.cat.patch new file mode 100644 index 00000000000..e66fde3ce8d --- /dev/null +++ b/queue-6.6/tools-memory-model-fix-bug-in-lock.cat.patch @@ -0,0 +1,98 @@ +From 4c830eef806679dc243e191f962c488dd9d00708 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 6 Jun 2024 09:57:55 -0400 +Subject: tools/memory-model: Fix bug in lock.cat + +From: Alan Stern + +commit 4c830eef806679dc243e191f962c488dd9d00708 upstream. + +Andrea reported that the following innocuous litmus test: + +C T + +{} + +P0(spinlock_t *x) +{ + int r0; + + spin_lock(x); + spin_unlock(x); + r0 = spin_is_locked(x); +} + +gives rise to a nonsensical empty result with no executions: + +$ herd7 -conf linux-kernel.cfg T.litmus +Test T Required +States 0 +Ok +Witnesses +Positive: 0 Negative: 0 +Condition forall (true) +Observation T Never 0 0 +Time T 0.00 +Hash=6fa204e139ddddf2cb6fa963bad117c0 + +The problem is caused by a bug in the lock.cat part of the LKMM. Its +computation of the rf relation for RU (read-unlocked) events is +faulty; it implicitly assumes that every RU event must read from +either a UL (unlock) event in another thread or from the lock's +initial state. Neither is true in the litmus test above, so the +computation yields no possible executions. + +The lock.cat code tries to make up for this deficiency by allowing RU +events outside of critical sections to read from the last po-previous +UL event. But it does this incorrectly, trying to keep these rfi links +separate from the rfe links that might also be needed, and passing only +the latter to herd7's cross() macro. + +The problem is fixed by merging the two sets of possible rf links for +RU events and using them all in the call to cross(). + +Signed-off-by: Alan Stern +Reported-by: Andrea Parri +Closes: https://lore.kernel.org/linux-arch/ZlC0IkzpQdeGj+a3@andrea/ +Tested-by: Andrea Parri +Acked-by: Andrea Parri +Fixes: 15553dcbca06 ("tools/memory-model: Add model support for spin_is_locked()") +CC: +Signed-off-by: Paul E. McKenney +Signed-off-by: Greg Kroah-Hartman +--- + tools/memory-model/lock.cat | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/tools/memory-model/lock.cat ++++ b/tools/memory-model/lock.cat +@@ -102,19 +102,19 @@ let rf-lf = rfe-lf | rfi-lf + * within one of the lock's critical sections returns False. + *) + +-(* rfi for RU events: an RU may read from the last po-previous UL *) +-let rfi-ru = ([UL] ; po-loc ; [RU]) \ ([UL] ; po-loc ; [LKW] ; po-loc) +- +-(* rfe for RU events: an RU may read from an external UL or the initial write *) +-let all-possible-rfe-ru = +- let possible-rfe-ru r = ++(* ++ * rf for RU events: an RU may read from an external UL or the initial write, ++ * or from the last po-previous UL ++ *) ++let all-possible-rf-ru = ++ let possible-rf-ru r = + let pair-to-relation p = p ++ 0 +- in map pair-to-relation (((UL | IW) * {r}) & loc & ext) +- in map possible-rfe-ru RU ++ in map pair-to-relation ((((UL | IW) * {r}) & loc & ext) | ++ (((UL * {r}) & po-loc) \ ([UL] ; po-loc ; [LKW] ; po-loc))) ++ in map possible-rf-ru RU + + (* Generate all rf relations for RU events *) +-with rfe-ru from cross(all-possible-rfe-ru) +-let rf-ru = rfe-ru | rfi-ru ++with rf-ru from cross(all-possible-rf-ru) + + (* Final rf relation *) + let rf = rf | rf-lf | rf-ru