]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Sat, 2 Nov 2024 11:11:41 +0000 (07:11 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 2 Nov 2024 11:11:41 +0000 (07:11 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
12 files changed:
queue-6.6/acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch [new file with mode: 0644]
queue-6.6/afs-automatically-generate-trace-tag-enums.patch [new file with mode: 0644]
queue-6.6/afs-fix-missing-subdir-edit-when-renamed-between-par.patch [new file with mode: 0644]
queue-6.6/firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch [new file with mode: 0644]
queue-6.6/fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch [new file with mode: 0644]
queue-6.6/fsdax-remove-zeroing-code-from-dax_unshare_iter.patch [new file with mode: 0644]
queue-6.6/iomap-don-t-bother-unsharing-delalloc-extents.patch [new file with mode: 0644]
queue-6.6/iomap-improve-shared-block-detection-in-iomap_unshar.patch [new file with mode: 0644]
queue-6.6/iomap-share-iomap_unshare_iter-predicate-code-with-f.patch [new file with mode: 0644]
queue-6.6/iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch [new file with mode: 0644]
queue-6.6/kasan-fix-software-tag-based-kasan-with-gcc.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-6.6/acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch b/queue-6.6/acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch
new file mode 100644 (file)
index 0000000..85b7279
--- /dev/null
@@ -0,0 +1,128 @@
+From d2f7ab03d6205a62b0576b39f2d939767dcfa03f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2024 13:56:56 +0100
+Subject: ACPI: CPPC: Make rmw_lock a raw_spin_lock
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit 1c10941e34c5fdc0357e46a25bd130d9cf40b925 ]
+
+The following BUG was triggered:
+
+=============================
+[ BUG: Invalid wait context ]
+6.12.0-rc2-XXX #406 Not tainted
+-----------------------------
+kworker/1:1/62 is trying to lock:
+ffffff8801593030 (&cpc_ptr->rmw_lock){+.+.}-{3:3}, at: cpc_write+0xcc/0x370
+other info that might help us debug this:
+context-{5:5}
+2 locks held by kworker/1:1/62:
+  #0: ffffff897ef5ec98 (&rq->__lock){-.-.}-{2:2}, at: raw_spin_rq_lock_nested+0x2c/0x50
+  #1: ffffff880154e238 (&sg_policy->update_lock){....}-{2:2}, at: sugov_update_shared+0x3c/0x280
+stack backtrace:
+CPU: 1 UID: 0 PID: 62 Comm: kworker/1:1 Not tainted 6.12.0-rc2-g9654bd3e8806 #406
+Workqueue:  0x0 (events)
+Call trace:
+  dump_backtrace+0xa4/0x130
+  show_stack+0x20/0x38
+  dump_stack_lvl+0x90/0xd0
+  dump_stack+0x18/0x28
+  __lock_acquire+0x480/0x1ad8
+  lock_acquire+0x114/0x310
+  _raw_spin_lock+0x50/0x70
+  cpc_write+0xcc/0x370
+  cppc_set_perf+0xa0/0x3a8
+  cppc_cpufreq_fast_switch+0x40/0xc0
+  cpufreq_driver_fast_switch+0x4c/0x218
+  sugov_update_shared+0x234/0x280
+  update_load_avg+0x6ec/0x7b8
+  dequeue_entities+0x108/0x830
+  dequeue_task_fair+0x58/0x408
+  __schedule+0x4f0/0x1070
+  schedule+0x54/0x130
+  worker_thread+0xc0/0x2e8
+  kthread+0x130/0x148
+  ret_from_fork+0x10/0x20
+
+sugov_update_shared() locks a raw_spinlock while cpc_write() locks a
+spinlock.
+
+To have a correct wait-type order, update rmw_lock to a raw spinlock and
+ensure that interrupts will be disabled on the CPU holding it.
+
+Fixes: 60949b7b8054 ("ACPI: CPPC: Fix MASK_VAL() usage")
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Link: https://patch.msgid.link/20241028125657.1271512-1-pierre.gondois@arm.com
+[ rjw: Changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 9 +++++----
+ include/acpi/cppc_acpi.h | 2 +-
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 5df417626fd10..26d1beec99137 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -863,7 +863,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+       /* Store CPU Logical ID */
+       cpc_ptr->cpu_id = pr->id;
+-      spin_lock_init(&cpc_ptr->rmw_lock);
++      raw_spin_lock_init(&cpc_ptr->rmw_lock);
+       /* Parse PSD data for this CPU */
+       ret = acpi_get_psd(cpc_ptr, handle);
+@@ -1083,6 +1083,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+       int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
+       struct cpc_reg *reg = &reg_res->cpc_entry.reg;
+       struct cpc_desc *cpc_desc;
++      unsigned long flags;
+       size = GET_BIT_WIDTH(reg);
+@@ -1122,7 +1123,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+                       return -ENODEV;
+               }
+-              spin_lock(&cpc_desc->rmw_lock);
++              raw_spin_lock_irqsave(&cpc_desc->rmw_lock, flags);
+               switch (size) {
+               case 8:
+                       prev_val = readb_relaxed(vaddr);
+@@ -1137,7 +1138,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+                       prev_val = readq_relaxed(vaddr);
+                       break;
+               default:
+-                      spin_unlock(&cpc_desc->rmw_lock);
++                      raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags);
+                       return -EFAULT;
+               }
+               val = MASK_VAL_WRITE(reg, prev_val, val);
+@@ -1170,7 +1171,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+       }
+       if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+-              spin_unlock(&cpc_desc->rmw_lock);
++              raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags);
+       return ret_val;
+ }
+diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
+index e1720d9306669..a451ca4c207bb 100644
+--- a/include/acpi/cppc_acpi.h
++++ b/include/acpi/cppc_acpi.h
+@@ -65,7 +65,7 @@ struct cpc_desc {
+       int write_cmd_status;
+       int write_cmd_id;
+       /* Lock used for RMW operations in cpc_write() */
+-      spinlock_t rmw_lock;
++      raw_spinlock_t rmw_lock;
+       struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
+       struct acpi_psd_package domain_info;
+       struct kobject kobj;
+-- 
+2.43.0
+
diff --git a/queue-6.6/afs-automatically-generate-trace-tag-enums.patch b/queue-6.6/afs-automatically-generate-trace-tag-enums.patch
new file mode 100644 (file)
index 0000000..7f52a20
--- /dev/null
@@ -0,0 +1,292 @@
+From bc501741ae836b702a31375865a842ef2915190b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Feb 2023 15:24:24 +0000
+Subject: afs: Automatically generate trace tag enums
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 2daa6404fd2f00985d5bfeb3c161f4630b46b6bf ]
+
+Automatically generate trace tag enums from the symbol -> string mapping
+tables rather than having the enums as well, thereby reducing duplicated
+data.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: linux-fsdevel@vger.kernel.org
+Stable-dep-of: 247d65fb122a ("afs: Fix missing subdir edit when renamed between parent dirs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/afs.h | 233 +++++--------------------------------
+ 1 file changed, 27 insertions(+), 206 deletions(-)
+
+diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h
+index e9d412d19dbbb..54d10c69e55ec 100644
+--- a/include/trace/events/afs.h
++++ b/include/trace/events/afs.h
+@@ -18,97 +18,6 @@
+ #ifndef __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
+ #define __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
+-enum afs_call_trace {
+-      afs_call_trace_alloc,
+-      afs_call_trace_free,
+-      afs_call_trace_get,
+-      afs_call_trace_put,
+-      afs_call_trace_wake,
+-      afs_call_trace_work,
+-};
+-
+-enum afs_server_trace {
+-      afs_server_trace_alloc,
+-      afs_server_trace_callback,
+-      afs_server_trace_destroy,
+-      afs_server_trace_free,
+-      afs_server_trace_gc,
+-      afs_server_trace_get_by_addr,
+-      afs_server_trace_get_by_uuid,
+-      afs_server_trace_get_caps,
+-      afs_server_trace_get_install,
+-      afs_server_trace_get_new_cbi,
+-      afs_server_trace_get_probe,
+-      afs_server_trace_give_up_cb,
+-      afs_server_trace_purging,
+-      afs_server_trace_put_call,
+-      afs_server_trace_put_cbi,
+-      afs_server_trace_put_find_rsq,
+-      afs_server_trace_put_probe,
+-      afs_server_trace_put_slist,
+-      afs_server_trace_put_slist_isort,
+-      afs_server_trace_put_uuid_rsq,
+-      afs_server_trace_update,
+-};
+-
+-
+-enum afs_volume_trace {
+-      afs_volume_trace_alloc,
+-      afs_volume_trace_free,
+-      afs_volume_trace_get_alloc_sbi,
+-      afs_volume_trace_get_cell_insert,
+-      afs_volume_trace_get_new_op,
+-      afs_volume_trace_get_query_alias,
+-      afs_volume_trace_put_cell_dup,
+-      afs_volume_trace_put_cell_root,
+-      afs_volume_trace_put_destroy_sbi,
+-      afs_volume_trace_put_free_fc,
+-      afs_volume_trace_put_put_op,
+-      afs_volume_trace_put_query_alias,
+-      afs_volume_trace_put_validate_fc,
+-      afs_volume_trace_remove,
+-};
+-
+-enum afs_cell_trace {
+-      afs_cell_trace_alloc,
+-      afs_cell_trace_free,
+-      afs_cell_trace_get_queue_dns,
+-      afs_cell_trace_get_queue_manage,
+-      afs_cell_trace_get_queue_new,
+-      afs_cell_trace_get_vol,
+-      afs_cell_trace_insert,
+-      afs_cell_trace_manage,
+-      afs_cell_trace_put_candidate,
+-      afs_cell_trace_put_destroy,
+-      afs_cell_trace_put_queue_fail,
+-      afs_cell_trace_put_queue_work,
+-      afs_cell_trace_put_vol,
+-      afs_cell_trace_see_source,
+-      afs_cell_trace_see_ws,
+-      afs_cell_trace_unuse_alias,
+-      afs_cell_trace_unuse_check_alias,
+-      afs_cell_trace_unuse_delete,
+-      afs_cell_trace_unuse_fc,
+-      afs_cell_trace_unuse_lookup,
+-      afs_cell_trace_unuse_mntpt,
+-      afs_cell_trace_unuse_no_pin,
+-      afs_cell_trace_unuse_parse,
+-      afs_cell_trace_unuse_pin,
+-      afs_cell_trace_unuse_probe,
+-      afs_cell_trace_unuse_sbi,
+-      afs_cell_trace_unuse_ws,
+-      afs_cell_trace_use_alias,
+-      afs_cell_trace_use_check_alias,
+-      afs_cell_trace_use_fc,
+-      afs_cell_trace_use_fc_alias,
+-      afs_cell_trace_use_lookup,
+-      afs_cell_trace_use_mntpt,
+-      afs_cell_trace_use_pin,
+-      afs_cell_trace_use_probe,
+-      afs_cell_trace_use_sbi,
+-      afs_cell_trace_wait,
+-};
+-
+ enum afs_fs_operation {
+       afs_FS_FetchData                = 130,  /* AFS Fetch file data */
+       afs_FS_FetchACL                 = 131,  /* AFS Fetch file ACL */
+@@ -202,121 +111,6 @@ enum yfs_cm_operation {
+       yfs_CB_CallBack                 = 64204,
+ };
+-enum afs_edit_dir_op {
+-      afs_edit_dir_create,
+-      afs_edit_dir_create_error,
+-      afs_edit_dir_create_inval,
+-      afs_edit_dir_create_nospc,
+-      afs_edit_dir_delete,
+-      afs_edit_dir_delete_error,
+-      afs_edit_dir_delete_inval,
+-      afs_edit_dir_delete_noent,
+-};
+-
+-enum afs_edit_dir_reason {
+-      afs_edit_dir_for_create,
+-      afs_edit_dir_for_link,
+-      afs_edit_dir_for_mkdir,
+-      afs_edit_dir_for_rename_0,
+-      afs_edit_dir_for_rename_1,
+-      afs_edit_dir_for_rename_2,
+-      afs_edit_dir_for_rmdir,
+-      afs_edit_dir_for_silly_0,
+-      afs_edit_dir_for_silly_1,
+-      afs_edit_dir_for_symlink,
+-      afs_edit_dir_for_unlink,
+-};
+-
+-enum afs_eproto_cause {
+-      afs_eproto_bad_status,
+-      afs_eproto_cb_count,
+-      afs_eproto_cb_fid_count,
+-      afs_eproto_cellname_len,
+-      afs_eproto_file_type,
+-      afs_eproto_ibulkst_cb_count,
+-      afs_eproto_ibulkst_count,
+-      afs_eproto_motd_len,
+-      afs_eproto_offline_msg_len,
+-      afs_eproto_volname_len,
+-      afs_eproto_yvl_fsendpt4_len,
+-      afs_eproto_yvl_fsendpt6_len,
+-      afs_eproto_yvl_fsendpt_num,
+-      afs_eproto_yvl_fsendpt_type,
+-      afs_eproto_yvl_vlendpt4_len,
+-      afs_eproto_yvl_vlendpt6_len,
+-      afs_eproto_yvl_vlendpt_type,
+-};
+-
+-enum afs_io_error {
+-      afs_io_error_cm_reply,
+-      afs_io_error_extract,
+-      afs_io_error_fs_probe_fail,
+-      afs_io_error_vl_lookup_fail,
+-      afs_io_error_vl_probe_fail,
+-};
+-
+-enum afs_file_error {
+-      afs_file_error_dir_bad_magic,
+-      afs_file_error_dir_big,
+-      afs_file_error_dir_missing_page,
+-      afs_file_error_dir_name_too_long,
+-      afs_file_error_dir_over_end,
+-      afs_file_error_dir_small,
+-      afs_file_error_dir_unmarked_ext,
+-      afs_file_error_mntpt,
+-      afs_file_error_writeback_fail,
+-};
+-
+-enum afs_flock_event {
+-      afs_flock_acquired,
+-      afs_flock_callback_break,
+-      afs_flock_defer_unlock,
+-      afs_flock_extend_fail,
+-      afs_flock_fail_other,
+-      afs_flock_fail_perm,
+-      afs_flock_no_lockers,
+-      afs_flock_release_fail,
+-      afs_flock_silly_delete,
+-      afs_flock_timestamp,
+-      afs_flock_try_to_lock,
+-      afs_flock_vfs_lock,
+-      afs_flock_vfs_locking,
+-      afs_flock_waited,
+-      afs_flock_waiting,
+-      afs_flock_work_extending,
+-      afs_flock_work_retry,
+-      afs_flock_work_unlocking,
+-      afs_flock_would_block,
+-};
+-
+-enum afs_flock_operation {
+-      afs_flock_op_copy_lock,
+-      afs_flock_op_flock,
+-      afs_flock_op_grant,
+-      afs_flock_op_lock,
+-      afs_flock_op_release_lock,
+-      afs_flock_op_return_ok,
+-      afs_flock_op_return_eagain,
+-      afs_flock_op_return_edeadlk,
+-      afs_flock_op_return_error,
+-      afs_flock_op_set_lock,
+-      afs_flock_op_unlock,
+-      afs_flock_op_wake,
+-};
+-
+-enum afs_cb_break_reason {
+-      afs_cb_break_no_break,
+-      afs_cb_break_no_promise,
+-      afs_cb_break_for_callback,
+-      afs_cb_break_for_deleted,
+-      afs_cb_break_for_lapsed,
+-      afs_cb_break_for_s_reinit,
+-      afs_cb_break_for_unlink,
+-      afs_cb_break_for_v_break,
+-      afs_cb_break_for_volume_callback,
+-      afs_cb_break_for_zap,
+-};
+-
+ #endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */
+ /*
+@@ -391,6 +185,7 @@ enum afs_cb_break_reason {
+       EM(afs_cell_trace_unuse_fc,             "UNU fc    ") \
+       EM(afs_cell_trace_unuse_lookup,         "UNU lookup") \
+       EM(afs_cell_trace_unuse_mntpt,          "UNU mntpt ") \
++      EM(afs_cell_trace_unuse_no_pin,         "UNU no-pin") \
+       EM(afs_cell_trace_unuse_parse,          "UNU parse ") \
+       EM(afs_cell_trace_unuse_pin,            "UNU pin   ") \
+       EM(afs_cell_trace_unuse_probe,          "UNU probe ") \
+@@ -614,6 +409,32 @@ enum afs_cb_break_reason {
+       EM(afs_cb_break_for_volume_callback,    "break-v-cb")           \
+       E_(afs_cb_break_for_zap,                "break-zap")
++/*
++ * Generate enums for tracing information.
++ */
++#ifndef __AFS_GENERATE_TRACE_ENUMS_ONCE_ONLY
++#define __AFS_GENERATE_TRACE_ENUMS_ONCE_ONLY
++
++#undef EM
++#undef E_
++#define EM(a, b) a,
++#define E_(a, b) a
++
++enum afs_call_trace           { afs_call_traces } __mode(byte);
++enum afs_cb_break_reason      { afs_cb_break_reasons } __mode(byte);
++enum afs_cell_trace           { afs_cell_traces } __mode(byte);
++enum afs_edit_dir_op          { afs_edit_dir_ops } __mode(byte);
++enum afs_edit_dir_reason      { afs_edit_dir_reasons } __mode(byte);
++enum afs_eproto_cause         { afs_eproto_causes } __mode(byte);
++enum afs_file_error           { afs_file_errors } __mode(byte);
++enum afs_flock_event          { afs_flock_events } __mode(byte);
++enum afs_flock_operation      { afs_flock_operations } __mode(byte);
++enum afs_io_error             { afs_io_errors } __mode(byte);
++enum afs_server_trace         { afs_server_traces } __mode(byte);
++enum afs_volume_trace         { afs_volume_traces } __mode(byte);
++
++#endif /* end __AFS_GENERATE_TRACE_ENUMS_ONCE_ONLY */
++
+ /*
+  * Export enum symbols via userspace.
+  */
+-- 
+2.43.0
+
diff --git a/queue-6.6/afs-fix-missing-subdir-edit-when-renamed-between-par.patch b/queue-6.6/afs-fix-missing-subdir-edit-when-renamed-between-par.patch
new file mode 100644 (file)
index 0000000..4a1210b
--- /dev/null
@@ -0,0 +1,256 @@
+From 7df0f2fd2240752a346d3822e02f388920074f3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 11:40:10 +0100
+Subject: afs: Fix missing subdir edit when renamed between parent dirs
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 247d65fb122ad560be1c8c4d87d7374fb28b0770 ]
+
+When rename moves an AFS subdirectory between parent directories, the
+subdir also needs a bit of editing: the ".." entry needs updating to point
+to the new parent (though I don't make use of the info) and the DV needs
+incrementing by 1 to reflect the change of content.  The server also sends
+a callback break notification on the subdirectory if we have one, but we
+can take care of recovering the promise next time we access the subdir.
+
+This can be triggered by something like:
+
+    mount -t afs %example.com:xfstest.test20 /xfstest.test/
+    mkdir /xfstest.test/{aaa,bbb,aaa/ccc}
+    touch /xfstest.test/bbb/ccc/d
+    mv /xfstest.test/{aaa/ccc,bbb/ccc}
+    touch /xfstest.test/bbb/ccc/e
+
+When the pathwalk for the second touch hits "ccc", kafs spots that the DV
+is incorrect and downloads it again (so the fix is not critical).
+
+Fix this, if the rename target is a directory and the old and new
+parents are different, by:
+
+ (1) Incrementing the DV number of the target locally.
+
+ (2) Editing the ".." entry in the target to refer to its new parent's
+     vnode ID and uniquifier.
+
+Link: https://lore.kernel.org/r/3340431.1729680010@warthog.procyon.org.uk
+Fixes: 63a4681ff39c ("afs: Locally edit directory data for mkdir/create/unlink/...")
+cc: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/dir.c               | 25 +++++++++++
+ fs/afs/dir_edit.c          | 91 +++++++++++++++++++++++++++++++++++++-
+ fs/afs/internal.h          |  2 +
+ include/trace/events/afs.h |  7 ++-
+ 4 files changed, 122 insertions(+), 3 deletions(-)
+
+diff --git a/fs/afs/dir.c b/fs/afs/dir.c
+index 5219182e52e1a..897569e1d3a90 100644
+--- a/fs/afs/dir.c
++++ b/fs/afs/dir.c
+@@ -12,6 +12,7 @@
+ #include <linux/swap.h>
+ #include <linux/ctype.h>
+ #include <linux/sched.h>
++#include <linux/iversion.h>
+ #include <linux/task_io_accounting_ops.h>
+ #include "internal.h"
+ #include "afs_fs.h"
+@@ -1809,6 +1810,8 @@ static int afs_symlink(struct mnt_idmap *idmap, struct inode *dir,
+ static void afs_rename_success(struct afs_operation *op)
+ {
++      struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry));
++
+       _enter("op=%08x", op->debug_id);
+       op->ctime = op->file[0].scb.status.mtime_client;
+@@ -1818,6 +1821,22 @@ static void afs_rename_success(struct afs_operation *op)
+               op->ctime = op->file[1].scb.status.mtime_client;
+               afs_vnode_commit_status(op, &op->file[1]);
+       }
++
++      /* If we're moving a subdir between dirs, we need to update
++       * its DV counter too as the ".." will be altered.
++       */
++      if (S_ISDIR(vnode->netfs.inode.i_mode) &&
++          op->file[0].vnode != op->file[1].vnode) {
++              u64 new_dv;
++
++              write_seqlock(&vnode->cb_lock);
++
++              new_dv = vnode->status.data_version + 1;
++              vnode->status.data_version = new_dv;
++              inode_set_iversion_raw(&vnode->netfs.inode, new_dv);
++
++              write_sequnlock(&vnode->cb_lock);
++      }
+ }
+ static void afs_rename_edit_dir(struct afs_operation *op)
+@@ -1859,6 +1878,12 @@ static void afs_rename_edit_dir(struct afs_operation *op)
+                                &vnode->fid, afs_edit_dir_for_rename_2);
+       }
++      if (S_ISDIR(vnode->netfs.inode.i_mode) &&
++          new_dvnode != orig_dvnode &&
++          test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
++              afs_edit_dir_update_dotdot(vnode, new_dvnode,
++                                         afs_edit_dir_for_rename_sub);
++
+       new_inode = d_inode(new_dentry);
+       if (new_inode) {
+               spin_lock(&new_inode->i_lock);
+diff --git a/fs/afs/dir_edit.c b/fs/afs/dir_edit.c
+index e2fa577b66fe0..1dcc75fd0cee3 100644
+--- a/fs/afs/dir_edit.c
++++ b/fs/afs/dir_edit.c
+@@ -127,10 +127,10 @@ static struct folio *afs_dir_get_folio(struct afs_vnode *vnode, pgoff_t index)
+ /*
+  * Scan a directory block looking for a dirent of the right name.
+  */
+-static int afs_dir_scan_block(union afs_xdr_dir_block *block, struct qstr *name,
++static int afs_dir_scan_block(const union afs_xdr_dir_block *block, const struct qstr *name,
+                             unsigned int blocknum)
+ {
+-      union afs_xdr_dirent *de;
++      const union afs_xdr_dirent *de;
+       u64 bitmap;
+       int d, len, n;
+@@ -492,3 +492,90 @@ void afs_edit_dir_remove(struct afs_vnode *vnode,
+       clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
+       goto out_unmap;
+ }
++
++/*
++ * Edit a subdirectory that has been moved between directories to update the
++ * ".." entry.
++ */
++void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
++                              enum afs_edit_dir_reason why)
++{
++      union afs_xdr_dir_block *block;
++      union afs_xdr_dirent *de;
++      struct folio *folio;
++      unsigned int nr_blocks, b;
++      pgoff_t index;
++      loff_t i_size;
++      int slot;
++
++      _enter("");
++
++      i_size = i_size_read(&vnode->netfs.inode);
++      if (i_size < AFS_DIR_BLOCK_SIZE) {
++              clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
++              return;
++      }
++      nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
++
++      /* Find a block that has sufficient slots available.  Each folio
++       * contains two or more directory blocks.
++       */
++      for (b = 0; b < nr_blocks; b++) {
++              index = b / AFS_DIR_BLOCKS_PER_PAGE;
++              folio = afs_dir_get_folio(vnode, index);
++              if (!folio)
++                      goto error;
++
++              block = kmap_local_folio(folio, b * AFS_DIR_BLOCK_SIZE - folio_pos(folio));
++
++              /* Abandon the edit if we got a callback break. */
++              if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
++                      goto invalidated;
++
++              slot = afs_dir_scan_block(block, &dotdot_name, b);
++              if (slot >= 0)
++                      goto found_dirent;
++
++              kunmap_local(block);
++              folio_unlock(folio);
++              folio_put(folio);
++      }
++
++      /* Didn't find the dirent to clobber.  Download the directory again. */
++      trace_afs_edit_dir(vnode, why, afs_edit_dir_update_nodd,
++                         0, 0, 0, 0, "..");
++      clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
++      goto out;
++
++found_dirent:
++      de = &block->dirents[slot];
++      de->u.vnode  = htonl(new_dvnode->fid.vnode);
++      de->u.unique = htonl(new_dvnode->fid.unique);
++
++      trace_afs_edit_dir(vnode, why, afs_edit_dir_update_dd, b, slot,
++                         ntohl(de->u.vnode), ntohl(de->u.unique), "..");
++
++      kunmap_local(block);
++      folio_unlock(folio);
++      folio_put(folio);
++      inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version);
++
++out:
++      _leave("");
++      return;
++
++invalidated:
++      kunmap_local(block);
++      folio_unlock(folio);
++      folio_put(folio);
++      trace_afs_edit_dir(vnode, why, afs_edit_dir_update_inval,
++                         0, 0, 0, 0, "..");
++      clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
++      goto out;
++
++error:
++      trace_afs_edit_dir(vnode, why, afs_edit_dir_update_error,
++                         0, 0, 0, 0, "..");
++      clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
++      goto out;
++}
+diff --git a/fs/afs/internal.h b/fs/afs/internal.h
+index c4bf8439bc9c9..8dcc09cf0adbe 100644
+--- a/fs/afs/internal.h
++++ b/fs/afs/internal.h
+@@ -1037,6 +1037,8 @@ extern void afs_check_for_remote_deletion(struct afs_operation *);
+ extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *,
+                            enum afs_edit_dir_reason);
+ extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
++void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
++                              enum afs_edit_dir_reason why);
+ /*
+  * dir_silly.c
+diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h
+index 54d10c69e55ec..d1ee4272d1cb8 100644
+--- a/include/trace/events/afs.h
++++ b/include/trace/events/afs.h
+@@ -295,7 +295,11 @@ enum yfs_cm_operation {
+       EM(afs_edit_dir_delete,                 "delete") \
+       EM(afs_edit_dir_delete_error,           "d_err ") \
+       EM(afs_edit_dir_delete_inval,           "d_invl") \
+-      E_(afs_edit_dir_delete_noent,           "d_nent")
++      EM(afs_edit_dir_delete_noent,           "d_nent") \
++      EM(afs_edit_dir_update_dd,              "u_ddot") \
++      EM(afs_edit_dir_update_error,           "u_fail") \
++      EM(afs_edit_dir_update_inval,           "u_invl") \
++      E_(afs_edit_dir_update_nodd,            "u_nodd")
+ #define afs_edit_dir_reasons                            \
+       EM(afs_edit_dir_for_create,             "Create") \
+@@ -304,6 +308,7 @@ enum yfs_cm_operation {
+       EM(afs_edit_dir_for_rename_0,           "Renam0") \
+       EM(afs_edit_dir_for_rename_1,           "Renam1") \
+       EM(afs_edit_dir_for_rename_2,           "Renam2") \
++      EM(afs_edit_dir_for_rename_sub,         "RnmSub") \
+       EM(afs_edit_dir_for_rmdir,              "RmDir ") \
+       EM(afs_edit_dir_for_silly_0,            "S_Ren0") \
+       EM(afs_edit_dir_for_silly_1,            "S_Ren1") \
+-- 
+2.43.0
+
diff --git a/queue-6.6/firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch b/queue-6.6/firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch
new file mode 100644 (file)
index 0000000..0e5db69
--- /dev/null
@@ -0,0 +1,38 @@
+From 457296957ee93e1ad4937a4ea98a951f44e570b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 16:47:40 +0800
+Subject: firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit c83212d79be2c9886d3e6039759ecd388fd5fed1 ]
+
+In sdei_device_freeze(), the input parameter of cpuhp_remove_state() is
+passed as 'sdei_entry_point' by mistake. Change it to 'sdei_hp_state'.
+
+Fixes: d2c48b2387eb ("firmware: arm_sdei: Fix sleep from invalid context BUG")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Reviewed-by: James Morse <james.morse@arm.com>
+Link: https://lore.kernel.org/r/20241016084740.183353-1-wangxiongfeng2@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_sdei.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
+index 285fe7ad490d1..3e8051fe82965 100644
+--- a/drivers/firmware/arm_sdei.c
++++ b/drivers/firmware/arm_sdei.c
+@@ -763,7 +763,7 @@ static int sdei_device_freeze(struct device *dev)
+       int err;
+       /* unregister private events */
+-      cpuhp_remove_state(sdei_entry_point);
++      cpuhp_remove_state(sdei_hp_state);
+       err = sdei_unregister_shared();
+       if (err)
+-- 
+2.43.0
+
diff --git a/queue-6.6/fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch b/queue-6.6/fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch
new file mode 100644 (file)
index 0000000..e2687c5
--- /dev/null
@@ -0,0 +1,112 @@
+From 444ecb5626d5ad6c33b5093369a063af548c837d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 08:09:48 -0700
+Subject: fsdax: dax_unshare_iter needs to copy entire blocks
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit 50793801fc7f6d08def48754fb0f0706b0cfc394 ]
+
+The code that copies data from srcmap to iomap in dax_unshare_iter is
+very very broken, which bfoster's recent fsx changes have exposed.
+
+If the pos and len passed to dax_file_unshare are not aligned to an
+fsblock boundary, the iter pos and length in the _iter function will
+reflect this unalignment.
+
+dax_iomap_direct_access always returns a pointer to the start of the
+kmapped fsdax page, even if its pos argument is in the middle of that
+page.  This is catastrophic for data integrity when iter->pos is not
+aligned to a page, because daddr/saddr do not point to the same byte in
+the file as iter->pos.  Hence we corrupt user data by copying it to the
+wrong place.
+
+If iter->pos + iomap_length() in the _iter function not aligned to a
+page, then we fail to copy a full block, and only partially populate the
+destination block.  This is catastrophic for data confidentiality
+because we expose stale pmem contents.
+
+Fix both of these issues by aligning copy_pos/copy_len to a page
+boundary (remember, this is fsdax so 1 fsblock == 1 base page) so that
+we always copy full blocks.
+
+We're not done yet -- there's no call to invalidate_inode_pages2_range,
+so programs that have the file range mmap'd will continue accessing the
+old memory mapping after the file metadata updates have completed.
+
+Be careful with the return value -- if the unshare succeeds, we still
+need to return the number of bytes that the iomap iter thinks we're
+operating on.
+
+Cc: ruansy.fnst@fujitsu.com
+Fixes: d984648e428b ("fsdax,xfs: port unshare to fsdax")
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Link: https://lore.kernel.org/r/172796813328.1131942.16777025316348797355.stgit@frogsfrogsfrogs
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dax.c | 34 +++++++++++++++++++++++++++-------
+ 1 file changed, 27 insertions(+), 7 deletions(-)
+
+diff --git a/fs/dax.c b/fs/dax.c
+index 5e7fc5017570d..8c09578fa0357 100644
+--- a/fs/dax.c
++++ b/fs/dax.c
+@@ -1262,26 +1262,46 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
+ {
+       struct iomap *iomap = &iter->iomap;
+       const struct iomap *srcmap = iomap_iter_srcmap(iter);
+-      loff_t pos = iter->pos;
+-      loff_t length = iomap_length(iter);
++      loff_t copy_pos = iter->pos;
++      u64 copy_len = iomap_length(iter);
++      u32 mod;
+       int id = 0;
+       s64 ret = 0;
+       void *daddr = NULL, *saddr = NULL;
+       if (!iomap_want_unshare_iter(iter))
+-              return length;
++              return iomap_length(iter);
++
++      /*
++       * Extend the file range to be aligned to fsblock/pagesize, because
++       * we need to copy entire blocks, not just the byte range specified.
++       * Invalidate the mapping because we're about to CoW.
++       */
++      mod = offset_in_page(copy_pos);
++      if (mod) {
++              copy_len += mod;
++              copy_pos -= mod;
++      }
++
++      mod = offset_in_page(copy_pos + copy_len);
++      if (mod)
++              copy_len += PAGE_SIZE - mod;
++
++      invalidate_inode_pages2_range(iter->inode->i_mapping,
++                                    copy_pos >> PAGE_SHIFT,
++                                    (copy_pos + copy_len - 1) >> PAGE_SHIFT);
+       id = dax_read_lock();
+-      ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL);
++      ret = dax_iomap_direct_access(iomap, copy_pos, copy_len, &daddr, NULL);
+       if (ret < 0)
+               goto out_unlock;
+-      ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL);
++      ret = dax_iomap_direct_access(srcmap, copy_pos, copy_len, &saddr, NULL);
+       if (ret < 0)
+               goto out_unlock;
+-      if (copy_mc_to_kernel(daddr, saddr, length) == 0)
+-              ret = length;
++      if (copy_mc_to_kernel(daddr, saddr, copy_len) == 0)
++              ret = iomap_length(iter);
+       else
+               ret = -EIO;
+-- 
+2.43.0
+
diff --git a/queue-6.6/fsdax-remove-zeroing-code-from-dax_unshare_iter.patch b/queue-6.6/fsdax-remove-zeroing-code-from-dax_unshare_iter.patch
new file mode 100644 (file)
index 0000000..b56ef13
--- /dev/null
@@ -0,0 +1,55 @@
+From f999b8de8213e3a2349ead2f8705bc8ff7316e52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 08:09:32 -0700
+Subject: fsdax: remove zeroing code from dax_unshare_iter
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit 95472274b6fed8f2d30fbdda304e12174b3d4099 ]
+
+Remove the code in dax_unshare_iter that zeroes the destination memory
+because it's not necessary.
+
+If srcmap is unwritten, we don't have to do anything because that
+unwritten extent came from the regular file mapping, and unwritten
+extents cannot be shared.  The same applies to holes.
+
+Furthermore, zeroing to unshare a mapping is just plain wrong because
+unsharing means copy on write, and we should be copying data.
+
+This is effectively a revert of commit 13dd4e04625f ("fsdax: unshare:
+zero destination if srcmap is HOLE or UNWRITTEN")
+
+Cc: ruansy.fnst@fujitsu.com
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Link: https://lore.kernel.org/r/172796813311.1131942.16033376284752798632.stgit@frogsfrogsfrogs
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dax.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/fs/dax.c b/fs/dax.c
+index 2f7f5e2d167dd..5e7fc5017570d 100644
+--- a/fs/dax.c
++++ b/fs/dax.c
+@@ -1276,14 +1276,6 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
+       if (ret < 0)
+               goto out_unlock;
+-      /* zero the distance if srcmap is HOLE or UNWRITTEN */
+-      if (srcmap->flags & IOMAP_F_SHARED || srcmap->type == IOMAP_UNWRITTEN) {
+-              memset(daddr, 0, length);
+-              dax_flush(iomap->dax_dev, daddr, length);
+-              ret = length;
+-              goto out_unlock;
+-      }
+-
+       ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL);
+       if (ret < 0)
+               goto out_unlock;
+-- 
+2.43.0
+
diff --git a/queue-6.6/iomap-don-t-bother-unsharing-delalloc-extents.patch b/queue-6.6/iomap-don-t-bother-unsharing-delalloc-extents.patch
new file mode 100644 (file)
index 0000000..33fe2cd
--- /dev/null
@@ -0,0 +1,48 @@
+From 9e3cf70955635c522ce983e3700079fa4248c220 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Oct 2024 08:00:40 -0700
+Subject: iomap: don't bother unsharing delalloc extents
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit f7a4874d977bf4202ad575031222e78809a36292 ]
+
+If unshare encounters a delalloc reservation in the srcmap, that means
+that the file range isn't shared because delalloc reservations cannot be
+reflinked.  Therefore, don't try to unshare them.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Link: https://lore.kernel.org/r/20241002150040.GB21853@frogsfrogsfrogs
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index 7db9bb0d15184..eb65953895d24 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1282,7 +1282,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
+               return length;
+       /*
+-       * Don't bother with holes or unwritten extents.
++       * Don't bother with delalloc reservations, holes or unwritten extents.
+        *
+        * Note that we use srcmap directly instead of iomap_iter_srcmap as
+        * unsharing requires providing a separate source map, and the presence
+@@ -1291,6 +1291,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
+        * fork for XFS.
+        */
+       if (iter->srcmap.type == IOMAP_HOLE ||
++          iter->srcmap.type == IOMAP_DELALLOC ||
+           iter->srcmap.type == IOMAP_UNWRITTEN)
+               return length;
+-- 
+2.43.0
+
diff --git a/queue-6.6/iomap-improve-shared-block-detection-in-iomap_unshar.patch b/queue-6.6/iomap-improve-shared-block-detection-in-iomap_unshar.patch
new file mode 100644 (file)
index 0000000..f035b0b
--- /dev/null
@@ -0,0 +1,69 @@
+From dfafa4fca7837adbf72f36d026f6607e042cbc30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 07:39:04 +0300
+Subject: iomap: improve shared block detection in iomap_unshare_iter
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit b53fdb215d13f8e9c29541434bf2d14dac8bcbdc ]
+
+Currently iomap_unshare_iter relies on the IOMAP_F_SHARED flag to detect
+blocks to unshare.  This is reasonable, but IOMAP_F_SHARED is also useful
+for the file system to do internal book keeping for out of place writes.
+XFS used to that, until it got removed in commit 72a048c1056a
+("xfs: only set IOMAP_F_SHARED when providing a srcmap to a write")
+because unshare for incorrectly unshare such blocks.
+
+Add an extra safeguard by checking the explicitly provided srcmap instead
+of the fallback to the iomap for valid data, as that catches the case
+where we'd just copy from the same place we'd write to easily, allowing
+to reinstate setting IOMAP_F_SHARED for all XFS writes that go to the
+COW fork.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20240910043949.3481298-3-hch@lst.de
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index aedaad4c37d75..7db9bb0d15184 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1273,16 +1273,25 @@ EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc);
+ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
+ {
+       struct iomap *iomap = &iter->iomap;
+-      const struct iomap *srcmap = iomap_iter_srcmap(iter);
+       loff_t pos = iter->pos;
+       loff_t length = iomap_length(iter);
+       loff_t written = 0;
+-      /* don't bother with blocks that are not shared to start with */
++      /* Don't bother with blocks that are not shared to start with. */
+       if (!(iomap->flags & IOMAP_F_SHARED))
+               return length;
+-      /* don't bother with holes or unwritten extents */
+-      if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN)
++
++      /*
++       * Don't bother with holes or unwritten extents.
++       *
++       * Note that we use srcmap directly instead of iomap_iter_srcmap as
++       * unsharing requires providing a separate source map, and the presence
++       * of one is a good indicator that unsharing is needed, unlike
++       * IOMAP_F_SHARED which can be set for any data that goes into the COW
++       * fork for XFS.
++       */
++      if (iter->srcmap.type == IOMAP_HOLE ||
++          iter->srcmap.type == IOMAP_UNWRITTEN)
+               return length;
+       do {
+-- 
+2.43.0
+
diff --git a/queue-6.6/iomap-share-iomap_unshare_iter-predicate-code-with-f.patch b/queue-6.6/iomap-share-iomap_unshare_iter-predicate-code-with-f.patch
new file mode 100644 (file)
index 0000000..bde3f94
--- /dev/null
@@ -0,0 +1,111 @@
+From 693837adc33f151fa3b3b9aba21426b7f278ee31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 08:09:16 -0700
+Subject: iomap: share iomap_unshare_iter predicate code with fsdax
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit 6ef6a0e821d3dad6bf8a5d5508762dba9042c84b ]
+
+The predicate code that iomap_unshare_iter uses to decide if it's really
+needs to unshare a file range mapping should be shared with the fsdax
+version, because right now they're opencoded and inconsistent.
+
+Note that we simplify the predicate logic a bit -- we no longer allow
+unsharing of inline data mappings, but there aren't any filesystems that
+allow shared inline data currently.
+
+This is a fix in the sense that it should have been ported to fsdax.
+
+Fixes: b53fdb215d13 ("iomap: improve shared block detection in iomap_unshare_iter")
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Link: https://lore.kernel.org/r/172796813294.1131942.15762084021076932620.stgit@frogsfrogsfrogs
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dax.c               |  3 +--
+ fs/iomap/buffered-io.c | 30 ++++++++++++++++--------------
+ include/linux/iomap.h  |  1 +
+ 3 files changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/fs/dax.c b/fs/dax.c
+index d48b4fc7a4838..2f7f5e2d167dd 100644
+--- a/fs/dax.c
++++ b/fs/dax.c
+@@ -1268,8 +1268,7 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
+       s64 ret = 0;
+       void *daddr = NULL, *saddr = NULL;
+-      /* don't bother with blocks that are not shared to start with */
+-      if (!(iomap->flags & IOMAP_F_SHARED))
++      if (!iomap_want_unshare_iter(iter))
+               return length;
+       id = dax_read_lock();
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index eb65953895d24..55619cce05422 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1270,19 +1270,12 @@ int iomap_file_buffered_write_punch_delalloc(struct inode *inode,
+ }
+ EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc);
+-static loff_t iomap_unshare_iter(struct iomap_iter *iter)
++bool iomap_want_unshare_iter(const struct iomap_iter *iter)
+ {
+-      struct iomap *iomap = &iter->iomap;
+-      loff_t pos = iter->pos;
+-      loff_t length = iomap_length(iter);
+-      loff_t written = 0;
+-
+-      /* Don't bother with blocks that are not shared to start with. */
+-      if (!(iomap->flags & IOMAP_F_SHARED))
+-              return length;
+-
+       /*
+-       * Don't bother with delalloc reservations, holes or unwritten extents.
++       * Don't bother with blocks that are not shared to start with; or
++       * mappings that cannot be shared, such as inline data, delalloc
++       * reservations, holes or unwritten extents.
+        *
+        * Note that we use srcmap directly instead of iomap_iter_srcmap as
+        * unsharing requires providing a separate source map, and the presence
+@@ -1290,9 +1283,18 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
+        * IOMAP_F_SHARED which can be set for any data that goes into the COW
+        * fork for XFS.
+        */
+-      if (iter->srcmap.type == IOMAP_HOLE ||
+-          iter->srcmap.type == IOMAP_DELALLOC ||
+-          iter->srcmap.type == IOMAP_UNWRITTEN)
++      return (iter->iomap.flags & IOMAP_F_SHARED) &&
++              iter->srcmap.type == IOMAP_MAPPED;
++}
++
++static loff_t iomap_unshare_iter(struct iomap_iter *iter)
++{
++      struct iomap *iomap = &iter->iomap;
++      loff_t pos = iter->pos;
++      loff_t length = iomap_length(iter);
++      loff_t written = 0;
++
++      if (!iomap_want_unshare_iter(iter))
+               return length;
+       do {
+diff --git a/include/linux/iomap.h b/include/linux/iomap.h
+index 96dd0acbba44a..846cd2f1454c7 100644
+--- a/include/linux/iomap.h
++++ b/include/linux/iomap.h
+@@ -271,6 +271,7 @@ void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len);
+ bool iomap_dirty_folio(struct address_space *mapping, struct folio *folio);
+ int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
+               const struct iomap_ops *ops);
++bool iomap_want_unshare_iter(const struct iomap_iter *iter);
+ int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len,
+               bool *did_zero, const struct iomap_ops *ops);
+ int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
+-- 
+2.43.0
+
diff --git a/queue-6.6/iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch b/queue-6.6/iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch
new file mode 100644 (file)
index 0000000..4b13763
--- /dev/null
@@ -0,0 +1,98 @@
+From 147dfdc40833466d15538ea55735c035c7efe407 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 06:13:50 +0200
+Subject: iomap: turn iomap_want_unshare_iter into an inline function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 6db388585e486c0261aeef55f8bc63a9b45756c0 ]
+
+iomap_want_unshare_iter currently sits in fs/iomap/buffered-io.c, which
+depends on CONFIG_BLOCK.  It is also in used in fs/dax.c whіch has no
+such dependency.  Given that it is a trivial check turn it into an inline
+in include/linux/iomap.h to fix the DAX && !BLOCK build.
+
+Fixes: 6ef6a0e821d3 ("iomap: share iomap_unshare_iter predicate code with fsdax")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20241015041350.118403-1-hch@lst.de
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c | 17 -----------------
+ include/linux/iomap.h  | 20 +++++++++++++++++++-
+ 2 files changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index 55619cce05422..a05ee2cbb7793 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1270,23 +1270,6 @@ int iomap_file_buffered_write_punch_delalloc(struct inode *inode,
+ }
+ EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc);
+-bool iomap_want_unshare_iter(const struct iomap_iter *iter)
+-{
+-      /*
+-       * Don't bother with blocks that are not shared to start with; or
+-       * mappings that cannot be shared, such as inline data, delalloc
+-       * reservations, holes or unwritten extents.
+-       *
+-       * Note that we use srcmap directly instead of iomap_iter_srcmap as
+-       * unsharing requires providing a separate source map, and the presence
+-       * of one is a good indicator that unsharing is needed, unlike
+-       * IOMAP_F_SHARED which can be set for any data that goes into the COW
+-       * fork for XFS.
+-       */
+-      return (iter->iomap.flags & IOMAP_F_SHARED) &&
+-              iter->srcmap.type == IOMAP_MAPPED;
+-}
+-
+ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
+ {
+       struct iomap *iomap = &iter->iomap;
+diff --git a/include/linux/iomap.h b/include/linux/iomap.h
+index 846cd2f1454c7..47b81ebf6e598 100644
+--- a/include/linux/iomap.h
++++ b/include/linux/iomap.h
+@@ -256,6 +256,25 @@ static inline const struct iomap *iomap_iter_srcmap(const struct iomap_iter *i)
+       return &i->iomap;
+ }
++/*
++ * Check if the range needs to be unshared for a FALLOC_FL_UNSHARE_RANGE
++ * operation.
++ *
++ * Don't bother with blocks that are not shared to start with; or mappings that
++ * cannot be shared, such as inline data, delalloc reservations, holes or
++ * unwritten extents.
++ *
++ * Note that we use srcmap directly instead of iomap_iter_srcmap as unsharing
++ * requires providing a separate source map, and the presence of one is a good
++ * indicator that unsharing is needed, unlike IOMAP_F_SHARED which can be set
++ * for any data that goes into the COW fork for XFS.
++ */
++static inline bool iomap_want_unshare_iter(const struct iomap_iter *iter)
++{
++      return (iter->iomap.flags & IOMAP_F_SHARED) &&
++              iter->srcmap.type == IOMAP_MAPPED;
++}
++
+ ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from,
+               const struct iomap_ops *ops);
+ int iomap_file_buffered_write_punch_delalloc(struct inode *inode,
+@@ -271,7 +290,6 @@ void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len);
+ bool iomap_dirty_folio(struct address_space *mapping, struct folio *folio);
+ int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
+               const struct iomap_ops *ops);
+-bool iomap_want_unshare_iter(const struct iomap_iter *iter);
+ int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len,
+               bool *did_zero, const struct iomap_ops *ops);
+ int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
+-- 
+2.43.0
+
diff --git a/queue-6.6/kasan-fix-software-tag-based-kasan-with-gcc.patch b/queue-6.6/kasan-fix-software-tag-based-kasan-with-gcc.patch
new file mode 100644 (file)
index 0000000..6aee8f4
--- /dev/null
@@ -0,0 +1,53 @@
+From 7fe55ed7e63fa084c883d8abd1857ab7fa1f0867 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 14:00:10 +0200
+Subject: kasan: Fix Software Tag-Based KASAN with GCC
+
+From: Marco Elver <elver@google.com>
+
+[ Upstream commit 894b00a3350c560990638bdf89bdf1f3d5491950 ]
+
+Per [1], -fsanitize=kernel-hwaddress with GCC currently does not disable
+instrumentation in functions with __attribute__((no_sanitize_address)).
+
+However, __attribute__((no_sanitize("hwaddress"))) does correctly
+disable instrumentation. Use it instead.
+
+Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117196 [1]
+Link: https://lore.kernel.org/r/000000000000f362e80620e27859@google.com
+Link: https://lore.kernel.org/r/ZvFGwKfoC4yVjN_X@J2N7QTR9R3
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=218854
+Reported-by: syzbot+908886656a02769af987@syzkaller.appspotmail.com
+Tested-by: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Andrew Pinski <pinskia@gmail.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Marco Elver <elver@google.com>
+Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
+Fixes: 7b861a53e46b ("kasan: Bump required compiler version")
+Link: https://lore.kernel.org/r/20241021120013.3209481-1-elver@google.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/compiler-gcc.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
+index 8c9a095c17571..9e6961078c2aa 100644
+--- a/include/linux/compiler-gcc.h
++++ b/include/linux/compiler-gcc.h
+@@ -102,7 +102,11 @@
+ #define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))
+ #endif
++#ifdef __SANITIZE_HWADDRESS__
++#define __no_sanitize_address __attribute__((__no_sanitize__("hwaddress")))
++#else
+ #define __no_sanitize_address __attribute__((__no_sanitize_address__))
++#endif
+ #if defined(__SANITIZE_THREAD__)
+ #define __no_sanitize_thread __attribute__((__no_sanitize_thread__))
+-- 
+2.43.0
+
index 545621c4c30b41fb5b2c28544f0c1b6e5e8ce8b1..b426676fd5a86f00badb584ccc15a93a4c10ebd8 100644 (file)
@@ -46,3 +46,14 @@ net-hns3-initialize-reset_timer-before-hclgevf_misc_.patch
 net-hns3-fixed-hclge_fetch_pf_reg-accesses-bar-space.patch
 net-hns3-fix-kernel-crash-when-1588-is-sent-on-hip08.patch
 bpf-test_run-fix-live_frame-frame-update-after-a-pag.patch
+iomap-improve-shared-block-detection-in-iomap_unshar.patch
+iomap-don-t-bother-unsharing-delalloc-extents.patch
+iomap-share-iomap_unshare_iter-predicate-code-with-f.patch
+fsdax-remove-zeroing-code-from-dax_unshare_iter.patch
+fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch
+iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch
+kasan-fix-software-tag-based-kasan-with-gcc.patch
+firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch
+afs-automatically-generate-trace-tag-enums.patch
+afs-fix-missing-subdir-edit-when-renamed-between-par.patch
+acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch