From: Sasha Levin Date: Fri, 19 Dec 2025 12:29:46 +0000 (-0500) Subject: Fixes for all trees X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7d1e66a34d636c0995c563a5ff49709c1394488;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch b/queue-5.10/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch new file mode 100644 index 0000000000..0c1cabbaa6 --- /dev/null +++ b/queue-5.10/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch @@ -0,0 +1,59 @@ +From 5d21290569bcaf47b2b014397512ce4cb63af414 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 13:43:19 +0300 +Subject: ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() + only + +From: Sakari Ailus + +[ Upstream commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 ] + +Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode +property API is somewhat problematic as the latter is used in the +impelementation of the former. Instead of using +fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call +acpi_get_next_subnode() directly instead. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20251001104320.1272752-3-sakari.ailus@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 7c3d98fae457d..3a3efd15b8497 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1188,7 +1188,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + + if (!prev) { + do { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + /* + * The names of the port nodes begin with "port@" + * followed by the number of the port node and they also +@@ -1206,13 +1206,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + if (!port) + return NULL; + +- endpoint = fwnode_get_next_child_node(port, prev); ++ endpoint = acpi_get_next_subnode(port, prev); + while (!endpoint) { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + if (!port) + break; + if (is_acpi_graph_node(port, "port")) +- endpoint = fwnode_get_next_child_node(port, NULL); ++ endpoint = acpi_get_next_subnode(port, NULL); + } + + /* +-- +2.51.0 + diff --git a/queue-5.10/acpica-avoid-walking-the-namespace-if-start_node-is-.patch b/queue-5.10/acpica-avoid-walking-the-namespace-if-start_node-is-.patch new file mode 100644 index 0000000000..38ce5fed29 --- /dev/null +++ b/queue-5.10/acpica-avoid-walking-the-namespace-if-start_node-is-.patch @@ -0,0 +1,63 @@ +From 17ef92bac03aaee975c69bbcfdd17250e976ae4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:14:38 +0800 +Subject: ACPICA: Avoid walking the Namespace if start_node is NULL + +From: Cryolitia PukNgae + +[ Upstream commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 ] + +Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace +if it is not there") fixed the situation when both start_node and +acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed +on Honor Magicbook 14 Pro [1]. + +That happens due to the access to the member of parent_node in +acpi_ns_get_next_node(). The NULL pointer dereference will always +happen, no matter whether or not the start_node is equal to +ACPI_ROOT_OBJECT, so move the check of start_node being NULL +out of the if block. + +Unfortunately, all the attempts to contact Honor have failed, they +refused to provide any technical support for Linux. + +The bad DSDT table's dump could be found on GitHub [2]. + +DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025 + +Link: https://github.com/acpica/acpica/commit/1c1b57b9eba4554cb132ee658dd942c0210ed20d +Link: https://gist.github.com/Cryolitia/a860ffc97437dcd2cd988371d5b73ed7 [1] +Link: https://github.com/denis-bb/honor-fmb-p-dsdt [2] +Signed-off-by: Cryolitia PukNgae +Reviewed-by: WangYuli +[ rjw: Subject adjustment, changelog edits ] +Link: https://patch.msgid.link/20251125-acpica-v1-1-99e63b1b25f8@linux.dev +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/nswalk.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c +index 901fa5ca284d2..91c4dc9026bf1 100644 +--- a/drivers/acpi/acpica/nswalk.c ++++ b/drivers/acpi/acpica/nswalk.c +@@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type, + + if (start_node == ACPI_ROOT_OBJECT) { + start_node = acpi_gbl_root_node; +- if (!start_node) { +- return_ACPI_STATUS(AE_NO_NAMESPACE); +- } ++ } ++ ++ /* Avoid walking the namespace if the StartNode is NULL */ ++ ++ if (!start_node) { ++ return_ACPI_STATUS(AE_NO_NAMESPACE); + } + + /* Null child means "get first node" */ +-- +2.51.0 + diff --git a/queue-5.10/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch b/queue-5.10/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch new file mode 100644 index 0000000000..f3b4a5a9ab --- /dev/null +++ b/queue-5.10/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch @@ -0,0 +1,67 @@ +From 4852463adc9c85eb8f230acb6b98db860366a2b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 15:33:38 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE + +From: Gongwei Li + +[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ] + +Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3533 Rev= 1.10 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Gongwei Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 155eaaf0485a1..c5e4f675270c2 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -396,6 +396,8 @@ static const struct usb_device_id blacklist_table[] = { + /* Realtek 8821CE Bluetooth devices */ + { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-5.10/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch b/queue-5.10/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch new file mode 100644 index 0000000000..5bc11098d8 --- /dev/null +++ b/queue-5.10/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch @@ -0,0 +1,56 @@ +From 7019ecb58cd01932e728e9fb4bc3cbe6f8a897d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Dec 2025 13:59:16 +0100 +Subject: bpf, arm64: Do not audit capability check in do_jit() + +From: Ondrej Mosnacek + +[ Upstream commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c ] + +Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit +capability check in do_jit()"), change the capable() call to +ns_capable_noaudit() in order to avoid spurious SELinux denials in audit +log. + +The commit log from that commit applies here as well: +""" +The failure of this check only results in a security mitigation being +applied, slightly affecting performance of the compiled BPF program. It +doesn't result in a failed syscall, an thus auditing a failed LSM +permission check for it is unwanted. For example with SELinux, it causes +a denial to be reported for confined processes running as root, which +tends to be flagged as a problem to be fixed in the policy. Yet +dontauditing or allowing CAP_SYS_ADMIN to the domain may not be +desirable, as it would allow/silence also other checks - either going +against the principle of least privilege or making debugging potentially +harder. + +Fix it by changing it from capable() to ns_capable_noaudit(), which +instructs the LSMs to not audit the resulting denials. +""" + +Fixes: f300769ead03 ("arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users") +Signed-off-by: Ondrej Mosnacek +Link: https://lore.kernel.org/r/20251204125916.441021-1-omosnace@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + arch/arm64/net/bpf_jit_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index 970d8f318177c..e98fe8c006cc9 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -342,7 +342,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) + arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) + return; + +- if (capable(CAP_SYS_ADMIN)) ++ if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) + return; + + if (supports_clearbhb(SCOPE_SYSTEM)) { +-- +2.51.0 + diff --git a/queue-5.10/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch b/queue-5.10/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch new file mode 100644 index 0000000000..2194c75a6c --- /dev/null +++ b/queue-5.10/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch @@ -0,0 +1,51 @@ +From a05feeb1df2b277c8af6f7bb73d9179facb16bee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 18:58:07 +0530 +Subject: btrfs: fix memory leak of fs_devices in degraded seed device path + +From: Deepanshu Kartikey + +[ Upstream commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 ] + +In open_seed_devices(), when find_fsid() fails and we're in DEGRADED +mode, a new fs_devices is allocated via alloc_fs_devices() but is never +added to the seed_list before returning. This contrasts with the normal +path where fs_devices is properly added via list_add(). + +If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), +the cleanup code iterates seed_list to free seed devices, but this +orphaned fs_devices is never found and never freed, causing a memory +leak. Any devices allocated via add_missing_dev() and attached to this +fs_devices are also leaked. + +Fix this by adding the newly allocated fs_devices to seed_list in the +degraded path, consistent with the normal path. + +Fixes: 5f37583569442 ("Btrfs: move the missing device to its own fs device list") +Reported-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=eadd98df8bceb15d7fed +Tested-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Reviewed-by: Qu Wenruo +Signed-off-by: Deepanshu Kartikey +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/volumes.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 9c1a7b3b84e42..2bba6e8d43740 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -6899,6 +6899,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, + + fs_devices->seeding = true; + fs_devices->opened = 1; ++ list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); + return fs_devices; + } + +-- +2.51.0 + diff --git a/queue-5.10/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch b/queue-5.10/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch new file mode 100644 index 0000000000..b42657c17b --- /dev/null +++ b/queue-5.10/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch @@ -0,0 +1,90 @@ +From 50e38e94c74927b6738bf5246d29bfb97e9f0426 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 12:51:09 +1030 +Subject: btrfs: scrub: always update btrfs_scrub_progress::last_physical + +From: Qu Wenruo + +[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ] + +[BUG] +When a scrub failed immediately without any byte scrubbed, the returned +btrfs_scrub_progress::last_physical will always be 0, even if there is a +non-zero @start passed into btrfs_scrub_dev() for resume cases. + +This will reset the progress and make later scrub resume start from the +beginning. + +[CAUSE] +The function btrfs_scrub_dev() accepts a @progress parameter to copy its +updated progress to the caller, there are cases where we either don't +touch progress::last_physical at all or copy 0 into last_physical: + +- last_physical not updated at all + If some error happened before scrubbing any super block or chunk, we + will not copy the progress, leaving the @last_physical untouched. + + E.g. failed to allocate @sctx, scrubbing a missing device or even + there is already a running scrub and so on. + + All those cases won't touch @progress at all, resulting the + last_physical untouched and will be left as 0 for most cases. + +- Error out before scrubbing any bytes + In those case we allocated @sctx, and sctx->stat.last_physical is all + zero (initialized by kvzalloc()). + Unfortunately some critical errors happened during + scrub_enumerate_chunks() or scrub_supers() before any stripe is really + scrubbed. + + In that case although we will copy sctx->stat back to @progress, since + no byte is really scrubbed, last_physical will be overwritten to 0. + +[FIX] +Make sure the parameter @progress always has its @last_physical member +updated to @start parameter inside btrfs_scrub_dev(). + +At the very beginning of the function, set @progress->last_physical to +@start, so that even if we error out without doing progress copying, +last_physical is still at @start. + +Then after we got @sctx allocated, set sctx->stat.last_physical to +@start, this will make sure even if we didn't get any byte scrubbed, at +the progress copying stage the @last_physical is not left as zero. + +This should resolve the resume progress reset problem. + +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index 715a0329ba277..c8d033deb8ab8 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -3820,6 +3820,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + unsigned int nofs_flag; + bool need_commit = false; + ++ /* Set the basic fallback @last_physical before we got a sctx. */ ++ if (progress) ++ progress->last_physical = start; ++ + if (btrfs_fs_closing(fs_info)) + return -EAGAIN; + +@@ -3864,6 +3868,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + sctx = scrub_setup_ctx(fs_info, is_dev_replace); + if (IS_ERR(sctx)) + return PTR_ERR(sctx); ++ sctx->stat.last_physical = start; + + ret = scrub_workers_get(fs_info, is_dev_replace); + if (ret) +-- +2.51.0 + diff --git a/queue-5.10/cpufreq-s5pv210-fix-refcount-leak.patch b/queue-5.10/cpufreq-s5pv210-fix-refcount-leak.patch new file mode 100644 index 0000000000..9c72c24727 --- /dev/null +++ b/queue-5.10/cpufreq-s5pv210-fix-refcount-leak.patch @@ -0,0 +1,62 @@ +From ba83da62121d8d0702dca75defa9cc255340111c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 03:31:17 +0800 +Subject: cpufreq: s5pv210: fix refcount leak + +From: Shuhao Fu + +[ Upstream commit 2de5cb96060a1664880d65b120e59485a73588a8 ] + +In function `s5pv210_cpu_init`, a possible refcount inconsistency has +been identified, causing a resource leak. + +Why it is a bug: +1. For every clk_get, there should be a matching clk_put on every +successive error handling path. +2. After calling `clk_get(dmc1_clk)`, variable `dmc1_clk` will not be +freed even if any error happens. + +How it is fixed: For every failed path, an extra goto label is added to +ensure `dmc1_clk` will be freed regardlessly. + +Signed-off-by: Shuhao Fu +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c +index bed496cf8d247..f95b4658097a6 100644 +--- a/drivers/cpufreq/s5pv210-cpufreq.c ++++ b/drivers/cpufreq/s5pv210-cpufreq.c +@@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + + if (policy->cpu != 0) { + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* +@@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { + pr_err("CPUFreq doesn't support this memory type\n"); + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* Find current refresh counter and frequency each DMC */ +@@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + cpufreq_generic_init(policy, s5pv210_freq_table, 40000); + return 0; + ++out: ++ clk_put(dmc1_clk); + out_dmc1: + clk_put(dmc0_clk); + out_dmc0: +-- +2.51.0 + diff --git a/queue-5.10/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch b/queue-5.10/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch new file mode 100644 index 0000000000..cb8b95a276 --- /dev/null +++ b/queue-5.10/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch @@ -0,0 +1,91 @@ +From 4cc090dda1480d41d003fe70d35456546454d189 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 17:39:12 +0800 +Subject: hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create + +From: Yang Chenzhi + +[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ] + +When sync() and link() are called concurrently, both threads may +enter hfs_bnode_find() without finding the node in the hash table +and proceed to create it. + +Thread A: + hfsplus_write_inode() + -> hfsplus_write_system_inode() + -> hfs_btree_write() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +Thread B: + hfsplus_create_cat() + -> hfs_brec_insert() + -> hfs_bnode_split() + -> hfs_bmap_alloc() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +In this case, thread A creates the bnode, sets refcnt=1, and hashes it. +Thread B also tries to create the same bnode, notices it has already +been inserted, drops its own instance, and uses the hashed one without +getting the node. + +``` + + node2 = hfs_bnode_findhash(tree, cnid); + if (!node2) { <- Thread A + hash = hfs_bnode_hash(cnid); + node->next_hash = tree->node_hash[hash]; + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { <- Thread B + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, + !test_bit(HFS_BNODE_NEW, &node2->flags)); + return node2; + } +``` + +However, hfs_bnode_find() requires each call to take a reference. +Here both threads end up setting refcnt=1. When they later put the node, +this triggers: + +BUG_ON(!atomic_read(&node->refcnt)) + +In this scenario, Thread B in fact finds the node in the hash table +rather than creating a new one, and thus must take a reference. + +Fix this by calling hfs_bnode_get() when reusing a bnode newly created by +another thread to ensure the refcount is updated correctly. + +A similar bug was fixed in HFS long ago in commit +a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") +but the same issue remained in HFS+ until now. + +Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com +Signed-off-by: Yang Chenzhi +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index 358294726ff17..7c127922ac0c7 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -488,6 +488,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { ++ hfs_bnode_get(node2); + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, +-- +2.51.0 + diff --git a/queue-5.10/hfsplus-fix-volume-corruption-issue-for-generic-070.patch b/queue-5.10/hfsplus-fix-volume-corruption-issue-for-generic-070.patch new file mode 100644 index 0000000000..71d693b27c --- /dev/null +++ b/queue-5.10/hfsplus-fix-volume-corruption-issue-for-generic-070.patch @@ -0,0 +1,122 @@ +From 7e1f708db4e03bffb05ab215c9745bf827311030 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:12:30 -0700 +Subject: hfsplus: fix volume corruption issue for generic/070 + +From: Viacheslav Dubeyko + +[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ] + +The xfstests' test-case generic/070 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent +(see xfstests-dev/results//generic/070.full for details) + +Ran: generic/070 +Failures: generic/070 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop50 +** /dev/loop50 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +Unused node is not erased (node = 1) +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 +CBTStat = 0x0000 CatStat = 0x00000000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume test was repaired successfully. + +It is possible to see that fsck.hfsplus detected not +erased and unused node for the case of extents overflow file. +The HFS+ logic has special method that defines if the node +should be erased: + +bool hfs_bnode_need_zeroout(struct hfs_btree *tree) +{ + struct super_block *sb = tree->inode->i_sb; + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + + return tree->cnid == HFSPLUS_CAT_CNID && + volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; +} + +However, it is possible to see that this method works +only for the case of catalog file. But debugging of the issue +has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been +requested for the extents overflow file too: + +catalog file +kernel: hfsplus: node 4, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800 + +extents overflow file +kernel: hfsplus: node 1, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800 + +This patch modifies the hfs_bnode_need_zeroout() by checking +only volume_attr but not the b-tree ID because node zeroing +can be requested for all HFS+ b-tree types. + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 33s ... 34s +Ran: generic/070 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index e566cea238279..358294726ff17 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -717,6 +717,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + +- return tree->cnid == HFSPLUS_CAT_CNID && +- volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; ++ return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + } +-- +2.51.0 + diff --git a/queue-5.10/hfsplus-fix-volume-corruption-issue-for-generic-073.patch b/queue-5.10/hfsplus-fix-volume-corruption-issue-for-generic-073.patch new file mode 100644 index 0000000000..06ad0d1374 --- /dev/null +++ b/queue-5.10/hfsplus-fix-volume-corruption-issue-for-generic-073.patch @@ -0,0 +1,125 @@ +From 6fe74368dccabd9bab31f680642ba9081406918e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:25:23 -0800 +Subject: hfsplus: fix volume corruption issue for generic/073 + +From: Viacheslav Dubeyko + +[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ] + +The xfstests' test-case generic/073 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent +(see XFSTESTS-2/xfstests-dev/results//generic/073.full for details) + +Ran: generic/073 +Failures: generic/073 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +Invalid directory item count +(It should be 1 instead of 0) +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 +CBTStat = 0x0000 CatStat = 0x00004000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled was repaired successfully. + +The test is doing these steps on final phase: + +mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo + +So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ +logic decrements the number of entries in testdir_1 and increments number of +entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not +for testdir_2. As a result, this is the reason why fsck.hfsplus detects the +volume corruption afterwards. + +This patch fixes the issue by means of adding the +hfsplus_cat_write_inode() call for old_dir and new_dir in +hfsplus_rename() after the successful ending of +hfsplus_rename_cat(). This method makes modification of in-core +inode objects for old_dir and new_dir but it doesn't save these +modifications in Catalog File's entries. It was expected that +hfsplus_write_inode() will save these modifications afterwards. +However, because generic/073 does fsync only for testdir_1 and foo +then testdir_2 modification hasn't beed saved into Catalog File's +entry and it was flushed without this modification. And it was +detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog +File all modified entries and correct state of Catalog File will +be flushed during hfsplus_file_fsync() call. Finally, it makes +fsck.hfsplus happy. + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 32s ... 32s +Ran: generic/073 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/dir.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c +index 29a9dcfbe81f7..292cc06206a10 100644 +--- a/fs/hfsplus/dir.c ++++ b/fs/hfsplus/dir.c +@@ -550,8 +550,13 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, + res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, + old_dir, &old_dentry->d_name, + new_dir, &new_dentry->d_name); +- if (!res) ++ if (!res) { + new_dentry->d_fsdata = old_dentry->d_fsdata; ++ ++ res = hfsplus_cat_write_inode(old_dir); ++ if (!res) ++ res = hfsplus_cat_write_inode(new_dir); ++ } + return res; + } + +-- +2.51.0 + diff --git a/queue-5.10/hfsplus-verify-inode-mode-when-loading-from-disk.patch b/queue-5.10/hfsplus-verify-inode-mode-when-loading-from-disk.patch new file mode 100644 index 0000000000..62ec9ab649 --- /dev/null +++ b/queue-5.10/hfsplus-verify-inode-mode-when-loading-from-disk.patch @@ -0,0 +1,105 @@ +From 2f0bcc7aaebfbeb94c4d21b6479ccf6f898a3057 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 18:18:54 +0900 +Subject: hfsplus: Verify inode mode when loading from disk + +From: Tetsuo Handa + +[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ] + +syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when +the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted. + +According to [1], the permissions field was treated as reserved in Mac OS +8 and 9. According to [2], the reserved field was explicitly initialized +with 0, and that field must remain 0 as long as reserved. Therefore, when +the "mode" field is not 0 (i.e. no longer reserved), the file must be +S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ +S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlusPermissions [1] +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#ReservedAndPadFields [2] +Signed-off-by: Tetsuo Handa +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA.ne.jp +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index 7e1d889dcc07a..0ba324ee7dffb 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -178,13 +178,29 @@ const struct dentry_operations hfsplus_dentry_operations = { + .d_compare = hfsplus_compare_dentry, + }; + +-static void hfsplus_get_perms(struct inode *inode, +- struct hfsplus_perm *perms, int dir) ++static int hfsplus_get_perms(struct inode *inode, ++ struct hfsplus_perm *perms, int dir) + { + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + u16 mode; + + mode = be16_to_cpu(perms->mode); ++ if (dir) { ++ if (mode && !S_ISDIR(mode)) ++ goto bad_type; ++ } else if (mode) { ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ case S_IFLNK: ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: ++ break; ++ default: ++ goto bad_type; ++ } ++ } + + i_uid_write(inode, be32_to_cpu(perms->owner)); + if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) +@@ -210,6 +226,10 @@ static void hfsplus_get_perms(struct inode *inode, + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; ++ return 0; ++bad_type: ++ pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); ++ return -EIO; + } + + static int hfsplus_file_open(struct inode *inode, struct file *file) +@@ -504,7 +524,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); +- hfsplus_get_perms(inode, &folder->permissions, 1); ++ res = hfsplus_get_perms(inode, &folder->permissions, 1); ++ if (res) ++ goto out; + set_nlink(inode, 1); + inode->i_size = 2 + be32_to_cpu(folder->valence); + inode->i_atime = hfsp_mt2ut(folder->access_date); +@@ -531,7 +553,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + + hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? + &file->rsrc_fork : &file->data_fork); +- hfsplus_get_perms(inode, &file->permissions, 0); ++ res = hfsplus_get_perms(inode, &file->permissions, 0); ++ if (res) ++ goto out; + set_nlink(inode, 1); + if (S_ISREG(inode->i_mode)) { + if (file->permissions.dev) +-- +2.51.0 + diff --git a/queue-5.10/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch b/queue-5.10/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch new file mode 100644 index 0000000000..aadf5d1f78 --- /dev/null +++ b/queue-5.10/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch @@ -0,0 +1,88 @@ +From a756f1f98b2441432b73a31cacadd073dbbcf672 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 10:30:19 -0700 +Subject: livepatch: Match old_sympos 0 and 1 in klp_find_func() + +From: Song Liu + +[ Upstream commit 139560e8b973402140cafeb68c656c1374bd4c20 ] + +When there is only one function of the same name, old_sympos of 0 and 1 +are logically identical. Match them in klp_find_func(). + +This is to avoid a corner case with different toolchain behavior. + +In this specific issue, two versions of kpatch-build were used to +build livepatch for the same kernel. One assigns old_sympos == 0 for +unique local functions, the other assigns old_sympos == 1 for unique +local functions. Both versions work fine by themselves. (PS: This +behavior change was introduced in a downstream version of kpatch-build. +This change does not exist in upstream kpatch-build.) + +However, during livepatch upgrade (with the replace flag set) from a +patch built with one version of kpatch-build to the same fix built with +the other version of kpatch-build, livepatching fails with errors like: + +[ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' +... +[ 14.219466] Call Trace: +[ 14.219468] +[ 14.219469] dump_stack_lvl+0x47/0x60 +[ 14.219474] sysfs_warn_dup.cold+0x17/0x27 +[ 14.219476] sysfs_create_dir_ns+0x95/0xb0 +[ 14.219479] kobject_add_internal+0x9e/0x260 +[ 14.219483] kobject_add+0x68/0x80 +[ 14.219485] ? kstrdup+0x3c/0xa0 +[ 14.219486] klp_enable_patch+0x320/0x830 +[ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] +[ 14.219491] ? 0xffffffffa05eb000 +[ 14.219492] do_one_initcall+0x2e/0x190 +[ 14.219494] do_init_module+0x67/0x270 +[ 14.219496] init_module_from_file+0x75/0xa0 +[ 14.219499] idempotent_init_module+0x15a/0x240 +[ 14.219501] __x64_sys_finit_module+0x61/0xc0 +[ 14.219503] do_syscall_64+0x5b/0x160 +[ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 +[ 14.219507] RIP: 0033:0x7f545a4bd96d +... +[ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with + -EEXIST, don't try to register things with the same name ... + +This happens because klp_find_func() thinks somefunc with old_sympos==0 +is not the same as somefunc with old_sympos==1, and klp_add_object_nops +adds another xxx/func,1 to the list of functions to patch. + +Signed-off-by: Song Liu +Acked-by: Josh Poimboeuf +[pmladek@suse.com: Fixed some typos.] +Reviewed-by: Petr Mladek +Tested-by: Petr Mladek +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + kernel/livepatch/core.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c +index 147ed154ebc77..c49042f5e71ec 100644 +--- a/kernel/livepatch/core.c ++++ b/kernel/livepatch/core.c +@@ -89,8 +89,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj, + struct klp_func *func; + + klp_for_each_func(obj, func) { ++ /* ++ * Besides identical old_sympos, also consider old_sympos ++ * of 0 and 1 are identical. ++ */ + if ((strcmp(old_func->old_name, func->old_name) == 0) && +- (old_func->old_sympos == func->old_sympos)) { ++ ((old_func->old_sympos == func->old_sympos) || ++ (old_func->old_sympos == 0 && func->old_sympos == 1) || ++ (old_func->old_sympos == 1 && func->old_sympos == 0))) { + return func; + } + } +-- +2.51.0 + diff --git a/queue-5.10/series b/queue-5.10/series index e3ef9fddc6..0c8cddee51 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -152,3 +152,16 @@ nfs-fix-missing-unlock-in-nfs_unlink.patch netfilter-nf_conncount-garbage-collection-is-not-skipped-when-jiffies-wrap-around.patch i3c-fix-uninitialized-variable-use-in-i2c-setup.patch netfilter-nft_connlimit-memleak-if-nf_ct_netns_get-fails.patch +bpf-arm64-do-not-audit-capability-check-in-do_jit.patch +btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch +x86-ptrace-always-inline-trivial-accessors.patch +acpica-avoid-walking-the-namespace-if-start_node-is-.patch +acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch +cpufreq-s5pv210-fix-refcount-leak.patch +livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch +hfsplus-fix-volume-corruption-issue-for-generic-070.patch +hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch +hfsplus-verify-inode-mode-when-loading-from-disk.patch +hfsplus-fix-volume-corruption-issue-for-generic-073.patch +btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch +bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch diff --git a/queue-5.10/x86-ptrace-always-inline-trivial-accessors.patch b/queue-5.10/x86-ptrace-always-inline-trivial-accessors.patch new file mode 100644 index 0000000000..7fee57c447 --- /dev/null +++ b/queue-5.10/x86-ptrace-always-inline-trivial-accessors.patch @@ -0,0 +1,89 @@ +From a5f7b65eee6571d9c813475c33b0a84c46fe0ba8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 12:04:24 +0100 +Subject: x86/ptrace: Always inline trivial accessors + +From: Peter Zijlstra + +[ Upstream commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa ] + +A KASAN build bloats these single load/store helpers such that +it fails to inline them: + + vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled + +Make sure the compiler isn't allowed to do stupid. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Link: https://patch.msgid.link/20251031105435.GU4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index b94f615600d57..d5186653311da 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -109,12 +109,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); + extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); + + +-static inline unsigned long regs_return_value(struct pt_regs *regs) ++static __always_inline unsigned long regs_return_value(struct pt_regs *regs) + { + return regs->ax; + } + +-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) ++static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) + { + regs->ax = rc; + } +@@ -195,34 +195,34 @@ static inline bool ip_within_syscall_gap(struct pt_regs *regs) + } + #endif + +-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline unsigned long instruction_pointer(struct pt_regs *regs) ++static __always_inline unsigned long instruction_pointer(struct pt_regs *regs) + { + return regs->ip; + } + +-static inline void instruction_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void instruction_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->ip = val; + } + +-static inline unsigned long frame_pointer(struct pt_regs *regs) ++static __always_inline unsigned long frame_pointer(struct pt_regs *regs) + { + return regs->bp; + } + +-static inline unsigned long user_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long user_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline void user_stack_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->sp = val; + } +-- +2.51.0 + diff --git a/queue-5.15/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch b/queue-5.15/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch new file mode 100644 index 0000000000..74ad386370 --- /dev/null +++ b/queue-5.15/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch @@ -0,0 +1,59 @@ +From 62fac76c1e8c2e471fe81600ceed66fd73515054 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 13:43:19 +0300 +Subject: ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() + only + +From: Sakari Ailus + +[ Upstream commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 ] + +Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode +property API is somewhat problematic as the latter is used in the +impelementation of the former. Instead of using +fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call +acpi_get_next_subnode() directly instead. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20251001104320.1272752-3-sakari.ailus@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 7f0fa58b634a3..cb4bcc90d4be5 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1168,7 +1168,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + + if (!prev) { + do { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + /* + * The names of the port nodes begin with "port@" + * followed by the number of the port node and they also +@@ -1186,13 +1186,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + if (!port) + return NULL; + +- endpoint = fwnode_get_next_child_node(port, prev); ++ endpoint = acpi_get_next_subnode(port, prev); + while (!endpoint) { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + if (!port) + break; + if (is_acpi_graph_node(port, "port")) +- endpoint = fwnode_get_next_child_node(port, NULL); ++ endpoint = acpi_get_next_subnode(port, NULL); + } + + /* +-- +2.51.0 + diff --git a/queue-5.15/acpica-avoid-walking-the-namespace-if-start_node-is-.patch b/queue-5.15/acpica-avoid-walking-the-namespace-if-start_node-is-.patch new file mode 100644 index 0000000000..dc3626f907 --- /dev/null +++ b/queue-5.15/acpica-avoid-walking-the-namespace-if-start_node-is-.patch @@ -0,0 +1,63 @@ +From eded30be4683580573d3c293aaca4fe4cc65d144 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:14:38 +0800 +Subject: ACPICA: Avoid walking the Namespace if start_node is NULL + +From: Cryolitia PukNgae + +[ Upstream commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 ] + +Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace +if it is not there") fixed the situation when both start_node and +acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed +on Honor Magicbook 14 Pro [1]. + +That happens due to the access to the member of parent_node in +acpi_ns_get_next_node(). The NULL pointer dereference will always +happen, no matter whether or not the start_node is equal to +ACPI_ROOT_OBJECT, so move the check of start_node being NULL +out of the if block. + +Unfortunately, all the attempts to contact Honor have failed, they +refused to provide any technical support for Linux. + +The bad DSDT table's dump could be found on GitHub [2]. + +DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025 + +Link: https://github.com/acpica/acpica/commit/1c1b57b9eba4554cb132ee658dd942c0210ed20d +Link: https://gist.github.com/Cryolitia/a860ffc97437dcd2cd988371d5b73ed7 [1] +Link: https://github.com/denis-bb/honor-fmb-p-dsdt [2] +Signed-off-by: Cryolitia PukNgae +Reviewed-by: WangYuli +[ rjw: Subject adjustment, changelog edits ] +Link: https://patch.msgid.link/20251125-acpica-v1-1-99e63b1b25f8@linux.dev +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/nswalk.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c +index e7c30ce06e189..dee2cb5fb9617 100644 +--- a/drivers/acpi/acpica/nswalk.c ++++ b/drivers/acpi/acpica/nswalk.c +@@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type, + + if (start_node == ACPI_ROOT_OBJECT) { + start_node = acpi_gbl_root_node; +- if (!start_node) { +- return_ACPI_STATUS(AE_NO_NAMESPACE); +- } ++ } ++ ++ /* Avoid walking the namespace if the StartNode is NULL */ ++ ++ if (!start_node) { ++ return_ACPI_STATUS(AE_NO_NAMESPACE); + } + + /* Null child means "get first node" */ +-- +2.51.0 + diff --git a/queue-5.15/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch b/queue-5.15/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch new file mode 100644 index 0000000000..919573feba --- /dev/null +++ b/queue-5.15/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch @@ -0,0 +1,67 @@ +From 7e894f7cda392f1b6f6d93d38c2070d15f5fb889 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 15:33:38 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE + +From: Gongwei Li + +[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ] + +Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3533 Rev= 1.10 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Gongwei Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index c8c638aa47262..95483a8d7b1e9 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -403,6 +403,8 @@ static const struct usb_device_id blacklist_table[] = { + /* Realtek 8821CE Bluetooth devices */ + { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-5.15/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch b/queue-5.15/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch new file mode 100644 index 0000000000..e250312165 --- /dev/null +++ b/queue-5.15/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch @@ -0,0 +1,56 @@ +From 511c41bfa6a268d0bb1d22ecf587a93ea27d53b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Dec 2025 13:59:16 +0100 +Subject: bpf, arm64: Do not audit capability check in do_jit() + +From: Ondrej Mosnacek + +[ Upstream commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c ] + +Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit +capability check in do_jit()"), change the capable() call to +ns_capable_noaudit() in order to avoid spurious SELinux denials in audit +log. + +The commit log from that commit applies here as well: +""" +The failure of this check only results in a security mitigation being +applied, slightly affecting performance of the compiled BPF program. It +doesn't result in a failed syscall, an thus auditing a failed LSM +permission check for it is unwanted. For example with SELinux, it causes +a denial to be reported for confined processes running as root, which +tends to be flagged as a problem to be fixed in the policy. Yet +dontauditing or allowing CAP_SYS_ADMIN to the domain may not be +desirable, as it would allow/silence also other checks - either going +against the principle of least privilege or making debugging potentially +harder. + +Fix it by changing it from capable() to ns_capable_noaudit(), which +instructs the LSMs to not audit the resulting denials. +""" + +Fixes: f300769ead03 ("arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users") +Signed-off-by: Ondrej Mosnacek +Link: https://lore.kernel.org/r/20251204125916.441021-1-omosnace@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + arch/arm64/net/bpf_jit_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index 654e7ed2d1a64..e934ad5837d08 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -341,7 +341,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) + arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) + return; + +- if (capable(CAP_SYS_ADMIN)) ++ if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) + return; + + if (supports_clearbhb(SCOPE_SYSTEM)) { +-- +2.51.0 + diff --git a/queue-5.15/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch b/queue-5.15/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch new file mode 100644 index 0000000000..69e1351e39 --- /dev/null +++ b/queue-5.15/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch @@ -0,0 +1,51 @@ +From 16e140f283354ebade03f22e02078934fa8ed0cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 18:58:07 +0530 +Subject: btrfs: fix memory leak of fs_devices in degraded seed device path + +From: Deepanshu Kartikey + +[ Upstream commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 ] + +In open_seed_devices(), when find_fsid() fails and we're in DEGRADED +mode, a new fs_devices is allocated via alloc_fs_devices() but is never +added to the seed_list before returning. This contrasts with the normal +path where fs_devices is properly added via list_add(). + +If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), +the cleanup code iterates seed_list to free seed devices, but this +orphaned fs_devices is never found and never freed, causing a memory +leak. Any devices allocated via add_missing_dev() and attached to this +fs_devices are also leaked. + +Fix this by adding the newly allocated fs_devices to seed_list in the +degraded path, consistent with the normal path. + +Fixes: 5f37583569442 ("Btrfs: move the missing device to its own fs device list") +Reported-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=eadd98df8bceb15d7fed +Tested-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Reviewed-by: Qu Wenruo +Signed-off-by: Deepanshu Kartikey +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/volumes.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 316f099a0bcfe..c18918ce8edde 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -7322,6 +7322,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, + + fs_devices->seeding = true; + fs_devices->opened = 1; ++ list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); + return fs_devices; + } + +-- +2.51.0 + diff --git a/queue-5.15/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch b/queue-5.15/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch new file mode 100644 index 0000000000..5b9afdea4d --- /dev/null +++ b/queue-5.15/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch @@ -0,0 +1,90 @@ +From 25b0e789916bfb0fc938208fe2aaea1895f3d90f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 12:51:09 +1030 +Subject: btrfs: scrub: always update btrfs_scrub_progress::last_physical + +From: Qu Wenruo + +[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ] + +[BUG] +When a scrub failed immediately without any byte scrubbed, the returned +btrfs_scrub_progress::last_physical will always be 0, even if there is a +non-zero @start passed into btrfs_scrub_dev() for resume cases. + +This will reset the progress and make later scrub resume start from the +beginning. + +[CAUSE] +The function btrfs_scrub_dev() accepts a @progress parameter to copy its +updated progress to the caller, there are cases where we either don't +touch progress::last_physical at all or copy 0 into last_physical: + +- last_physical not updated at all + If some error happened before scrubbing any super block or chunk, we + will not copy the progress, leaving the @last_physical untouched. + + E.g. failed to allocate @sctx, scrubbing a missing device or even + there is already a running scrub and so on. + + All those cases won't touch @progress at all, resulting the + last_physical untouched and will be left as 0 for most cases. + +- Error out before scrubbing any bytes + In those case we allocated @sctx, and sctx->stat.last_physical is all + zero (initialized by kvzalloc()). + Unfortunately some critical errors happened during + scrub_enumerate_chunks() or scrub_supers() before any stripe is really + scrubbed. + + In that case although we will copy sctx->stat back to @progress, since + no byte is really scrubbed, last_physical will be overwritten to 0. + +[FIX] +Make sure the parameter @progress always has its @last_physical member +updated to @start parameter inside btrfs_scrub_dev(). + +At the very beginning of the function, set @progress->last_physical to +@start, so that even if we error out without doing progress copying, +last_physical is still at @start. + +Then after we got @sctx allocated, set sctx->stat.last_physical to +@start, this will make sure even if we didn't get any byte scrubbed, at +the progress copying stage the @last_physical is not left as zero. + +This should resolve the resume progress reset problem. + +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index aac4ee5880952..3d5cb6e6b3bbe 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -4090,6 +4090,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + unsigned int nofs_flag; + bool need_commit = false; + ++ /* Set the basic fallback @last_physical before we got a sctx. */ ++ if (progress) ++ progress->last_physical = start; ++ + if (btrfs_fs_closing(fs_info)) + return -EAGAIN; + +@@ -4126,6 +4130,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + sctx = scrub_setup_ctx(fs_info, is_dev_replace); + if (IS_ERR(sctx)) + return PTR_ERR(sctx); ++ sctx->stat.last_physical = start; + + ret = scrub_workers_get(fs_info, is_dev_replace); + if (ret) +-- +2.51.0 + diff --git a/queue-5.15/cpufreq-s5pv210-fix-refcount-leak.patch b/queue-5.15/cpufreq-s5pv210-fix-refcount-leak.patch new file mode 100644 index 0000000000..a790fe077e --- /dev/null +++ b/queue-5.15/cpufreq-s5pv210-fix-refcount-leak.patch @@ -0,0 +1,62 @@ +From 5cce15ae75e6e050e50d4ccff78c558fdbd39d55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 03:31:17 +0800 +Subject: cpufreq: s5pv210: fix refcount leak + +From: Shuhao Fu + +[ Upstream commit 2de5cb96060a1664880d65b120e59485a73588a8 ] + +In function `s5pv210_cpu_init`, a possible refcount inconsistency has +been identified, causing a resource leak. + +Why it is a bug: +1. For every clk_get, there should be a matching clk_put on every +successive error handling path. +2. After calling `clk_get(dmc1_clk)`, variable `dmc1_clk` will not be +freed even if any error happens. + +How it is fixed: For every failed path, an extra goto label is added to +ensure `dmc1_clk` will be freed regardlessly. + +Signed-off-by: Shuhao Fu +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c +index ad7d4f272ddcb..f51b2e84ef63d 100644 +--- a/drivers/cpufreq/s5pv210-cpufreq.c ++++ b/drivers/cpufreq/s5pv210-cpufreq.c +@@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + + if (policy->cpu != 0) { + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* +@@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { + pr_err("CPUFreq doesn't support this memory type\n"); + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* Find current refresh counter and frequency each DMC */ +@@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + cpufreq_generic_init(policy, s5pv210_freq_table, 40000); + return 0; + ++out: ++ clk_put(dmc1_clk); + out_dmc1: + clk_put(dmc0_clk); + out_dmc0: +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-support-timestamps-prior-to-epoch.patch b/queue-5.15/fs-ntfs3-support-timestamps-prior-to-epoch.patch new file mode 100644 index 0000000000..2f62dd3688 --- /dev/null +++ b/queue-5.15/fs-ntfs3-support-timestamps-prior-to-epoch.patch @@ -0,0 +1,43 @@ +From 6747740ebbda84db422fedfc7096ed3d8f7d17e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Sep 2025 11:48:48 +0300 +Subject: fs/ntfs3: Support timestamps prior to epoch + +From: Konstantin Komarov + +[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ] + +Before it used an unsigned 64-bit type, which prevented proper handling +of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to +support pre-epoch timestamps. The issue was caught by xfstests. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/ntfs_fs.h | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index 69d1442eea623..d93cba03a65aa 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -975,11 +975,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts) + */ + static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) + { +- u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; ++ s32 t32; ++ /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ ++ s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; + +- // WARNING: do_div changes its first argument(!) +- ts->tv_nsec = do_div(t, _100ns2seconds) * 100; +- ts->tv_sec = t; ++ ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); ++ ts->tv_nsec = t32 * 100; + } + + static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb) +-- +2.51.0 + diff --git a/queue-5.15/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch b/queue-5.15/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch new file mode 100644 index 0000000000..0fcd275963 --- /dev/null +++ b/queue-5.15/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch @@ -0,0 +1,91 @@ +From 93d575d5e0c85aca55f6ec10d63f7edea8d0102f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 17:39:12 +0800 +Subject: hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create + +From: Yang Chenzhi + +[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ] + +When sync() and link() are called concurrently, both threads may +enter hfs_bnode_find() without finding the node in the hash table +and proceed to create it. + +Thread A: + hfsplus_write_inode() + -> hfsplus_write_system_inode() + -> hfs_btree_write() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +Thread B: + hfsplus_create_cat() + -> hfs_brec_insert() + -> hfs_bnode_split() + -> hfs_bmap_alloc() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +In this case, thread A creates the bnode, sets refcnt=1, and hashes it. +Thread B also tries to create the same bnode, notices it has already +been inserted, drops its own instance, and uses the hashed one without +getting the node. + +``` + + node2 = hfs_bnode_findhash(tree, cnid); + if (!node2) { <- Thread A + hash = hfs_bnode_hash(cnid); + node->next_hash = tree->node_hash[hash]; + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { <- Thread B + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, + !test_bit(HFS_BNODE_NEW, &node2->flags)); + return node2; + } +``` + +However, hfs_bnode_find() requires each call to take a reference. +Here both threads end up setting refcnt=1. When they later put the node, +this triggers: + +BUG_ON(!atomic_read(&node->refcnt)) + +In this scenario, Thread B in fact finds the node in the hash table +rather than creating a new one, and thus must take a reference. + +Fix this by calling hfs_bnode_get() when reusing a bnode newly created by +another thread to ensure the refcount is updated correctly. + +A similar bug was fixed in HFS long ago in commit +a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") +but the same issue remained in HFS+ until now. + +Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com +Signed-off-by: Yang Chenzhi +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index 358294726ff17..7c127922ac0c7 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -488,6 +488,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { ++ hfs_bnode_get(node2); + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, +-- +2.51.0 + diff --git a/queue-5.15/hfsplus-fix-volume-corruption-issue-for-generic-070.patch b/queue-5.15/hfsplus-fix-volume-corruption-issue-for-generic-070.patch new file mode 100644 index 0000000000..dfd1c04075 --- /dev/null +++ b/queue-5.15/hfsplus-fix-volume-corruption-issue-for-generic-070.patch @@ -0,0 +1,122 @@ +From cdac4107e30886acdfc266136d4025cb999a6402 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:12:30 -0700 +Subject: hfsplus: fix volume corruption issue for generic/070 + +From: Viacheslav Dubeyko + +[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ] + +The xfstests' test-case generic/070 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent +(see xfstests-dev/results//generic/070.full for details) + +Ran: generic/070 +Failures: generic/070 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop50 +** /dev/loop50 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +Unused node is not erased (node = 1) +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 +CBTStat = 0x0000 CatStat = 0x00000000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume test was repaired successfully. + +It is possible to see that fsck.hfsplus detected not +erased and unused node for the case of extents overflow file. +The HFS+ logic has special method that defines if the node +should be erased: + +bool hfs_bnode_need_zeroout(struct hfs_btree *tree) +{ + struct super_block *sb = tree->inode->i_sb; + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + + return tree->cnid == HFSPLUS_CAT_CNID && + volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; +} + +However, it is possible to see that this method works +only for the case of catalog file. But debugging of the issue +has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been +requested for the extents overflow file too: + +catalog file +kernel: hfsplus: node 4, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800 + +extents overflow file +kernel: hfsplus: node 1, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800 + +This patch modifies the hfs_bnode_need_zeroout() by checking +only volume_attr but not the b-tree ID because node zeroing +can be requested for all HFS+ b-tree types. + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 33s ... 34s +Ran: generic/070 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index e566cea238279..358294726ff17 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -717,6 +717,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + +- return tree->cnid == HFSPLUS_CAT_CNID && +- volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; ++ return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + } +-- +2.51.0 + diff --git a/queue-5.15/hfsplus-fix-volume-corruption-issue-for-generic-073.patch b/queue-5.15/hfsplus-fix-volume-corruption-issue-for-generic-073.patch new file mode 100644 index 0000000000..d0061086c9 --- /dev/null +++ b/queue-5.15/hfsplus-fix-volume-corruption-issue-for-generic-073.patch @@ -0,0 +1,125 @@ +From bed0bf3d9a1976044a7572d1cb0dfe6e4d4d11a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:25:23 -0800 +Subject: hfsplus: fix volume corruption issue for generic/073 + +From: Viacheslav Dubeyko + +[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ] + +The xfstests' test-case generic/073 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent +(see XFSTESTS-2/xfstests-dev/results//generic/073.full for details) + +Ran: generic/073 +Failures: generic/073 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +Invalid directory item count +(It should be 1 instead of 0) +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 +CBTStat = 0x0000 CatStat = 0x00004000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled was repaired successfully. + +The test is doing these steps on final phase: + +mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo + +So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ +logic decrements the number of entries in testdir_1 and increments number of +entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not +for testdir_2. As a result, this is the reason why fsck.hfsplus detects the +volume corruption afterwards. + +This patch fixes the issue by means of adding the +hfsplus_cat_write_inode() call for old_dir and new_dir in +hfsplus_rename() after the successful ending of +hfsplus_rename_cat(). This method makes modification of in-core +inode objects for old_dir and new_dir but it doesn't save these +modifications in Catalog File's entries. It was expected that +hfsplus_write_inode() will save these modifications afterwards. +However, because generic/073 does fsync only for testdir_1 and foo +then testdir_2 modification hasn't beed saved into Catalog File's +entry and it was flushed without this modification. And it was +detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog +File all modified entries and correct state of Catalog File will +be flushed during hfsplus_file_fsync() call. Finally, it makes +fsck.hfsplus happy. + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 32s ... 32s +Ran: generic/073 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/dir.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c +index 84714bbccc123..98a30ca6354ce 100644 +--- a/fs/hfsplus/dir.c ++++ b/fs/hfsplus/dir.c +@@ -552,8 +552,13 @@ static int hfsplus_rename(struct user_namespace *mnt_userns, + res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, + old_dir, &old_dentry->d_name, + new_dir, &new_dentry->d_name); +- if (!res) ++ if (!res) { + new_dentry->d_fsdata = old_dentry->d_fsdata; ++ ++ res = hfsplus_cat_write_inode(old_dir); ++ if (!res) ++ res = hfsplus_cat_write_inode(new_dir); ++ } + return res; + } + +-- +2.51.0 + diff --git a/queue-5.15/hfsplus-verify-inode-mode-when-loading-from-disk.patch b/queue-5.15/hfsplus-verify-inode-mode-when-loading-from-disk.patch new file mode 100644 index 0000000000..c383b1fc56 --- /dev/null +++ b/queue-5.15/hfsplus-verify-inode-mode-when-loading-from-disk.patch @@ -0,0 +1,105 @@ +From a687b453413d07772952e25a1079a658c9af3810 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 18:18:54 +0900 +Subject: hfsplus: Verify inode mode when loading from disk + +From: Tetsuo Handa + +[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ] + +syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when +the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted. + +According to [1], the permissions field was treated as reserved in Mac OS +8 and 9. According to [2], the reserved field was explicitly initialized +with 0, and that field must remain 0 as long as reserved. Therefore, when +the "mode" field is not 0 (i.e. no longer reserved), the file must be +S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ +S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlusPermissions [1] +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#ReservedAndPadFields [2] +Signed-off-by: Tetsuo Handa +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA.ne.jp +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index 87bc222dc9062..98a80ec5faa91 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -181,13 +181,29 @@ const struct dentry_operations hfsplus_dentry_operations = { + .d_compare = hfsplus_compare_dentry, + }; + +-static void hfsplus_get_perms(struct inode *inode, +- struct hfsplus_perm *perms, int dir) ++static int hfsplus_get_perms(struct inode *inode, ++ struct hfsplus_perm *perms, int dir) + { + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + u16 mode; + + mode = be16_to_cpu(perms->mode); ++ if (dir) { ++ if (mode && !S_ISDIR(mode)) ++ goto bad_type; ++ } else if (mode) { ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ case S_IFLNK: ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: ++ break; ++ default: ++ goto bad_type; ++ } ++ } + + i_uid_write(inode, be32_to_cpu(perms->owner)); + if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) +@@ -213,6 +229,10 @@ static void hfsplus_get_perms(struct inode *inode, + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; ++ return 0; ++bad_type: ++ pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); ++ return -EIO; + } + + static int hfsplus_file_open(struct inode *inode, struct file *file) +@@ -516,7 +536,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); +- hfsplus_get_perms(inode, &folder->permissions, 1); ++ res = hfsplus_get_perms(inode, &folder->permissions, 1); ++ if (res) ++ goto out; + set_nlink(inode, 1); + inode->i_size = 2 + be32_to_cpu(folder->valence); + inode->i_atime = hfsp_mt2ut(folder->access_date); +@@ -543,7 +565,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + + hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? + &file->rsrc_fork : &file->data_fork); +- hfsplus_get_perms(inode, &file->permissions, 0); ++ res = hfsplus_get_perms(inode, &file->permissions, 0); ++ if (res) ++ goto out; + set_nlink(inode, 1); + if (S_ISREG(inode->i_mode)) { + if (file->permissions.dev) +-- +2.51.0 + diff --git a/queue-5.15/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch b/queue-5.15/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch new file mode 100644 index 0000000000..e09cd1cdc0 --- /dev/null +++ b/queue-5.15/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch @@ -0,0 +1,88 @@ +From b5ad6c7e5077074e1b2197b2ac4fa5f20f041c6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 10:30:19 -0700 +Subject: livepatch: Match old_sympos 0 and 1 in klp_find_func() + +From: Song Liu + +[ Upstream commit 139560e8b973402140cafeb68c656c1374bd4c20 ] + +When there is only one function of the same name, old_sympos of 0 and 1 +are logically identical. Match them in klp_find_func(). + +This is to avoid a corner case with different toolchain behavior. + +In this specific issue, two versions of kpatch-build were used to +build livepatch for the same kernel. One assigns old_sympos == 0 for +unique local functions, the other assigns old_sympos == 1 for unique +local functions. Both versions work fine by themselves. (PS: This +behavior change was introduced in a downstream version of kpatch-build. +This change does not exist in upstream kpatch-build.) + +However, during livepatch upgrade (with the replace flag set) from a +patch built with one version of kpatch-build to the same fix built with +the other version of kpatch-build, livepatching fails with errors like: + +[ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' +... +[ 14.219466] Call Trace: +[ 14.219468] +[ 14.219469] dump_stack_lvl+0x47/0x60 +[ 14.219474] sysfs_warn_dup.cold+0x17/0x27 +[ 14.219476] sysfs_create_dir_ns+0x95/0xb0 +[ 14.219479] kobject_add_internal+0x9e/0x260 +[ 14.219483] kobject_add+0x68/0x80 +[ 14.219485] ? kstrdup+0x3c/0xa0 +[ 14.219486] klp_enable_patch+0x320/0x830 +[ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] +[ 14.219491] ? 0xffffffffa05eb000 +[ 14.219492] do_one_initcall+0x2e/0x190 +[ 14.219494] do_init_module+0x67/0x270 +[ 14.219496] init_module_from_file+0x75/0xa0 +[ 14.219499] idempotent_init_module+0x15a/0x240 +[ 14.219501] __x64_sys_finit_module+0x61/0xc0 +[ 14.219503] do_syscall_64+0x5b/0x160 +[ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 +[ 14.219507] RIP: 0033:0x7f545a4bd96d +... +[ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with + -EEXIST, don't try to register things with the same name ... + +This happens because klp_find_func() thinks somefunc with old_sympos==0 +is not the same as somefunc with old_sympos==1, and klp_add_object_nops +adds another xxx/func,1 to the list of functions to patch. + +Signed-off-by: Song Liu +Acked-by: Josh Poimboeuf +[pmladek@suse.com: Fixed some typos.] +Reviewed-by: Petr Mladek +Tested-by: Petr Mladek +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + kernel/livepatch/core.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c +index 147ed154ebc77..c49042f5e71ec 100644 +--- a/kernel/livepatch/core.c ++++ b/kernel/livepatch/core.c +@@ -89,8 +89,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj, + struct klp_func *func; + + klp_for_each_func(obj, func) { ++ /* ++ * Besides identical old_sympos, also consider old_sympos ++ * of 0 and 1 are identical. ++ */ + if ((strcmp(old_func->old_name, func->old_name) == 0) && +- (old_func->old_sympos == func->old_sympos)) { ++ ((old_func->old_sympos == func->old_sympos) || ++ (old_func->old_sympos == 0 && func->old_sympos == 1) || ++ (old_func->old_sympos == 1 && func->old_sympos == 0))) { + return func; + } + } +-- +2.51.0 + diff --git a/queue-5.15/sched-deadline-only-set-free_cpus-for-online-runqueu.patch b/queue-5.15/sched-deadline-only-set-free_cpus-for-online-runqueu.patch new file mode 100644 index 0000000000..94227cbf83 --- /dev/null +++ b/queue-5.15/sched-deadline-only-set-free_cpus-for-online-runqueu.patch @@ -0,0 +1,189 @@ +From dbd07e09e506b643d4ecd77bce94b82a2c9457e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 18:22:36 -0700 +Subject: sched/deadline: only set free_cpus for online runqueues + +From: Doug Berger + +[ Upstream commit 382748c05e58a9f1935f5a653c352422375566ea ] + +Commit 16b269436b72 ("sched/deadline: Modify cpudl::free_cpus +to reflect rd->online") introduced the cpudl_set/clear_freecpu +functions to allow the cpu_dl::free_cpus mask to be manipulated +by the deadline scheduler class rq_on/offline callbacks so the +mask would also reflect this state. + +Commit 9659e1eeee28 ("sched/deadline: Remove cpu_active_mask +from cpudl_find()") removed the check of the cpu_active_mask to +save some processing on the premise that the cpudl::free_cpus +mask already reflected the runqueue online state. + +Unfortunately, there are cases where it is possible for the +cpudl_clear function to set the free_cpus bit for a CPU when the +deadline runqueue is offline. When this occurs while a CPU is +connected to the default root domain the flag may retain the bad +state after the CPU has been unplugged. Later, a different CPU +that is transitioning through the default root domain may push a +deadline task to the powered down CPU when cpudl_find sees its +free_cpus bit is set. If this happens the task will not have the +opportunity to run. + +One example is outlined here: +https://lore.kernel.org/lkml/20250110233010.2339521-1-opendmb@gmail.com + +Another occurs when the last deadline task is migrated from a +CPU that has an offlined runqueue. The dequeue_task member of +the deadline scheduler class will eventually call cpudl_clear +and set the free_cpus bit for the CPU. + +This commit modifies the cpudl_clear function to be aware of the +online state of the deadline runqueue so that the free_cpus mask +can be updated appropriately. + +It is no longer necessary to manage the mask outside of the +cpudl_set/clear functions so the cpudl_set/clear_freecpu +functions are removed. In addition, since the free_cpus mask is +now only updated under the cpudl lock the code was changed to +use the non-atomic __cpumask functions. + +Signed-off-by: Doug Berger +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + kernel/sched/cpudeadline.c | 34 +++++++++------------------------- + kernel/sched/cpudeadline.h | 4 +--- + kernel/sched/deadline.c | 8 ++++---- + 3 files changed, 14 insertions(+), 32 deletions(-) + +diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c +index 221ca10505738..219cec91ecee4 100644 +--- a/kernel/sched/cpudeadline.c ++++ b/kernel/sched/cpudeadline.c +@@ -166,12 +166,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, + * cpudl_clear - remove a CPU from the cpudl max-heap + * @cp: the cpudl max-heap context + * @cpu: the target CPU ++ * @online: the online state of the deadline runqueue + * + * Notes: assumes cpu_rq(cpu)->lock is locked + * + * Returns: (void) + */ +-void cpudl_clear(struct cpudl *cp, int cpu) ++void cpudl_clear(struct cpudl *cp, int cpu, bool online) + { + int old_idx, new_cpu; + unsigned long flags; +@@ -184,7 +185,7 @@ void cpudl_clear(struct cpudl *cp, int cpu) + if (old_idx == IDX_INVALID) { + /* + * Nothing to remove if old_idx was invalid. +- * This could happen if a rq_offline_dl is ++ * This could happen if rq_online_dl or rq_offline_dl is + * called for a CPU without -dl tasks running. + */ + } else { +@@ -195,9 +196,12 @@ void cpudl_clear(struct cpudl *cp, int cpu) + cp->elements[new_cpu].idx = old_idx; + cp->elements[cpu].idx = IDX_INVALID; + cpudl_heapify(cp, old_idx); +- +- cpumask_set_cpu(cpu, cp->free_cpus); + } ++ if (likely(online)) ++ __cpumask_set_cpu(cpu, cp->free_cpus); ++ else ++ __cpumask_clear_cpu(cpu, cp->free_cpus); ++ + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +@@ -228,7 +232,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + cp->elements[new_idx].cpu = cpu; + cp->elements[cpu].idx = new_idx; + cpudl_heapify_up(cp, new_idx); +- cpumask_clear_cpu(cpu, cp->free_cpus); ++ __cpumask_clear_cpu(cpu, cp->free_cpus); + } else { + cp->elements[old_idx].dl = dl; + cpudl_heapify(cp, old_idx); +@@ -237,26 +241,6 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +-/* +- * cpudl_set_freecpu - Set the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_set_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_set_cpu(cpu, cp->free_cpus); +-} +- +-/* +- * cpudl_clear_freecpu - Clear the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_clear_cpu(cpu, cp->free_cpus); +-} +- + /* + * cpudl_init - initialize the cpudl structure + * @cp: the cpudl max-heap context +diff --git a/kernel/sched/cpudeadline.h b/kernel/sched/cpudeadline.h +index 0adeda93b5fb5..ecff718d94aea 100644 +--- a/kernel/sched/cpudeadline.h ++++ b/kernel/sched/cpudeadline.h +@@ -18,9 +18,7 @@ struct cpudl { + #ifdef CONFIG_SMP + int cpudl_find(struct cpudl *cp, struct task_struct *p, struct cpumask *later_mask); + void cpudl_set(struct cpudl *cp, int cpu, u64 dl); +-void cpudl_clear(struct cpudl *cp, int cpu); ++void cpudl_clear(struct cpudl *cp, int cpu, bool online); + int cpudl_init(struct cpudl *cp); +-void cpudl_set_freecpu(struct cpudl *cp, int cpu); +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu); + void cpudl_cleanup(struct cpudl *cp); + #endif /* CONFIG_SMP */ +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index 708c3960bd06e..923ac2244d4b5 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -1418,7 +1418,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline) + if (!dl_rq->dl_nr_running) { + dl_rq->earliest_dl.curr = 0; + dl_rq->earliest_dl.next = 0; +- cpudl_clear(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, rq->online); + cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr); + } else { + struct rb_node *leftmost = dl_rq->root.rb_leftmost; +@@ -2377,9 +2377,10 @@ static void rq_online_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_set_overload(rq); + +- cpudl_set_freecpu(&rq->rd->cpudl, rq->cpu); + if (rq->dl.dl_nr_running > 0) + cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr); ++ else ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, true); + } + + /* Assumes rq->lock is held */ +@@ -2388,8 +2389,7 @@ static void rq_offline_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_clear_overload(rq); + +- cpudl_clear(&rq->rd->cpudl, rq->cpu); +- cpudl_clear_freecpu(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, false); + } + + void __init init_sched_dl_class(void) +-- +2.51.0 + diff --git a/queue-5.15/series b/queue-5.15/series index d1de956709..2792f2f5e6 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -205,3 +205,18 @@ coresight-etm4x-correct-polling-idle-bit.patch spi-tegra210-quad-fix-validate-combined-sequence.patch spi-tegra210-quad-fix-x1_x2_x4-encoding-and-support-x4-transfers.patch i3c-fix-uninitialized-variable-use-in-i2c-setup.patch +bpf-arm64-do-not-audit-capability-check-in-do_jit.patch +btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch +sched-deadline-only-set-free_cpus-for-online-runqueu.patch +x86-ptrace-always-inline-trivial-accessors.patch +acpica-avoid-walking-the-namespace-if-start_node-is-.patch +acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch +cpufreq-s5pv210-fix-refcount-leak.patch +livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch +fs-ntfs3-support-timestamps-prior-to-epoch.patch +hfsplus-fix-volume-corruption-issue-for-generic-070.patch +hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch +hfsplus-verify-inode-mode-when-loading-from-disk.patch +hfsplus-fix-volume-corruption-issue-for-generic-073.patch +btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch +bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch diff --git a/queue-5.15/x86-ptrace-always-inline-trivial-accessors.patch b/queue-5.15/x86-ptrace-always-inline-trivial-accessors.patch new file mode 100644 index 0000000000..d7f23a19b8 --- /dev/null +++ b/queue-5.15/x86-ptrace-always-inline-trivial-accessors.patch @@ -0,0 +1,89 @@ +From a0287bb59a31d01090d2881f50da87420bb7b535 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 12:04:24 +0100 +Subject: x86/ptrace: Always inline trivial accessors + +From: Peter Zijlstra + +[ Upstream commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa ] + +A KASAN build bloats these single load/store helpers such that +it fails to inline them: + + vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled + +Make sure the compiler isn't allowed to do stupid. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Link: https://patch.msgid.link/20251031105435.GU4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index b94f615600d57..d5186653311da 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -109,12 +109,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); + extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); + + +-static inline unsigned long regs_return_value(struct pt_regs *regs) ++static __always_inline unsigned long regs_return_value(struct pt_regs *regs) + { + return regs->ax; + } + +-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) ++static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) + { + regs->ax = rc; + } +@@ -195,34 +195,34 @@ static inline bool ip_within_syscall_gap(struct pt_regs *regs) + } + #endif + +-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline unsigned long instruction_pointer(struct pt_regs *regs) ++static __always_inline unsigned long instruction_pointer(struct pt_regs *regs) + { + return regs->ip; + } + +-static inline void instruction_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void instruction_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->ip = val; + } + +-static inline unsigned long frame_pointer(struct pt_regs *regs) ++static __always_inline unsigned long frame_pointer(struct pt_regs *regs) + { + return regs->bp; + } + +-static inline unsigned long user_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long user_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline void user_stack_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->sp = val; + } +-- +2.51.0 + diff --git a/queue-6.1/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch b/queue-6.1/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch new file mode 100644 index 0000000000..ddf15b0244 --- /dev/null +++ b/queue-6.1/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch @@ -0,0 +1,59 @@ +From 56eae3410ccc162bd85fc12002c85858a327b3bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 13:43:19 +0300 +Subject: ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() + only + +From: Sakari Ailus + +[ Upstream commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 ] + +Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode +property API is somewhat problematic as the latter is used in the +impelementation of the former. Instead of using +fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call +acpi_get_next_subnode() directly instead. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20251001104320.1272752-3-sakari.ailus@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 0ff1c3d2504d4..577942d29d133 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1382,7 +1382,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + + if (!prev) { + do { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + /* + * The names of the port nodes begin with "port@" + * followed by the number of the port node and they also +@@ -1400,13 +1400,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + if (!port) + return NULL; + +- endpoint = fwnode_get_next_child_node(port, prev); ++ endpoint = acpi_get_next_subnode(port, prev); + while (!endpoint) { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + if (!port) + break; + if (is_acpi_graph_node(port, "port")) +- endpoint = fwnode_get_next_child_node(port, NULL); ++ endpoint = acpi_get_next_subnode(port, NULL); + } + + /* +-- +2.51.0 + diff --git a/queue-6.1/acpica-avoid-walking-the-namespace-if-start_node-is-.patch b/queue-6.1/acpica-avoid-walking-the-namespace-if-start_node-is-.patch new file mode 100644 index 0000000000..5d279dec0b --- /dev/null +++ b/queue-6.1/acpica-avoid-walking-the-namespace-if-start_node-is-.patch @@ -0,0 +1,63 @@ +From 33db496ba4131c8c530c5caaca13b06a2af3d0c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:14:38 +0800 +Subject: ACPICA: Avoid walking the Namespace if start_node is NULL + +From: Cryolitia PukNgae + +[ Upstream commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 ] + +Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace +if it is not there") fixed the situation when both start_node and +acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed +on Honor Magicbook 14 Pro [1]. + +That happens due to the access to the member of parent_node in +acpi_ns_get_next_node(). The NULL pointer dereference will always +happen, no matter whether or not the start_node is equal to +ACPI_ROOT_OBJECT, so move the check of start_node being NULL +out of the if block. + +Unfortunately, all the attempts to contact Honor have failed, they +refused to provide any technical support for Linux. + +The bad DSDT table's dump could be found on GitHub [2]. + +DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025 + +Link: https://github.com/acpica/acpica/commit/1c1b57b9eba4554cb132ee658dd942c0210ed20d +Link: https://gist.github.com/Cryolitia/a860ffc97437dcd2cd988371d5b73ed7 [1] +Link: https://github.com/denis-bb/honor-fmb-p-dsdt [2] +Signed-off-by: Cryolitia PukNgae +Reviewed-by: WangYuli +[ rjw: Subject adjustment, changelog edits ] +Link: https://patch.msgid.link/20251125-acpica-v1-1-99e63b1b25f8@linux.dev +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/nswalk.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c +index 82a0dae349e2f..254b0ca0c1540 100644 +--- a/drivers/acpi/acpica/nswalk.c ++++ b/drivers/acpi/acpica/nswalk.c +@@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type, + + if (start_node == ACPI_ROOT_OBJECT) { + start_node = acpi_gbl_root_node; +- if (!start_node) { +- return_ACPI_STATUS(AE_NO_NAMESPACE); +- } ++ } ++ ++ /* Avoid walking the namespace if the StartNode is NULL */ ++ ++ if (!start_node) { ++ return_ACPI_STATUS(AE_NO_NAMESPACE); + } + + /* Null child means "get first node" */ +-- +2.51.0 + diff --git a/queue-6.1/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch b/queue-6.1/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch new file mode 100644 index 0000000000..cf884202e3 --- /dev/null +++ b/queue-6.1/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch @@ -0,0 +1,67 @@ +From a87a8d0d7a189029552ced8d18574fb61d26d4fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 15:33:38 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE + +From: Gongwei Li + +[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ] + +Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3533 Rev= 1.10 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Gongwei Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 70cdcef684138..9837946329272 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -496,6 +496,8 @@ static const struct usb_device_id blacklist_table[] = { + /* Realtek 8821CE Bluetooth devices */ + { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-6.1/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch b/queue-6.1/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch new file mode 100644 index 0000000000..4d69c68390 --- /dev/null +++ b/queue-6.1/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch @@ -0,0 +1,56 @@ +From 46ccc8d46badea1bec18b6c766cbf76c94e03e7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Dec 2025 13:59:16 +0100 +Subject: bpf, arm64: Do not audit capability check in do_jit() + +From: Ondrej Mosnacek + +[ Upstream commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c ] + +Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit +capability check in do_jit()"), change the capable() call to +ns_capable_noaudit() in order to avoid spurious SELinux denials in audit +log. + +The commit log from that commit applies here as well: +""" +The failure of this check only results in a security mitigation being +applied, slightly affecting performance of the compiled BPF program. It +doesn't result in a failed syscall, an thus auditing a failed LSM +permission check for it is unwanted. For example with SELinux, it causes +a denial to be reported for confined processes running as root, which +tends to be flagged as a problem to be fixed in the policy. Yet +dontauditing or allowing CAP_SYS_ADMIN to the domain may not be +desirable, as it would allow/silence also other checks - either going +against the principle of least privilege or making debugging potentially +harder. + +Fix it by changing it from capable() to ns_capable_noaudit(), which +instructs the LSMs to not audit the resulting denials. +""" + +Fixes: f300769ead03 ("arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users") +Signed-off-by: Ondrej Mosnacek +Link: https://lore.kernel.org/r/20251204125916.441021-1-omosnace@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + arch/arm64/net/bpf_jit_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index 3dd23050a6c89..783883721aaf5 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -666,7 +666,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) + arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) + return; + +- if (capable(CAP_SYS_ADMIN)) ++ if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) + return; + + if (supports_clearbhb(SCOPE_SYSTEM)) { +-- +2.51.0 + diff --git a/queue-6.1/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch b/queue-6.1/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch new file mode 100644 index 0000000000..6e9ac88a7f --- /dev/null +++ b/queue-6.1/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch @@ -0,0 +1,72 @@ +From dde88c4f2258756ad8df2c0626486e08c6edf1cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 17:02:00 +0000 +Subject: btrfs: do not skip logging new dentries when logging a new name + +From: Filipe Manana + +[ Upstream commit 5630f7557de61264ccb4f031d4734a1a97eaed16 ] + +When we are logging a directory and the log context indicates that we +are logging a new name for some other file (that is or was inside that +directory), we skip logging the inodes for new dentries in the directory. + +This is ok most of the time, but if after the rename or link operation +that triggered the logging of that directory, we have an explicit fsync +of that directory without the directory inode being evicted and reloaded, +we end up never logging the inodes for the new dentries that we found +during the new name logging, as the next directory fsync will only process +dentries that were added after the last time we logged the directory (we +are doing an incremental directory logging). + +So make sure we always log new dentries for a directory even if we are +in a context of logging a new name. + +We started skipping logging inodes for new dentries as of commit +c48792c6ee7a ("btrfs: do not log new dentries when logging that a new name +exists") and it was fine back then, because when logging a directory we +always iterated over all the directory entries (for leaves changed in the +current transaction) so a subsequent fsync would always log anything that +was previously skipped while logging a directory when logging a new name +(with btrfs_log_new_name()). But later support for incrementally logging +a directory was added in commit dc2872247ec0 ("btrfs: keep track of the +last logged keys when logging a directory"), to avoid checking all dir +items every time we log a directory, so the check to skip dentry logging +added in the first commit should have been removed when the incremental +support for logging a directory was added. + +A test case for fstests will follow soon. + +Reported-by: Vyacheslav Kovalevsky +Link: https://lore.kernel.org/linux-btrfs/84c4e713-85d6-42b9-8dcf-0722ed26cb05@gmail.com/ +Fixes: dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory") +Reviewed-by: Boris Burkov +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tree-log.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 11a7408ebc265..aa506716e9201 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -5478,14 +5478,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, + u64 ino = btrfs_ino(start_inode); + int ret = 0; + +- /* +- * If we are logging a new name, as part of a link or rename operation, +- * don't bother logging new dentries, as we just want to log the names +- * of an inode and that any new parents exist. +- */ +- if (ctx->logging_new_name) +- return 0; +- + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.1/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch b/queue-6.1/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch new file mode 100644 index 0000000000..171ec90d96 --- /dev/null +++ b/queue-6.1/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch @@ -0,0 +1,51 @@ +From e05677744edb3fb391cb900f3070596fcab4b2d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 18:58:07 +0530 +Subject: btrfs: fix memory leak of fs_devices in degraded seed device path + +From: Deepanshu Kartikey + +[ Upstream commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 ] + +In open_seed_devices(), when find_fsid() fails and we're in DEGRADED +mode, a new fs_devices is allocated via alloc_fs_devices() but is never +added to the seed_list before returning. This contrasts with the normal +path where fs_devices is properly added via list_add(). + +If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), +the cleanup code iterates seed_list to free seed devices, but this +orphaned fs_devices is never found and never freed, causing a memory +leak. Any devices allocated via add_missing_dev() and attached to this +fs_devices are also leaked. + +Fix this by adding the newly allocated fs_devices to seed_list in the +degraded path, consistent with the normal path. + +Fixes: 5f37583569442 ("Btrfs: move the missing device to its own fs device list") +Reported-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=eadd98df8bceb15d7fed +Tested-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Reviewed-by: Qu Wenruo +Signed-off-by: Deepanshu Kartikey +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/volumes.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 628238493167f..366cf2e8c51cb 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -7416,6 +7416,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, + + fs_devices->seeding = true; + fs_devices->opened = 1; ++ list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); + return fs_devices; + } + +-- +2.51.0 + diff --git a/queue-6.1/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch b/queue-6.1/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch new file mode 100644 index 0000000000..a15e0d6263 --- /dev/null +++ b/queue-6.1/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch @@ -0,0 +1,90 @@ +From 4c345feb693bd9f1c896b093f45b63d60db9a103 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 12:51:09 +1030 +Subject: btrfs: scrub: always update btrfs_scrub_progress::last_physical + +From: Qu Wenruo + +[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ] + +[BUG] +When a scrub failed immediately without any byte scrubbed, the returned +btrfs_scrub_progress::last_physical will always be 0, even if there is a +non-zero @start passed into btrfs_scrub_dev() for resume cases. + +This will reset the progress and make later scrub resume start from the +beginning. + +[CAUSE] +The function btrfs_scrub_dev() accepts a @progress parameter to copy its +updated progress to the caller, there are cases where we either don't +touch progress::last_physical at all or copy 0 into last_physical: + +- last_physical not updated at all + If some error happened before scrubbing any super block or chunk, we + will not copy the progress, leaving the @last_physical untouched. + + E.g. failed to allocate @sctx, scrubbing a missing device or even + there is already a running scrub and so on. + + All those cases won't touch @progress at all, resulting the + last_physical untouched and will be left as 0 for most cases. + +- Error out before scrubbing any bytes + In those case we allocated @sctx, and sctx->stat.last_physical is all + zero (initialized by kvzalloc()). + Unfortunately some critical errors happened during + scrub_enumerate_chunks() or scrub_supers() before any stripe is really + scrubbed. + + In that case although we will copy sctx->stat back to @progress, since + no byte is really scrubbed, last_physical will be overwritten to 0. + +[FIX] +Make sure the parameter @progress always has its @last_physical member +updated to @start parameter inside btrfs_scrub_dev(). + +At the very beginning of the function, set @progress->last_physical to +@start, so that even if we error out without doing progress copying, +last_physical is still at @start. + +Then after we got @sctx allocated, set sctx->stat.last_physical to +@start, this will make sure even if we didn't get any byte scrubbed, at +the progress copying stage the @last_physical is not left as zero. + +This should resolve the resume progress reset problem. + +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index ce8a9c226534f..8cae31edc68d7 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -4294,6 +4294,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + unsigned int nofs_flag; + bool need_commit = false; + ++ /* Set the basic fallback @last_physical before we got a sctx. */ ++ if (progress) ++ progress->last_physical = start; ++ + if (btrfs_fs_closing(fs_info)) + return -EAGAIN; + +@@ -4312,6 +4316,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + sctx = scrub_setup_ctx(fs_info, is_dev_replace); + if (IS_ERR(sctx)) + return PTR_ERR(sctx); ++ sctx->stat.last_physical = start; + + ret = scrub_workers_get(fs_info, is_dev_replace); + if (ret) +-- +2.51.0 + diff --git a/queue-6.1/cpufreq-s5pv210-fix-refcount-leak.patch b/queue-6.1/cpufreq-s5pv210-fix-refcount-leak.patch new file mode 100644 index 0000000000..30fe47dfd4 --- /dev/null +++ b/queue-6.1/cpufreq-s5pv210-fix-refcount-leak.patch @@ -0,0 +1,62 @@ +From 22a320621a0081d1eba3c6d72ae991dceb75216a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 03:31:17 +0800 +Subject: cpufreq: s5pv210: fix refcount leak + +From: Shuhao Fu + +[ Upstream commit 2de5cb96060a1664880d65b120e59485a73588a8 ] + +In function `s5pv210_cpu_init`, a possible refcount inconsistency has +been identified, causing a resource leak. + +Why it is a bug: +1. For every clk_get, there should be a matching clk_put on every +successive error handling path. +2. After calling `clk_get(dmc1_clk)`, variable `dmc1_clk` will not be +freed even if any error happens. + +How it is fixed: For every failed path, an extra goto label is added to +ensure `dmc1_clk` will be freed regardlessly. + +Signed-off-by: Shuhao Fu +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c +index 76c888ed8d160..d2fa42beae9c2 100644 +--- a/drivers/cpufreq/s5pv210-cpufreq.c ++++ b/drivers/cpufreq/s5pv210-cpufreq.c +@@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + + if (policy->cpu != 0) { + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* +@@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { + pr_err("CPUFreq doesn't support this memory type\n"); + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* Find current refresh counter and frequency each DMC */ +@@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + cpufreq_generic_init(policy, s5pv210_freq_table, 40000); + return 0; + ++out: ++ clk_put(dmc1_clk); + out_dmc1: + clk_put(dmc0_clk); + out_dmc0: +-- +2.51.0 + diff --git a/queue-6.1/fs-ntfs3-support-timestamps-prior-to-epoch.patch b/queue-6.1/fs-ntfs3-support-timestamps-prior-to-epoch.patch new file mode 100644 index 0000000000..eaaa722764 --- /dev/null +++ b/queue-6.1/fs-ntfs3-support-timestamps-prior-to-epoch.patch @@ -0,0 +1,43 @@ +From 74e8ec3ab5ebcbe91abb784a75ca1e3ebb87777a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Sep 2025 11:48:48 +0300 +Subject: fs/ntfs3: Support timestamps prior to epoch + +From: Konstantin Komarov + +[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ] + +Before it used an unsigned 64-bit type, which prevented proper handling +of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to +support pre-epoch timestamps. The issue was caught by xfstests. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/ntfs_fs.h | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index f2f32e304b3d3..c93217ed3f6c1 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -978,11 +978,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts) + */ + static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) + { +- u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; ++ s32 t32; ++ /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ ++ s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; + +- // WARNING: do_div changes its first argument(!) +- ts->tv_nsec = do_div(t, _100ns2seconds) * 100; +- ts->tv_sec = t; ++ ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); ++ ts->tv_nsec = t32 * 100; + } + + static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb) +-- +2.51.0 + diff --git a/queue-6.1/gfs2-fix-use-of-bio_chain.patch b/queue-6.1/gfs2-fix-use-of-bio_chain.patch new file mode 100644 index 0000000000..d9534edc35 --- /dev/null +++ b/queue-6.1/gfs2-fix-use-of-bio_chain.patch @@ -0,0 +1,37 @@ +From 08c4656f33b7b677c9be12c0f12294ff8694f786 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 21:19:52 +0000 +Subject: gfs2: Fix use of bio_chain + +From: Andreas Gruenbacher + +[ Upstream commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941 ] + +In gfs2_chain_bio(), the call to bio_chain() has its arguments swapped. +The result is leaked bios and incorrect synchronization (only the last +bio will actually be waited for). This code is only used during mount +and filesystem thaw, so the bug normally won't be noticeable. + +Reported-by: Stephen Zhang +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/lops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c +index 1902413d5d123..5656851b9240a 100644 +--- a/fs/gfs2/lops.c ++++ b/fs/gfs2/lops.c +@@ -491,7 +491,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) + new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); + bio_clone_blkg_association(new, prev); + new->bi_iter.bi_sector = bio_end_sector(prev); +- bio_chain(new, prev); ++ bio_chain(prev, new); + submit_bio(prev); + return new; + } +-- +2.51.0 + diff --git a/queue-6.1/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch b/queue-6.1/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch new file mode 100644 index 0000000000..66adc60807 --- /dev/null +++ b/queue-6.1/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch @@ -0,0 +1,91 @@ +From 814a376c0e48d0e92a9e6e04da5e566321fb0c46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 17:39:12 +0800 +Subject: hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create + +From: Yang Chenzhi + +[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ] + +When sync() and link() are called concurrently, both threads may +enter hfs_bnode_find() without finding the node in the hash table +and proceed to create it. + +Thread A: + hfsplus_write_inode() + -> hfsplus_write_system_inode() + -> hfs_btree_write() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +Thread B: + hfsplus_create_cat() + -> hfs_brec_insert() + -> hfs_bnode_split() + -> hfs_bmap_alloc() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +In this case, thread A creates the bnode, sets refcnt=1, and hashes it. +Thread B also tries to create the same bnode, notices it has already +been inserted, drops its own instance, and uses the hashed one without +getting the node. + +``` + + node2 = hfs_bnode_findhash(tree, cnid); + if (!node2) { <- Thread A + hash = hfs_bnode_hash(cnid); + node->next_hash = tree->node_hash[hash]; + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { <- Thread B + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, + !test_bit(HFS_BNODE_NEW, &node2->flags)); + return node2; + } +``` + +However, hfs_bnode_find() requires each call to take a reference. +Here both threads end up setting refcnt=1. When they later put the node, +this triggers: + +BUG_ON(!atomic_read(&node->refcnt)) + +In this scenario, Thread B in fact finds the node in the hash table +rather than creating a new one, and thus must take a reference. + +Fix this by calling hfs_bnode_get() when reusing a bnode newly created by +another thread to ensure the refcount is updated correctly. + +A similar bug was fixed in HFS long ago in commit +a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") +but the same issue remained in HFS+ until now. + +Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com +Signed-off-by: Yang Chenzhi +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index aa095e6fb20e8..c0089849be50e 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -481,6 +481,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { ++ hfs_bnode_get(node2); + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, +-- +2.51.0 + diff --git a/queue-6.1/hfsplus-fix-volume-corruption-issue-for-generic-070.patch b/queue-6.1/hfsplus-fix-volume-corruption-issue-for-generic-070.patch new file mode 100644 index 0000000000..6835c6f863 --- /dev/null +++ b/queue-6.1/hfsplus-fix-volume-corruption-issue-for-generic-070.patch @@ -0,0 +1,122 @@ +From 78e2e317910b5300d0b71915301563cf8a3594a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:12:30 -0700 +Subject: hfsplus: fix volume corruption issue for generic/070 + +From: Viacheslav Dubeyko + +[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ] + +The xfstests' test-case generic/070 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent +(see xfstests-dev/results//generic/070.full for details) + +Ran: generic/070 +Failures: generic/070 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop50 +** /dev/loop50 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +Unused node is not erased (node = 1) +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 +CBTStat = 0x0000 CatStat = 0x00000000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume test was repaired successfully. + +It is possible to see that fsck.hfsplus detected not +erased and unused node for the case of extents overflow file. +The HFS+ logic has special method that defines if the node +should be erased: + +bool hfs_bnode_need_zeroout(struct hfs_btree *tree) +{ + struct super_block *sb = tree->inode->i_sb; + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + + return tree->cnid == HFSPLUS_CAT_CNID && + volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; +} + +However, it is possible to see that this method works +only for the case of catalog file. But debugging of the issue +has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been +requested for the extents overflow file too: + +catalog file +kernel: hfsplus: node 4, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800 + +extents overflow file +kernel: hfsplus: node 1, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800 + +This patch modifies the hfs_bnode_need_zeroout() by checking +only volume_attr but not the b-tree ID because node zeroing +can be requested for all HFS+ b-tree types. + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 33s ... 34s +Ran: generic/070 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index 407d5152eb411..aa095e6fb20e8 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -704,6 +704,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + +- return tree->cnid == HFSPLUS_CAT_CNID && +- volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; ++ return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + } +-- +2.51.0 + diff --git a/queue-6.1/hfsplus-fix-volume-corruption-issue-for-generic-073.patch b/queue-6.1/hfsplus-fix-volume-corruption-issue-for-generic-073.patch new file mode 100644 index 0000000000..7946970bf9 --- /dev/null +++ b/queue-6.1/hfsplus-fix-volume-corruption-issue-for-generic-073.patch @@ -0,0 +1,125 @@ +From 684a617bf8ecb72dd2a537b30dc3b8b5106b3fd7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:25:23 -0800 +Subject: hfsplus: fix volume corruption issue for generic/073 + +From: Viacheslav Dubeyko + +[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ] + +The xfstests' test-case generic/073 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent +(see XFSTESTS-2/xfstests-dev/results//generic/073.full for details) + +Ran: generic/073 +Failures: generic/073 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +Invalid directory item count +(It should be 1 instead of 0) +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 +CBTStat = 0x0000 CatStat = 0x00004000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled was repaired successfully. + +The test is doing these steps on final phase: + +mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo + +So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ +logic decrements the number of entries in testdir_1 and increments number of +entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not +for testdir_2. As a result, this is the reason why fsck.hfsplus detects the +volume corruption afterwards. + +This patch fixes the issue by means of adding the +hfsplus_cat_write_inode() call for old_dir and new_dir in +hfsplus_rename() after the successful ending of +hfsplus_rename_cat(). This method makes modification of in-core +inode objects for old_dir and new_dir but it doesn't save these +modifications in Catalog File's entries. It was expected that +hfsplus_write_inode() will save these modifications afterwards. +However, because generic/073 does fsync only for testdir_1 and foo +then testdir_2 modification hasn't beed saved into Catalog File's +entry and it was flushed without this modification. And it was +detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog +File all modified entries and correct state of Catalog File will +be flushed during hfsplus_file_fsync() call. Finally, it makes +fsck.hfsplus happy. + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 32s ... 32s +Ran: generic/073 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/dir.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c +index 84714bbccc123..98a30ca6354ce 100644 +--- a/fs/hfsplus/dir.c ++++ b/fs/hfsplus/dir.c +@@ -552,8 +552,13 @@ static int hfsplus_rename(struct user_namespace *mnt_userns, + res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, + old_dir, &old_dentry->d_name, + new_dir, &new_dentry->d_name); +- if (!res) ++ if (!res) { + new_dentry->d_fsdata = old_dentry->d_fsdata; ++ ++ res = hfsplus_cat_write_inode(old_dir); ++ if (!res) ++ res = hfsplus_cat_write_inode(new_dir); ++ } + return res; + } + +-- +2.51.0 + diff --git a/queue-6.1/hfsplus-verify-inode-mode-when-loading-from-disk.patch b/queue-6.1/hfsplus-verify-inode-mode-when-loading-from-disk.patch new file mode 100644 index 0000000000..01cb806ea7 --- /dev/null +++ b/queue-6.1/hfsplus-verify-inode-mode-when-loading-from-disk.patch @@ -0,0 +1,105 @@ +From 5d51e3de9b5016a11235d35a236554c679e50743 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 18:18:54 +0900 +Subject: hfsplus: Verify inode mode when loading from disk + +From: Tetsuo Handa + +[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ] + +syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when +the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted. + +According to [1], the permissions field was treated as reserved in Mac OS +8 and 9. According to [2], the reserved field was explicitly initialized +with 0, and that field must remain 0 as long as reserved. Therefore, when +the "mode" field is not 0 (i.e. no longer reserved), the file must be +S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ +S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlusPermissions [1] +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#ReservedAndPadFields [2] +Signed-off-by: Tetsuo Handa +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA.ne.jp +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index 399a6354f0cc5..98291bd73b65f 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -183,13 +183,29 @@ const struct dentry_operations hfsplus_dentry_operations = { + .d_compare = hfsplus_compare_dentry, + }; + +-static void hfsplus_get_perms(struct inode *inode, +- struct hfsplus_perm *perms, int dir) ++static int hfsplus_get_perms(struct inode *inode, ++ struct hfsplus_perm *perms, int dir) + { + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + u16 mode; + + mode = be16_to_cpu(perms->mode); ++ if (dir) { ++ if (mode && !S_ISDIR(mode)) ++ goto bad_type; ++ } else if (mode) { ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ case S_IFLNK: ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: ++ break; ++ default: ++ goto bad_type; ++ } ++ } + + i_uid_write(inode, be32_to_cpu(perms->owner)); + if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) +@@ -215,6 +231,10 @@ static void hfsplus_get_perms(struct inode *inode, + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; ++ return 0; ++bad_type: ++ pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); ++ return -EIO; + } + + static int hfsplus_file_open(struct inode *inode, struct file *file) +@@ -518,7 +538,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); +- hfsplus_get_perms(inode, &folder->permissions, 1); ++ res = hfsplus_get_perms(inode, &folder->permissions, 1); ++ if (res) ++ goto out; + set_nlink(inode, 1); + inode->i_size = 2 + be32_to_cpu(folder->valence); + inode->i_atime = hfsp_mt2ut(folder->access_date); +@@ -545,7 +567,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + + hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? + &file->rsrc_fork : &file->data_fork); +- hfsplus_get_perms(inode, &file->permissions, 0); ++ res = hfsplus_get_perms(inode, &file->permissions, 0); ++ if (res) ++ goto out; + set_nlink(inode, 1); + if (S_ISREG(inode->i_mode)) { + if (file->permissions.dev) +-- +2.51.0 + diff --git a/queue-6.1/kbuild-use-objtree-for-module-signing-key-path.patch b/queue-6.1/kbuild-use-objtree-for-module-signing-key-path.patch new file mode 100644 index 0000000000..3f737795c5 --- /dev/null +++ b/queue-6.1/kbuild-use-objtree-for-module-signing-key-path.patch @@ -0,0 +1,58 @@ +From 2bad9329b619a81595a32030dc0932c98c42a127 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 16:34:52 +0000 +Subject: kbuild: Use objtree for module signing key path + +From: Mikhail Malyshev + +[ Upstream commit af61da281f52aba0c5b090bafb3a31c5739850ff ] + +When building out-of-tree modules with CONFIG_MODULE_SIG_FORCE=y, +module signing fails because the private key path uses $(srctree) +while the public key path uses $(objtree). Since signing keys are +generated in the build directory during kernel compilation, both +paths should use $(objtree) for consistency. + +This causes SSL errors like: + SSL error:02001002:system library:fopen:No such file or directory + sign-file: /kernel-src/certs/signing_key.pem + +The issue occurs because: +- sig-key uses: $(srctree)/certs/signing_key.pem (source tree) +- cmd_sign uses: $(objtree)/certs/signing_key.x509 (build tree) + +But both keys are generated in $(objtree) during the build. + +This complements commit 25ff08aa43e37 ("kbuild: Fix signing issue for +external modules") which fixed the scripts path and public key path, +but missed the private key path inconsistency. + +Fixes out-of-tree module signing for configurations with separate +source and build directories (e.g., O=/kernel-out). + +Signed-off-by: Mikhail Malyshev +Reviewed-by: Nathan Chancellor +Tested-by: Nicolas Schier +Link: https://patch.msgid.link/20251015163452.3754286-1-mike.malyshev@gmail.com +Signed-off-by: Nicolas Schier +Signed-off-by: Sasha Levin +--- + scripts/Makefile.modinst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst +index 10df89b9ef679..dc947e7872b9f 100644 +--- a/scripts/Makefile.modinst ++++ b/scripts/Makefile.modinst +@@ -67,7 +67,7 @@ endif + # + ifeq ($(CONFIG_MODULE_SIG_ALL),y) + ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) +-sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) ++sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) + else + sig-key := $(CONFIG_MODULE_SIG_KEY) + endif +-- +2.51.0 + diff --git a/queue-6.1/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch b/queue-6.1/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch new file mode 100644 index 0000000000..139ce36a85 --- /dev/null +++ b/queue-6.1/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch @@ -0,0 +1,106 @@ +From 4023f771e8641f2f363cb0ec441e5cc240391a72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 09:05:46 +0900 +Subject: ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency + +From: Namjae Jeon + +[ Upstream commit b39a1833cc4a2755b02603eec3a71a85e9dff926 ] + +Under high concurrency, A tree-connection object (tcon) is freed on +a disconnect path while another path still holds a reference and later +executes *_put()/write on it. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/mgmt/tree_connect.c | 18 ++++-------------- + fs/smb/server/mgmt/tree_connect.h | 1 - + fs/smb/server/smb2pdu.c | 3 --- + 3 files changed, 4 insertions(+), 18 deletions(-) + +diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c +index 94a52a75014a4..9bde1b58f9c46 100644 +--- a/fs/smb/server/mgmt/tree_connect.c ++++ b/fs/smb/server/mgmt/tree_connect.c +@@ -77,7 +77,6 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + tree_conn->t_state = TREE_NEW; + status.tree_conn = tree_conn; + atomic_set(&tree_conn->refcount, 1); +- init_waitqueue_head(&tree_conn->refcount_q); + + ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, + GFP_KERNEL)); +@@ -99,14 +98,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + + void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) + { +- /* +- * Checking waitqueue to releasing tree connect on +- * tree disconnect. waitqueue_active is safe because it +- * uses atomic operation for condition. +- */ +- if (!atomic_dec_return(&tcon->refcount) && +- waitqueue_active(&tcon->refcount_q)) +- wake_up(&tcon->refcount_q); ++ if (atomic_dec_and_test(&tcon->refcount)) ++ kfree(tcon); + } + + int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, +@@ -118,14 +111,11 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, + xa_erase(&sess->tree_conns, tree_conn->id); + write_unlock(&sess->tree_conns_lock); + +- if (!atomic_dec_and_test(&tree_conn->refcount)) +- wait_event(tree_conn->refcount_q, +- atomic_read(&tree_conn->refcount) == 0); +- + ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); + ksmbd_release_tree_conn_id(sess, tree_conn->id); + ksmbd_share_config_put(tree_conn->share_conf); +- kfree(tree_conn); ++ if (atomic_dec_and_test(&tree_conn->refcount)) ++ kfree(tree_conn); + return ret; + } + +diff --git a/fs/smb/server/mgmt/tree_connect.h b/fs/smb/server/mgmt/tree_connect.h +index a42cdd0510411..f0023d86716f2 100644 +--- a/fs/smb/server/mgmt/tree_connect.h ++++ b/fs/smb/server/mgmt/tree_connect.h +@@ -33,7 +33,6 @@ struct ksmbd_tree_connect { + int maximal_access; + bool posix_extensions; + atomic_t refcount; +- wait_queue_head_t refcount_q; + unsigned int t_state; + }; + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index c50dbbfc4cd62..fe3d3d766719a 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -2181,7 +2181,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); + tcon->t_state = TREE_DISCONNECTED; + write_unlock(&sess->tree_conns_lock); + +@@ -2191,8 +2190,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- work->tcon = NULL; +- + rsp->StructureSize = cpu_to_le16(4); + err = ksmbd_iov_pin_rsp(work, rsp, + sizeof(struct smb2_tree_disconnect_rsp)); +-- +2.51.0 + diff --git a/queue-6.1/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch b/queue-6.1/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch new file mode 100644 index 0000000000..eaaad503e6 --- /dev/null +++ b/queue-6.1/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch @@ -0,0 +1,88 @@ +From 189d98cbfd9d077bb42277479ec4ab0fe8be6309 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 10:30:19 -0700 +Subject: livepatch: Match old_sympos 0 and 1 in klp_find_func() + +From: Song Liu + +[ Upstream commit 139560e8b973402140cafeb68c656c1374bd4c20 ] + +When there is only one function of the same name, old_sympos of 0 and 1 +are logically identical. Match them in klp_find_func(). + +This is to avoid a corner case with different toolchain behavior. + +In this specific issue, two versions of kpatch-build were used to +build livepatch for the same kernel. One assigns old_sympos == 0 for +unique local functions, the other assigns old_sympos == 1 for unique +local functions. Both versions work fine by themselves. (PS: This +behavior change was introduced in a downstream version of kpatch-build. +This change does not exist in upstream kpatch-build.) + +However, during livepatch upgrade (with the replace flag set) from a +patch built with one version of kpatch-build to the same fix built with +the other version of kpatch-build, livepatching fails with errors like: + +[ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' +... +[ 14.219466] Call Trace: +[ 14.219468] +[ 14.219469] dump_stack_lvl+0x47/0x60 +[ 14.219474] sysfs_warn_dup.cold+0x17/0x27 +[ 14.219476] sysfs_create_dir_ns+0x95/0xb0 +[ 14.219479] kobject_add_internal+0x9e/0x260 +[ 14.219483] kobject_add+0x68/0x80 +[ 14.219485] ? kstrdup+0x3c/0xa0 +[ 14.219486] klp_enable_patch+0x320/0x830 +[ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] +[ 14.219491] ? 0xffffffffa05eb000 +[ 14.219492] do_one_initcall+0x2e/0x190 +[ 14.219494] do_init_module+0x67/0x270 +[ 14.219496] init_module_from_file+0x75/0xa0 +[ 14.219499] idempotent_init_module+0x15a/0x240 +[ 14.219501] __x64_sys_finit_module+0x61/0xc0 +[ 14.219503] do_syscall_64+0x5b/0x160 +[ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 +[ 14.219507] RIP: 0033:0x7f545a4bd96d +... +[ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with + -EEXIST, don't try to register things with the same name ... + +This happens because klp_find_func() thinks somefunc with old_sympos==0 +is not the same as somefunc with old_sympos==1, and klp_add_object_nops +adds another xxx/func,1 to the list of functions to patch. + +Signed-off-by: Song Liu +Acked-by: Josh Poimboeuf +[pmladek@suse.com: Fixed some typos.] +Reviewed-by: Petr Mladek +Tested-by: Petr Mladek +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + kernel/livepatch/core.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c +index 0e651fd4cc9fc..e3f251ec1637f 100644 +--- a/kernel/livepatch/core.c ++++ b/kernel/livepatch/core.c +@@ -89,8 +89,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj, + struct klp_func *func; + + klp_for_each_func(obj, func) { ++ /* ++ * Besides identical old_sympos, also consider old_sympos ++ * of 0 and 1 are identical. ++ */ + if ((strcmp(old_func->old_name, func->old_name) == 0) && +- (old_func->old_sympos == func->old_sympos)) { ++ ((old_func->old_sympos == func->old_sympos) || ++ (old_func->old_sympos == 0 && func->old_sympos == 1) || ++ (old_func->old_sympos == 1 && func->old_sympos == 0))) { + return func; + } + } +-- +2.51.0 + diff --git a/queue-6.1/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch b/queue-6.1/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch new file mode 100644 index 0000000000..3a2aaacad1 --- /dev/null +++ b/queue-6.1/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch @@ -0,0 +1,83 @@ +From 5f59215a9acea3122fedf05f0740919ad91beaa7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 08:00:53 -0500 +Subject: perf/x86/amd: Check event before enable to avoid GPF + +From: George Kennedy + +[ Upstream commit 866cf36bfee4fba6a492d2dcc5133f857e3446b0 ] + +On AMD machines cpuc->events[idx] can become NULL in a subtle race +condition with NMI->throttle->x86_pmu_stop(). + +Check event for NULL in amd_pmu_enable_all() before enable to avoid a GPF. +This appears to be an AMD only issue. + +Syzkaller reported a GPF in amd_pmu_enable_all. + +INFO: NMI handler (perf_event_nmi_handler) took too long to run: 13.143 + msecs +Oops: general protection fault, probably for non-canonical address + 0xdffffc0000000034: 0000 PREEMPT SMP KASAN NOPTI +KASAN: null-ptr-deref in range [0x00000000000001a0-0x00000000000001a7] +CPU: 0 UID: 0 PID: 328415 Comm: repro_36674776 Not tainted 6.12.0-rc1-syzk +RIP: 0010:x86_pmu_enable_event (arch/x86/events/perf_event.h:1195 + arch/x86/events/core.c:1430) +RSP: 0018:ffff888118009d60 EFLAGS: 00010012 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: 0000000000000034 RSI: 0000000000000000 RDI: 00000000000001a0 +RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002 +R13: ffff88811802a440 R14: ffff88811802a240 R15: ffff8881132d8601 +FS: 00007f097dfaa700(0000) GS:ffff888118000000(0000) GS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000200001c0 CR3: 0000000103d56000 CR4: 00000000000006f0 +Call Trace: + +amd_pmu_enable_all (arch/x86/events/amd/core.c:760 (discriminator 2)) +x86_pmu_enable (arch/x86/events/core.c:1360) +event_sched_out (kernel/events/core.c:1191 kernel/events/core.c:1186 + kernel/events/core.c:2346) +__perf_remove_from_context (kernel/events/core.c:2435) +event_function (kernel/events/core.c:259) +remote_function (kernel/events/core.c:92 (discriminator 1) + kernel/events/core.c:72 (discriminator 1)) +__flush_smp_call_function_queue (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 ./include/trace/events/csd.h:64 + kernel/smp.c:135 kernel/smp.c:540) +__sysvec_call_function_single (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 + ./arch/x86/include/asm/trace/irq_vectors.h:99 arch/x86/kernel/smp.c:272) +sysvec_call_function_single (arch/x86/kernel/smp.c:266 (discriminator 47) + arch/x86/kernel/smp.c:266 (discriminator 47)) + + +Reported-by: syzkaller +Signed-off-by: George Kennedy +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + arch/x86/events/amd/core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c +index 1282f1a702139..5a6ef45dc9b68 100644 +--- a/arch/x86/events/amd/core.c ++++ b/arch/x86/events/amd/core.c +@@ -731,7 +731,12 @@ static void amd_pmu_enable_all(int added) + if (!test_bit(idx, cpuc->active_mask)) + continue; + +- amd_pmu_enable_event(cpuc->events[idx]); ++ /* ++ * FIXME: cpuc->events[idx] can become NULL in a subtle race ++ * condition with NMI->throttle->x86_pmu_stop(). ++ */ ++ if (cpuc->events[idx]) ++ amd_pmu_enable_event(cpuc->events[idx]); + } + } + +-- +2.51.0 + diff --git a/queue-6.1/sched-deadline-only-set-free_cpus-for-online-runqueu.patch b/queue-6.1/sched-deadline-only-set-free_cpus-for-online-runqueu.patch new file mode 100644 index 0000000000..ee1003d152 --- /dev/null +++ b/queue-6.1/sched-deadline-only-set-free_cpus-for-online-runqueu.patch @@ -0,0 +1,189 @@ +From 04f369b967a979746bae9097622cb7262f33ee8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 18:22:36 -0700 +Subject: sched/deadline: only set free_cpus for online runqueues + +From: Doug Berger + +[ Upstream commit 382748c05e58a9f1935f5a653c352422375566ea ] + +Commit 16b269436b72 ("sched/deadline: Modify cpudl::free_cpus +to reflect rd->online") introduced the cpudl_set/clear_freecpu +functions to allow the cpu_dl::free_cpus mask to be manipulated +by the deadline scheduler class rq_on/offline callbacks so the +mask would also reflect this state. + +Commit 9659e1eeee28 ("sched/deadline: Remove cpu_active_mask +from cpudl_find()") removed the check of the cpu_active_mask to +save some processing on the premise that the cpudl::free_cpus +mask already reflected the runqueue online state. + +Unfortunately, there are cases where it is possible for the +cpudl_clear function to set the free_cpus bit for a CPU when the +deadline runqueue is offline. When this occurs while a CPU is +connected to the default root domain the flag may retain the bad +state after the CPU has been unplugged. Later, a different CPU +that is transitioning through the default root domain may push a +deadline task to the powered down CPU when cpudl_find sees its +free_cpus bit is set. If this happens the task will not have the +opportunity to run. + +One example is outlined here: +https://lore.kernel.org/lkml/20250110233010.2339521-1-opendmb@gmail.com + +Another occurs when the last deadline task is migrated from a +CPU that has an offlined runqueue. The dequeue_task member of +the deadline scheduler class will eventually call cpudl_clear +and set the free_cpus bit for the CPU. + +This commit modifies the cpudl_clear function to be aware of the +online state of the deadline runqueue so that the free_cpus mask +can be updated appropriately. + +It is no longer necessary to manage the mask outside of the +cpudl_set/clear functions so the cpudl_set/clear_freecpu +functions are removed. In addition, since the free_cpus mask is +now only updated under the cpudl lock the code was changed to +use the non-atomic __cpumask functions. + +Signed-off-by: Doug Berger +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + kernel/sched/cpudeadline.c | 34 +++++++++------------------------- + kernel/sched/cpudeadline.h | 4 +--- + kernel/sched/deadline.c | 8 ++++---- + 3 files changed, 14 insertions(+), 32 deletions(-) + +diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c +index 57c92d751bcd7..afa84e1216ee9 100644 +--- a/kernel/sched/cpudeadline.c ++++ b/kernel/sched/cpudeadline.c +@@ -165,12 +165,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, + * cpudl_clear - remove a CPU from the cpudl max-heap + * @cp: the cpudl max-heap context + * @cpu: the target CPU ++ * @online: the online state of the deadline runqueue + * + * Notes: assumes cpu_rq(cpu)->lock is locked + * + * Returns: (void) + */ +-void cpudl_clear(struct cpudl *cp, int cpu) ++void cpudl_clear(struct cpudl *cp, int cpu, bool online) + { + int old_idx, new_cpu; + unsigned long flags; +@@ -183,7 +184,7 @@ void cpudl_clear(struct cpudl *cp, int cpu) + if (old_idx == IDX_INVALID) { + /* + * Nothing to remove if old_idx was invalid. +- * This could happen if a rq_offline_dl is ++ * This could happen if rq_online_dl or rq_offline_dl is + * called for a CPU without -dl tasks running. + */ + } else { +@@ -194,9 +195,12 @@ void cpudl_clear(struct cpudl *cp, int cpu) + cp->elements[new_cpu].idx = old_idx; + cp->elements[cpu].idx = IDX_INVALID; + cpudl_heapify(cp, old_idx); +- +- cpumask_set_cpu(cpu, cp->free_cpus); + } ++ if (likely(online)) ++ __cpumask_set_cpu(cpu, cp->free_cpus); ++ else ++ __cpumask_clear_cpu(cpu, cp->free_cpus); ++ + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +@@ -227,7 +231,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + cp->elements[new_idx].cpu = cpu; + cp->elements[cpu].idx = new_idx; + cpudl_heapify_up(cp, new_idx); +- cpumask_clear_cpu(cpu, cp->free_cpus); ++ __cpumask_clear_cpu(cpu, cp->free_cpus); + } else { + cp->elements[old_idx].dl = dl; + cpudl_heapify(cp, old_idx); +@@ -236,26 +240,6 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +-/* +- * cpudl_set_freecpu - Set the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_set_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_set_cpu(cpu, cp->free_cpus); +-} +- +-/* +- * cpudl_clear_freecpu - Clear the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_clear_cpu(cpu, cp->free_cpus); +-} +- + /* + * cpudl_init - initialize the cpudl structure + * @cp: the cpudl max-heap context +diff --git a/kernel/sched/cpudeadline.h b/kernel/sched/cpudeadline.h +index 0adeda93b5fb5..ecff718d94aea 100644 +--- a/kernel/sched/cpudeadline.h ++++ b/kernel/sched/cpudeadline.h +@@ -18,9 +18,7 @@ struct cpudl { + #ifdef CONFIG_SMP + int cpudl_find(struct cpudl *cp, struct task_struct *p, struct cpumask *later_mask); + void cpudl_set(struct cpudl *cp, int cpu, u64 dl); +-void cpudl_clear(struct cpudl *cp, int cpu); ++void cpudl_clear(struct cpudl *cp, int cpu, bool online); + int cpudl_init(struct cpudl *cp); +-void cpudl_set_freecpu(struct cpudl *cp, int cpu); +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu); + void cpudl_cleanup(struct cpudl *cp); + #endif /* CONFIG_SMP */ +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index 75fe40c6d080f..62a7c4ed86753 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -1486,7 +1486,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline) + if (!dl_rq->dl_nr_running) { + dl_rq->earliest_dl.curr = 0; + dl_rq->earliest_dl.next = 0; +- cpudl_clear(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, rq->online); + cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr); + } else { + struct rb_node *leftmost = rb_first_cached(&dl_rq->root); +@@ -2554,9 +2554,10 @@ static void rq_online_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_set_overload(rq); + +- cpudl_set_freecpu(&rq->rd->cpudl, rq->cpu); + if (rq->dl.dl_nr_running > 0) + cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr); ++ else ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, true); + } + + /* Assumes rq->lock is held */ +@@ -2565,8 +2566,7 @@ static void rq_offline_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_clear_overload(rq); + +- cpudl_clear(&rq->rd->cpudl, rq->cpu); +- cpudl_clear_freecpu(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, false); + } + + void __init init_sched_dl_class(void) +-- +2.51.0 + diff --git a/queue-6.1/sched-fair-revert-max_newidle_lb_cost-bump.patch b/queue-6.1/sched-fair-revert-max_newidle_lb_cost-bump.patch new file mode 100644 index 0000000000..f0f633f756 --- /dev/null +++ b/queue-6.1/sched-fair-revert-max_newidle_lb_cost-bump.patch @@ -0,0 +1,77 @@ +From 1aea48d936e10edebb3bca9359619fa5a41ee57c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 17:01:20 +0100 +Subject: sched/fair: Revert max_newidle_lb_cost bump + +From: Peter Zijlstra + +[ Upstream commit d206fbad9328ddb68ebabd7cf7413392acd38081 ] + +Many people reported regressions on their database workloads due to: + + 155213a2aed4 ("sched/fair: Bump sd->max_newidle_lb_cost when newidle balance fails") + +For instance Adam Li reported a 6% regression on SpecJBB. + +Conversely this will regress schbench again; on my machine from 2.22 +Mrps/s down to 2.04 Mrps/s. + +Reported-by: Joseph Salisbury +Reported-by: Adam Li +Reported-by: Dietmar Eggemann +Reported-by: Hazem Mohamed Abuelfotoh +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dietmar Eggemann +Tested-by: Dietmar Eggemann +Tested-by: Chris Mason +Link: https://lkml.kernel.org/r/20250626144017.1510594-2-clm@fb.com +Link: https://lkml.kernel.org/r/006c9df2-b691-47f1-82e6-e233c3f91faf@oracle.com +Link: https://patch.msgid.link/20251107161739.406147760@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 19 +++---------------- + 1 file changed, 3 insertions(+), 16 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index b6795bf15211c..f5a041bc3364f 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -10941,14 +10941,8 @@ static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) + /* + * Track max cost of a domain to make sure to not delay the + * next wakeup on the CPU. +- * +- * sched_balance_newidle() bumps the cost whenever newidle +- * balance fails, and we don't want things to grow out of +- * control. Use the sysctl_sched_migration_cost as the upper +- * limit, plus a litle extra to avoid off by ones. + */ +- sd->max_newidle_lb_cost = +- min(cost, sysctl_sched_migration_cost + 200); ++ sd->max_newidle_lb_cost = cost; + sd->last_decay_max_lb_cost = jiffies; + } else if (time_after(jiffies, sd->last_decay_max_lb_cost + HZ)) { + /* +@@ -11630,17 +11624,10 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) + + t1 = sched_clock_cpu(this_cpu); + domain_cost = t1 - t0; ++ update_newidle_cost(sd, domain_cost); ++ + curr_cost += domain_cost; + t0 = t1; +- +- /* +- * Failing newidle means it is not effective; +- * bump the cost so we end up doing less of it. +- */ +- if (!pulled_task) +- domain_cost = (3 * sd->max_newidle_lb_cost) / 2; +- +- update_newidle_cost(sd, domain_cost); + } + + /* +-- +2.51.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 3b68b170a2..5465e73a07 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -222,3 +222,26 @@ usb-gadget-tegra-xudc-always-reinitialize-data-toggle-when-clear-halt.patch usb-phy-initialize-struct-usb_phy-list_head.patch alsa-dice-fix-buffer-overflow-in-detect_stream_formats.patch asoc-fsl_xcvr-get-channel-status-data-when-phy-is-not-exists.patch +btrfs-do-not-skip-logging-new-dentries-when-logging-.patch +bpf-arm64-do-not-audit-capability-check-in-do_jit.patch +btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch +perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch +sched-deadline-only-set-free_cpus-for-online-runqueu.patch +sched-fair-revert-max_newidle_lb_cost-bump.patch +x86-ptrace-always-inline-trivial-accessors.patch +acpica-avoid-walking-the-namespace-if-start_node-is-.patch +acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch +cpufreq-s5pv210-fix-refcount-leak.patch +livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch +fs-ntfs3-support-timestamps-prior-to-epoch.patch +kbuild-use-objtree-for-module-signing-key-path.patch +hfsplus-fix-volume-corruption-issue-for-generic-070.patch +hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch +hfsplus-verify-inode-mode-when-loading-from-disk.patch +hfsplus-fix-volume-corruption-issue-for-generic-073.patch +wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch +btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch +smb-server-fix-return-value-of-smb2_ioctl.patch +ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch +bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch +gfs2-fix-use-of-bio_chain.patch diff --git a/queue-6.1/smb-server-fix-return-value-of-smb2_ioctl.patch b/queue-6.1/smb-server-fix-return-value-of-smb2_ioctl.patch new file mode 100644 index 0000000000..8499ff3570 --- /dev/null +++ b/queue-6.1/smb-server-fix-return-value-of-smb2_ioctl.patch @@ -0,0 +1,61 @@ +From 05fe507fa5b83f8d19eb1a716c94dcaa3e5de397 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:46:10 +0800 +Subject: smb/server: fix return value of smb2_ioctl() + +From: ChenXiaoSong + +[ Upstream commit 269df046c1e15ab34fa26fd90db9381f022a0963 ] + +__process_request() will not print error messages if smb2_ioctl() +always returns 0. + +Fix this by returning the correct value at the end of function. + +Signed-off-by: ChenXiaoSong +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/smb2pdu.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index 5a405706694b3..c50dbbfc4cd62 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -7727,7 +7727,7 @@ int smb2_ioctl(struct ksmbd_work *work) + id = req->VolatileFileId; + + if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) { +- rsp->hdr.Status = STATUS_NOT_SUPPORTED; ++ ret = -EOPNOTSUPP; + goto out; + } + +@@ -7747,8 +7747,9 @@ int smb2_ioctl(struct ksmbd_work *work) + case FSCTL_DFS_GET_REFERRALS: + case FSCTL_DFS_GET_REFERRALS_EX: + /* Not support DFS yet */ ++ ret = -EOPNOTSUPP; + rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED; +- goto out; ++ goto out2; + case FSCTL_CREATE_OR_GET_OBJECT_ID: + { + struct file_object_buf_type1_ioctl_rsp *obj_buf; +@@ -8038,8 +8039,10 @@ int smb2_ioctl(struct ksmbd_work *work) + rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL; + else if (ret < 0 || rsp->hdr.Status == 0) + rsp->hdr.Status = STATUS_INVALID_PARAMETER; ++ ++out2: + smb2_set_err_rsp(work); +- return 0; ++ return ret; + } + + /** +-- +2.51.0 + diff --git a/queue-6.1/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch b/queue-6.1/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch new file mode 100644 index 0000000000..07d27b2e84 --- /dev/null +++ b/queue-6.1/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch @@ -0,0 +1,61 @@ +From a3dfd5694efe8291cecf978078e73e2feedfa5fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 11:03:14 +0100 +Subject: wifi: brcmfmac: Add DMI nvram filename quirk for Acer A1 840 tablet + +From: Hans de Goede + +[ Upstream commit a8e5a110c0c38e08e5dd66356cd1156e91cf88e1 ] + +The Acer A1 840 tablet contains quite generic names in the sys_vendor and +product_name DMI strings, without this patch brcmfmac will try to load: +brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file which is a bit +too generic. + +Add a DMI quirk so that a unique and clearly identifiable nvram file name +is used on the Acer A1 840 tablet. + +Acked-by: Arend van Spriel +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20251103100314.353826-1-hansg@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +index c3a602197662b..abe7f6501e5ed 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +@@ -24,6 +24,10 @@ static const struct brcmf_dmi_data acepc_t8_data = { + BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" + }; + ++static const struct brcmf_dmi_data acer_a1_840_data = { ++ BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" ++}; ++ + /* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus + * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. + */ +@@ -91,6 +95,16 @@ static const struct dmi_system_id dmi_platform_data[] = { + }, + .driver_data = (void *)&acepc_t8_data, + }, ++ { ++ /* Acer Iconia One 8 A1-840 (non FHD version) */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), ++ /* Above strings are too generic also match BIOS date */ ++ DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), ++ }, ++ .driver_data = (void *)&acer_a1_840_data, ++ }, + { + /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ + .matches = { +-- +2.51.0 + diff --git a/queue-6.1/x86-ptrace-always-inline-trivial-accessors.patch b/queue-6.1/x86-ptrace-always-inline-trivial-accessors.patch new file mode 100644 index 0000000000..73b6462d19 --- /dev/null +++ b/queue-6.1/x86-ptrace-always-inline-trivial-accessors.patch @@ -0,0 +1,89 @@ +From f4f6d2c13a0c4546c3f423b1f3ec33e6c743d2c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 12:04:24 +0100 +Subject: x86/ptrace: Always inline trivial accessors + +From: Peter Zijlstra + +[ Upstream commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa ] + +A KASAN build bloats these single load/store helpers such that +it fails to inline them: + + vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled + +Make sure the compiler isn't allowed to do stupid. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Link: https://patch.msgid.link/20251031105435.GU4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index f4db78b09c8f0..87d8f3c492c19 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -109,12 +109,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); + extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); + + +-static inline unsigned long regs_return_value(struct pt_regs *regs) ++static __always_inline unsigned long regs_return_value(struct pt_regs *regs) + { + return regs->ax; + } + +-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) ++static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) + { + regs->ax = rc; + } +@@ -199,34 +199,34 @@ static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) + } + #endif + +-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline unsigned long instruction_pointer(struct pt_regs *regs) ++static __always_inline unsigned long instruction_pointer(struct pt_regs *regs) + { + return regs->ip; + } + +-static inline void instruction_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void instruction_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->ip = val; + } + +-static inline unsigned long frame_pointer(struct pt_regs *regs) ++static __always_inline unsigned long frame_pointer(struct pt_regs *regs) + { + return regs->bp; + } + +-static inline unsigned long user_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long user_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline void user_stack_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->sp = val; + } +-- +2.51.0 + diff --git a/queue-6.12/acpi-fan-workaround-for-64-bit-firmware-bug.patch b/queue-6.12/acpi-fan-workaround-for-64-bit-firmware-bug.patch new file mode 100644 index 0000000000..a323b913e1 --- /dev/null +++ b/queue-6.12/acpi-fan-workaround-for-64-bit-firmware-bug.patch @@ -0,0 +1,126 @@ +From 1c4880a43d6f4a4e528d2ede065bed057b414847 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 01:41:45 +0200 +Subject: ACPI: fan: Workaround for 64-bit firmware bug + +From: Armin Wolf + +[ Upstream commit 2e00f7a4bb0ac25ec7477b55fe482da39fb4dce8 ] + +Some firmware implementations use the "Ones" ASL opcode to produce +an integer with all bits set in order to indicate missing speed or +power readings. This however only works when using 32-bit integers, +as the ACPI spec requires a 32-bit integer (0xFFFFFFFF) to be +returned for missing speed/power readings. With 64-bit integers the +"Ones" opcode produces a 64-bit integer with all bits set, violating +the ACPI spec regarding the placeholder value for missing readings. + +Work around such buggy firmware implementation by also checking for +64-bit integers with all bits set when reading _FST. + +Signed-off-by: Armin Wolf +[ rjw: Typo fix in the changelog ] +Link: https://patch.msgid.link/20251007234149.2769-3-W_Armin@gmx.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/fan.h | 33 +++++++++++++++++++++++++++++++++ + drivers/acpi/fan_hwmon.c | 10 +++------- + 2 files changed, 36 insertions(+), 7 deletions(-) + +diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h +index 612ccc4c28279..eb48ac000e3d9 100644 +--- a/drivers/acpi/fan.h ++++ b/drivers/acpi/fan.h +@@ -11,6 +11,7 @@ + #define _ACPI_FAN_H_ + + #include ++#include + + #define ACPI_FAN_DEVICE_IDS \ + {"INT3404", }, /* Fan */ \ +@@ -58,6 +59,38 @@ struct acpi_fan { + struct device_attribute fine_grain_control; + }; + ++/** ++ * acpi_fan_speed_valid - Check if fan speed value is valid ++ * @speeed: Speed value returned by the ACPI firmware ++ * ++ * Check if the fan speed value returned by the ACPI firmware is valid. This function is ++ * necessary as ACPI firmware implementations can return 0xFFFFFFFF to signal that the ++ * ACPI fan does not support speed reporting. Additionally, some buggy ACPI firmware ++ * implementations return a value larger than the 32-bit integer value defined by ++ * the ACPI specification when using placeholder values. Such invalid values are also ++ * detected by this function. ++ * ++ * Returns: True if the fan speed value is valid, false otherwise. ++ */ ++static inline bool acpi_fan_speed_valid(u64 speed) ++{ ++ return speed < U32_MAX; ++} ++ ++/** ++ * acpi_fan_power_valid - Check if fan power value is valid ++ * @power: Power value returned by the ACPI firmware ++ * ++ * Check if the fan power value returned by the ACPI firmware is valid. ++ * See acpi_fan_speed_valid() for details. ++ * ++ * Returns: True if the fan power value is valid, false otherwise. ++ */ ++static inline bool acpi_fan_power_valid(u64 power) ++{ ++ return power < U32_MAX; ++} ++ + int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst); + int acpi_fan_create_attributes(struct acpi_device *device); + void acpi_fan_delete_attributes(struct acpi_device *device); +diff --git a/drivers/acpi/fan_hwmon.c b/drivers/acpi/fan_hwmon.c +index 4b2c2007f2d7f..47a02ef5a6067 100644 +--- a/drivers/acpi/fan_hwmon.c ++++ b/drivers/acpi/fan_hwmon.c +@@ -15,10 +15,6 @@ + + #include "fan.h" + +-/* Returned when the ACPI fan does not support speed reporting */ +-#define FAN_SPEED_UNAVAILABLE U32_MAX +-#define FAN_POWER_UNAVAILABLE U32_MAX +- + static struct acpi_fan_fps *acpi_fan_get_current_fps(struct acpi_fan *fan, u64 control) + { + unsigned int i; +@@ -77,7 +73,7 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_ + * when the associated attribute should not be created. + */ + for (i = 0; i < fan->fps_count; i++) { +- if (fan->fps[i].power != FAN_POWER_UNAVAILABLE) ++ if (acpi_fan_power_valid(fan->fps[i].power)) + return 0444; + } + +@@ -106,7 +102,7 @@ static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_fan: + switch (attr) { + case hwmon_fan_input: +- if (fst.speed == FAN_SPEED_UNAVAILABLE) ++ if (!acpi_fan_speed_valid(fst.speed)) + return -ENODEV; + + if (fst.speed > LONG_MAX) +@@ -134,7 +130,7 @@ static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + if (!fps) + return -EIO; + +- if (fps->power == FAN_POWER_UNAVAILABLE) ++ if (!acpi_fan_power_valid(fps->power)) + return -ENODEV; + + if (fps->power > LONG_MAX / MICROWATT_PER_MILLIWATT) +-- +2.51.0 + diff --git a/queue-6.12/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch b/queue-6.12/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch new file mode 100644 index 0000000000..e087e3bfaf --- /dev/null +++ b/queue-6.12/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch @@ -0,0 +1,59 @@ +From a5fff57b71734df106bd45fb61460127e5e7f84e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 13:43:19 +0300 +Subject: ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() + only + +From: Sakari Ailus + +[ Upstream commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 ] + +Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode +property API is somewhat problematic as the latter is used in the +impelementation of the former. Instead of using +fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call +acpi_get_next_subnode() directly instead. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20251001104320.1272752-3-sakari.ailus@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index b7ee463e757d2..8a37de04b69be 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1441,7 +1441,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + + if (!prev) { + do { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + /* + * The names of the port nodes begin with "port@" + * followed by the number of the port node and they also +@@ -1459,13 +1459,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + if (!port) + return NULL; + +- endpoint = fwnode_get_next_child_node(port, prev); ++ endpoint = acpi_get_next_subnode(port, prev); + while (!endpoint) { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + if (!port) + break; + if (is_acpi_graph_node(port, "port")) +- endpoint = fwnode_get_next_child_node(port, NULL); ++ endpoint = acpi_get_next_subnode(port, NULL); + } + + /* +-- +2.51.0 + diff --git a/queue-6.12/acpica-avoid-walking-the-namespace-if-start_node-is-.patch b/queue-6.12/acpica-avoid-walking-the-namespace-if-start_node-is-.patch new file mode 100644 index 0000000000..160cc6c6c2 --- /dev/null +++ b/queue-6.12/acpica-avoid-walking-the-namespace-if-start_node-is-.patch @@ -0,0 +1,63 @@ +From 6f8246c1087f5400aa0b889d616823a2979cf491 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:14:38 +0800 +Subject: ACPICA: Avoid walking the Namespace if start_node is NULL + +From: Cryolitia PukNgae + +[ Upstream commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 ] + +Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace +if it is not there") fixed the situation when both start_node and +acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed +on Honor Magicbook 14 Pro [1]. + +That happens due to the access to the member of parent_node in +acpi_ns_get_next_node(). The NULL pointer dereference will always +happen, no matter whether or not the start_node is equal to +ACPI_ROOT_OBJECT, so move the check of start_node being NULL +out of the if block. + +Unfortunately, all the attempts to contact Honor have failed, they +refused to provide any technical support for Linux. + +The bad DSDT table's dump could be found on GitHub [2]. + +DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025 + +Link: https://github.com/acpica/acpica/commit/1c1b57b9eba4554cb132ee658dd942c0210ed20d +Link: https://gist.github.com/Cryolitia/a860ffc97437dcd2cd988371d5b73ed7 [1] +Link: https://github.com/denis-bb/honor-fmb-p-dsdt [2] +Signed-off-by: Cryolitia PukNgae +Reviewed-by: WangYuli +[ rjw: Subject adjustment, changelog edits ] +Link: https://patch.msgid.link/20251125-acpica-v1-1-99e63b1b25f8@linux.dev +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/nswalk.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c +index eee396a77baec..1b000ccbf8e1f 100644 +--- a/drivers/acpi/acpica/nswalk.c ++++ b/drivers/acpi/acpica/nswalk.c +@@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type, + + if (start_node == ACPI_ROOT_OBJECT) { + start_node = acpi_gbl_root_node; +- if (!start_node) { +- return_ACPI_STATUS(AE_NO_NAMESPACE); +- } ++ } ++ ++ /* Avoid walking the namespace if the StartNode is NULL */ ++ ++ if (!start_node) { ++ return_ACPI_STATUS(AE_NO_NAMESPACE); + } + + /* Null child means "get first node" */ +-- +2.51.0 + diff --git a/queue-6.12/bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch b/queue-6.12/bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch new file mode 100644 index 0000000000..75cb5cb571 --- /dev/null +++ b/queue-6.12/bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch @@ -0,0 +1,67 @@ +From da08d2c9262bf86cb8ba59d59fca8f4fc37489da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 13:50:39 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 0x0489/0xE12F for RTL8852BE-VT + +From: Max Chou + +[ Upstream commit 32caa197b9b603e20f49fd3a0dffecd0cd620499 ] + +Add the support ID(0x0489, 0xE12F) to usb_device_id table for +Realtek RTL8852BE-VT. + +The device info from /sys/kernel/debug/usb/devices as below. + +T: Bus=04 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 86 Spd=12 MxCh= 0 +D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e12f Rev= 0.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Max Chou +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 2531ea7f163cb..fc7b3e02f14b7 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -577,6 +577,8 @@ static const struct usb_device_id quirks_table[] = { + /* Realtek 8852BT/8852BE-VT Bluetooth devices */ + { USB_DEVICE(0x0bda, 0x8520), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe12f), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8922AE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0x8922), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-6.12/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch b/queue-6.12/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch new file mode 100644 index 0000000000..45b01f232f --- /dev/null +++ b/queue-6.12/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch @@ -0,0 +1,67 @@ +From 7a31dbc5b369ffb2c1d2b0a87eeff79b2e3aebab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 15:33:38 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE + +From: Gongwei Li + +[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ] + +Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3533 Rev= 1.10 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Gongwei Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 78dc9012c5d75..2531ea7f163cb 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -501,6 +501,8 @@ static const struct usb_device_id quirks_table[] = { + /* Realtek 8821CE Bluetooth devices */ + { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-6.12/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch b/queue-6.12/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch new file mode 100644 index 0000000000..54f9dd1c6a --- /dev/null +++ b/queue-6.12/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch @@ -0,0 +1,67 @@ +From f3ccda628a7c756266ef86074d391a8f71358fc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 16:46:47 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 2b89/6275 for RTL8761BUV + +From: Chingbin Li + +[ Upstream commit 8dbbb5423c0802ec21266765de80fd491868fab1 ] + +Add VID 2b89 & PID 6275 for Realtek RTL8761BUV USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=2b89 ProdID=6275 Rev= 2.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00E04C239987 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Chingbin Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index dc0c45756c448..479b98befdc5f 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -763,6 +763,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x2b89, 0x6275), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Additional Realtek 8821AE Bluetooth devices */ + { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, +-- +2.51.0 + diff --git a/queue-6.12/bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch b/queue-6.12/bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch new file mode 100644 index 0000000000..de73bb5f9b --- /dev/null +++ b/queue-6.12/bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch @@ -0,0 +1,78 @@ +From d090e87500ab400429a559776651418714434a61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 11:31:49 +0800 +Subject: Bluetooth: btusb: MT7920: Add VID/PID 0489/e135 + +From: Chris Lu + +[ Upstream commit c126f98c011f5796ba118ef2093122d02809d30d ] + +Add VID 0489 & PID e135 for MediaTek MT7920 USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e135 Rev= 1.00 +S: Manufacturer=MediaTek Inc. +S: Product=Wireless_Device +S: SerialNumber=000000000 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA +A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us +I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us + +Signed-off-by: Chris Lu +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 9dc3a50c5e833..78dc9012c5d75 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -611,6 +611,8 @@ static const struct usb_device_id quirks_table[] = { + /* Additional MediaTek MT7920 Bluetooth devices */ + { USB_DEVICE(0x0489, 0xe134), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe135), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3620), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3621), .driver_info = BTUSB_MEDIATEK | +-- +2.51.0 + diff --git a/queue-6.12/bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch b/queue-6.12/bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch new file mode 100644 index 0000000000..34be28c253 --- /dev/null +++ b/queue-6.12/bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch @@ -0,0 +1,78 @@ +From 59167d7a29afa6ecbc4148981a06548766173235 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 11:31:50 +0800 +Subject: Bluetooth: btusb: MT7922: Add VID/PID 0489/e170 + +From: Chris Lu + +[ Upstream commit 5a6700a31c953af9a17a7e2681335f31d922614d ] + +Add VID 0489 & PID e170 for MediaTek MT7922 USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e170 Rev= 1.00 +S: Manufacturer=MediaTek Inc. +S: Product=Wireless_Device +S: SerialNumber=000000000 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA +A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us +I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us + +Signed-off-by: Chris Lu +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 479b98befdc5f..9dc3a50c5e833 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -673,6 +673,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe153), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe170), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK | +-- +2.51.0 + diff --git a/queue-6.12/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch b/queue-6.12/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch new file mode 100644 index 0000000000..6dfab379a3 --- /dev/null +++ b/queue-6.12/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch @@ -0,0 +1,56 @@ +From ac66f8ed1522504efa6507af823bc6126e37f581 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Dec 2025 13:59:16 +0100 +Subject: bpf, arm64: Do not audit capability check in do_jit() + +From: Ondrej Mosnacek + +[ Upstream commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c ] + +Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit +capability check in do_jit()"), change the capable() call to +ns_capable_noaudit() in order to avoid spurious SELinux denials in audit +log. + +The commit log from that commit applies here as well: +""" +The failure of this check only results in a security mitigation being +applied, slightly affecting performance of the compiled BPF program. It +doesn't result in a failed syscall, an thus auditing a failed LSM +permission check for it is unwanted. For example with SELinux, it causes +a denial to be reported for confined processes running as root, which +tends to be flagged as a problem to be fixed in the policy. Yet +dontauditing or allowing CAP_SYS_ADMIN to the domain may not be +desirable, as it would allow/silence also other checks - either going +against the principle of least privilege or making debugging potentially +harder. + +Fix it by changing it from capable() to ns_capable_noaudit(), which +instructs the LSMs to not audit the resulting denials. +""" + +Fixes: f300769ead03 ("arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users") +Signed-off-by: Ondrej Mosnacek +Link: https://lore.kernel.org/r/20251204125916.441021-1-omosnace@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + arch/arm64/net/bpf_jit_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index ca6d002a6f137..82b57436f2f10 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -871,7 +871,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) + arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) + return; + +- if (capable(CAP_SYS_ADMIN)) ++ if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) + return; + + if (supports_clearbhb(SCOPE_SYSTEM)) { +-- +2.51.0 + diff --git a/queue-6.12/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch b/queue-6.12/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch new file mode 100644 index 0000000000..ee8593e5e2 --- /dev/null +++ b/queue-6.12/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch @@ -0,0 +1,72 @@ +From af78340bcc07269d0caf782451797dfad912ddde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 17:02:00 +0000 +Subject: btrfs: do not skip logging new dentries when logging a new name + +From: Filipe Manana + +[ Upstream commit 5630f7557de61264ccb4f031d4734a1a97eaed16 ] + +When we are logging a directory and the log context indicates that we +are logging a new name for some other file (that is or was inside that +directory), we skip logging the inodes for new dentries in the directory. + +This is ok most of the time, but if after the rename or link operation +that triggered the logging of that directory, we have an explicit fsync +of that directory without the directory inode being evicted and reloaded, +we end up never logging the inodes for the new dentries that we found +during the new name logging, as the next directory fsync will only process +dentries that were added after the last time we logged the directory (we +are doing an incremental directory logging). + +So make sure we always log new dentries for a directory even if we are +in a context of logging a new name. + +We started skipping logging inodes for new dentries as of commit +c48792c6ee7a ("btrfs: do not log new dentries when logging that a new name +exists") and it was fine back then, because when logging a directory we +always iterated over all the directory entries (for leaves changed in the +current transaction) so a subsequent fsync would always log anything that +was previously skipped while logging a directory when logging a new name +(with btrfs_log_new_name()). But later support for incrementally logging +a directory was added in commit dc2872247ec0 ("btrfs: keep track of the +last logged keys when logging a directory"), to avoid checking all dir +items every time we log a directory, so the check to skip dentry logging +added in the first commit should have been removed when the incremental +support for logging a directory was added. + +A test case for fstests will follow soon. + +Reported-by: Vyacheslav Kovalevsky +Link: https://lore.kernel.org/linux-btrfs/84c4e713-85d6-42b9-8dcf-0722ed26cb05@gmail.com/ +Fixes: dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory") +Reviewed-by: Boris Burkov +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tree-log.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 609f221d4c309..25ab8f3af56c8 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -5556,14 +5556,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, + struct btrfs_inode *curr_inode = start_inode; + int ret = 0; + +- /* +- * If we are logging a new name, as part of a link or rename operation, +- * don't bother logging new dentries, as we just want to log the names +- * of an inode and that any new parents exist. +- */ +- if (ctx->logging_new_name) +- return 0; +- + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.12/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch b/queue-6.12/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch new file mode 100644 index 0000000000..83d94ca957 --- /dev/null +++ b/queue-6.12/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch @@ -0,0 +1,49 @@ +From 2cea020367a7c61e311250247cf182ce17d55fee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 18:49:56 +1030 +Subject: btrfs: fix a potential path leak in print_data_reloc_error() + +From: Qu Wenruo + +[ Upstream commit 313ef70a9f0f637a09d9ef45222f5bdcf30a354b ] + +Inside print_data_reloc_error(), if extent_from_logical() failed we +return immediately. + +However there are the following cases where extent_from_logical() can +return error but still holds a path: + +- btrfs_search_slot() returned 0 + +- No backref item found in extent tree + +- No flags_ret provided + This is not possible in this call site though. + +So for the above two cases, we can return without releasing the path, +causing extent buffer leaks. + +Fixes: b9a9a85059cd ("btrfs: output affected files when relocation fails") +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 01a1b979b717f..ce13b0ec978ed 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -253,6 +253,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off + if (ret < 0) { + btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d", + logical, ret); ++ btrfs_release_path(&path); + return; + } + eb = path.nodes[0]; +-- +2.51.0 + diff --git a/queue-6.12/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch b/queue-6.12/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch new file mode 100644 index 0000000000..90cd291684 --- /dev/null +++ b/queue-6.12/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch @@ -0,0 +1,51 @@ +From 0b065957eec6c90b21c1f21985cd929f2f37a4c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 18:58:07 +0530 +Subject: btrfs: fix memory leak of fs_devices in degraded seed device path + +From: Deepanshu Kartikey + +[ Upstream commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 ] + +In open_seed_devices(), when find_fsid() fails and we're in DEGRADED +mode, a new fs_devices is allocated via alloc_fs_devices() but is never +added to the seed_list before returning. This contrasts with the normal +path where fs_devices is properly added via list_add(). + +If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), +the cleanup code iterates seed_list to free seed devices, but this +orphaned fs_devices is never found and never freed, causing a memory +leak. Any devices allocated via add_missing_dev() and attached to this +fs_devices are also leaked. + +Fix this by adding the newly allocated fs_devices to seed_list in the +degraded path, consistent with the normal path. + +Fixes: 5f37583569442 ("Btrfs: move the missing device to its own fs device list") +Reported-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=eadd98df8bceb15d7fed +Tested-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Reviewed-by: Qu Wenruo +Signed-off-by: Deepanshu Kartikey +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/volumes.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index ce991a8390466..9c6e96f630132 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -7071,6 +7071,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, + + fs_devices->seeding = true; + fs_devices->opened = 1; ++ list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); + return fs_devices; + } + +-- +2.51.0 + diff --git a/queue-6.12/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch b/queue-6.12/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch new file mode 100644 index 0000000000..18d6547ea9 --- /dev/null +++ b/queue-6.12/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch @@ -0,0 +1,90 @@ +From 53a53367bb63250b6deecdb30098a0d09c4f4d79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 12:51:09 +1030 +Subject: btrfs: scrub: always update btrfs_scrub_progress::last_physical + +From: Qu Wenruo + +[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ] + +[BUG] +When a scrub failed immediately without any byte scrubbed, the returned +btrfs_scrub_progress::last_physical will always be 0, even if there is a +non-zero @start passed into btrfs_scrub_dev() for resume cases. + +This will reset the progress and make later scrub resume start from the +beginning. + +[CAUSE] +The function btrfs_scrub_dev() accepts a @progress parameter to copy its +updated progress to the caller, there are cases where we either don't +touch progress::last_physical at all or copy 0 into last_physical: + +- last_physical not updated at all + If some error happened before scrubbing any super block or chunk, we + will not copy the progress, leaving the @last_physical untouched. + + E.g. failed to allocate @sctx, scrubbing a missing device or even + there is already a running scrub and so on. + + All those cases won't touch @progress at all, resulting the + last_physical untouched and will be left as 0 for most cases. + +- Error out before scrubbing any bytes + In those case we allocated @sctx, and sctx->stat.last_physical is all + zero (initialized by kvzalloc()). + Unfortunately some critical errors happened during + scrub_enumerate_chunks() or scrub_supers() before any stripe is really + scrubbed. + + In that case although we will copy sctx->stat back to @progress, since + no byte is really scrubbed, last_physical will be overwritten to 0. + +[FIX] +Make sure the parameter @progress always has its @last_physical member +updated to @start parameter inside btrfs_scrub_dev(). + +At the very beginning of the function, set @progress->last_physical to +@start, so that even if we error out without doing progress copying, +last_physical is still at @start. + +Then after we got @sctx allocated, set sctx->stat.last_physical to +@start, this will make sure even if we didn't get any byte scrubbed, at +the progress copying stage the @last_physical is not left as zero. + +This should resolve the resume progress reset problem. + +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index 9f811ea604f71..3cbb9f22d3944 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -2943,6 +2943,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + unsigned int nofs_flag; + bool need_commit = false; + ++ /* Set the basic fallback @last_physical before we got a sctx. */ ++ if (progress) ++ progress->last_physical = start; ++ + if (btrfs_fs_closing(fs_info)) + return -EAGAIN; + +@@ -2961,6 +2965,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + sctx = scrub_setup_ctx(fs_info, is_dev_replace); + if (IS_ERR(sctx)) + return PTR_ERR(sctx); ++ sctx->stat.last_physical = start; + + ret = scrub_workers_get(fs_info); + if (ret) +-- +2.51.0 + diff --git a/queue-6.12/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch b/queue-6.12/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch new file mode 100644 index 0000000000..c04e98d9b7 --- /dev/null +++ b/queue-6.12/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch @@ -0,0 +1,35 @@ +From fb0dfa5be2ce8716ed8a7a6c8ffb8d36f5e03541 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 16:00:48 +0800 +Subject: cpufreq: dt-platdev: Add JH7110S SOC to the allowlist + +From: Hal Feng + +[ Upstream commit 6e7970cab51d01b8f7c56f120486c571c22e1b80 ] + +Add the compatible strings for supporting the generic +cpufreq driver on the StarFive JH7110S SoC. + +Signed-off-by: Hal Feng +Reviewed-by: Heinrich Schuchardt +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 67bac12d4d55b..dbd73cd0cf535 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -87,6 +87,7 @@ static const struct of_device_id allowlist[] __initconst = { + { .compatible = "st-ericsson,u9540", }, + + { .compatible = "starfive,jh7110", }, ++ { .compatible = "starfive,jh7110s", }, + + { .compatible = "ti,omap2", }, + { .compatible = "ti,omap4", }, +-- +2.51.0 + diff --git a/queue-6.12/cpufreq-s5pv210-fix-refcount-leak.patch b/queue-6.12/cpufreq-s5pv210-fix-refcount-leak.patch new file mode 100644 index 0000000000..da2bb6319a --- /dev/null +++ b/queue-6.12/cpufreq-s5pv210-fix-refcount-leak.patch @@ -0,0 +1,62 @@ +From 24daca8fcd1db8d322fb32017eeb8b071b3387d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 03:31:17 +0800 +Subject: cpufreq: s5pv210: fix refcount leak + +From: Shuhao Fu + +[ Upstream commit 2de5cb96060a1664880d65b120e59485a73588a8 ] + +In function `s5pv210_cpu_init`, a possible refcount inconsistency has +been identified, causing a resource leak. + +Why it is a bug: +1. For every clk_get, there should be a matching clk_put on every +successive error handling path. +2. After calling `clk_get(dmc1_clk)`, variable `dmc1_clk` will not be +freed even if any error happens. + +How it is fixed: For every failed path, an extra goto label is added to +ensure `dmc1_clk` will be freed regardlessly. + +Signed-off-by: Shuhao Fu +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c +index 76c888ed8d160..d2fa42beae9c2 100644 +--- a/drivers/cpufreq/s5pv210-cpufreq.c ++++ b/drivers/cpufreq/s5pv210-cpufreq.c +@@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + + if (policy->cpu != 0) { + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* +@@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { + pr_err("CPUFreq doesn't support this memory type\n"); + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* Find current refresh counter and frequency each DMC */ +@@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + cpufreq_generic_init(policy, s5pv210_freq_table, 40000); + return 0; + ++out: ++ clk_put(dmc1_clk); + out_dmc1: + clk_put(dmc0_clk); + out_dmc0: +-- +2.51.0 + diff --git a/queue-6.12/cpuidle-menu-use-residency-threshold-in-polling-stat.patch b/queue-6.12/cpuidle-menu-use-residency-threshold-in-polling-stat.patch new file mode 100644 index 0000000000..ada8ed5df1 --- /dev/null +++ b/queue-6.12/cpuidle-menu-use-residency-threshold-in-polling-stat.patch @@ -0,0 +1,99 @@ +From 84bdd0a41de6c75e08bdf8ae40385d9be4b094e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 07:09:54 +0530 +Subject: cpuidle: menu: Use residency threshold in polling state override + decisions + +From: Aboorva Devarajan + +[ Upstream commit 07d815701274d156ad8c7c088a52e01642156fb8 ] + +On virtualized PowerPC (pseries) systems, where only one polling state +(Snooze) and one deep state (CEDE) are available, selecting CEDE when +the predicted idle duration is less than the target residency of CEDE +state can hurt performance. In such cases, the entry/exit overhead of +CEDE outweighs the power savings, leading to unnecessary state +transitions and higher latency. + +Menu governor currently contains a special-case rule that prioritizes +the first non-polling state over polling, even when its target residency +is much longer than the predicted idle duration. On PowerPC/pseries, +where the gap between the polling state (Snooze) and the first non-polling +state (CEDE) is large, this behavior causes performance regressions. + +Refine that special case by adding an extra requirement: the first +non-polling state can only be chosen if its target residency is below +the defined RESIDENCY_THRESHOLD_NS. If this condition is not satisfied, +polling is allowed instead, avoiding suboptimal non-polling state +entries. + +This change is limited to the single special-case rule for the first +non-polling state. The general non-polling state selection logic in the +menu governor remains unchanged. + +Performance improvement observed with pgbench on PowerPC (pseries) +system: ++---------------------------+------------+------------+------------+ +| Metric | Baseline | Patched | Change (%) | ++---------------------------+------------+------------+------------+ +| Transactions/sec (TPS) | 495,210 | 536,982 | +8.45% | +| Avg latency (ms) | 0.163 | 0.150 | -7.98% | ++---------------------------+------------+------------+------------+ + +CPUIdle state usage: ++--------------+--------------+-------------+ +| Metric | Baseline | Patched | ++--------------+--------------+-------------+ +| Total usage | 12,735,820 | 13,918,442 | +| Above usage | 11,401,520 | 1,598,210 | +| Below usage | 20,145 | 702,395 | ++--------------+--------------+-------------+ + +Above/Total and Below/Total usage percentages: ++------------------------+-----------+---------+ +| Metric | Baseline | Patched | ++------------------------+-----------+---------+ +| Above % (Above/Total) | 89.56% | 11.49% | +| Below % (Below/Total) | 0.16% | 5.05% | +| Total cpuidle miss (%) | 89.72% | 16.54% | ++------------------------+-----------+---------+ + +The results indicate that restricting CEDE selection to cases where +its residency matches the predicted idle time reduces mispredictions, +lowers unnecessary state transitions, and improves overall throughput. + +Reviewed-by: Christian Loehle +Signed-off-by: Aboorva Devarajan +[ rjw: Changelog edits, rebase ] +Link: https://patch.msgid.link/20251006013954.17972-1-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/governors/menu.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index 9069c36a491d5..3be761961f1be 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -323,12 +323,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + } + + /* +- * Use a physical idle state, not busy polling, unless a timer +- * is going to trigger soon enough or the exit latency of the +- * idle state in question is greater than the predicted idle +- * duration. ++ * Use a physical idle state instead of busy polling so long as ++ * its target residency is below the residency threshold, its ++ * exit latency is not greater than the predicted idle duration, ++ * and the next timer doesn't expire soon. + */ + if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && ++ s->target_residency_ns < RESIDENCY_THRESHOLD_NS && + s->target_residency_ns <= data->next_timer_ns && + s->exit_latency_ns <= predicted_ns) { + predicted_ns = s->target_residency_ns; +-- +2.51.0 + diff --git a/queue-6.12/fs-ntfs3-check-for-shutdown-in-fsync.patch b/queue-6.12/fs-ntfs3-check-for-shutdown-in-fsync.patch new file mode 100644 index 0000000000..2dab527c6d --- /dev/null +++ b/queue-6.12/fs-ntfs3-check-for-shutdown-in-fsync.patch @@ -0,0 +1,53 @@ +From 449f95652bc5dc920ff715017ff26d3d4a8b9fd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 16:17:19 +0300 +Subject: fs/ntfs3: check for shutdown in fsync + +From: Konstantin Komarov + +[ Upstream commit 1b2ae190ea43bebb8c73d21f076addc8a8c71849 ] + +Ensure fsync() returns -EIO when the ntfs3 filesystem is in forced +shutdown, instead of silently succeeding via generic_file_fsync(). + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 902dc8ba878ef..f1122ac5be622 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -1396,6 +1396,18 @@ static ssize_t ntfs_file_splice_write(struct pipe_inode_info *pipe, + return iter_file_splice_write(pipe, file, ppos, len, flags); + } + ++/* ++ * ntfs_file_fsync - file_operations::fsync ++ */ ++static int ntfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) ++{ ++ struct inode *inode = file_inode(file); ++ if (unlikely(ntfs3_forced_shutdown(inode->i_sb))) ++ return -EIO; ++ ++ return generic_file_fsync(file, start, end, datasync); ++} ++ + // clang-format off + const struct inode_operations ntfs_file_inode_operations = { + .getattr = ntfs_getattr, +@@ -1420,7 +1432,7 @@ const struct file_operations ntfs_file_operations = { + .splice_write = ntfs_file_splice_write, + .mmap = ntfs_file_mmap, + .open = ntfs_file_open, +- .fsync = generic_file_fsync, ++ .fsync = ntfs_file_fsync, + .fallocate = ntfs_fallocate, + .release = ntfs_file_release, + }; +-- +2.51.0 + diff --git a/queue-6.12/fs-ntfs3-support-timestamps-prior-to-epoch.patch b/queue-6.12/fs-ntfs3-support-timestamps-prior-to-epoch.patch new file mode 100644 index 0000000000..c2f6d52181 --- /dev/null +++ b/queue-6.12/fs-ntfs3-support-timestamps-prior-to-epoch.patch @@ -0,0 +1,43 @@ +From 10cc345e650e4b4a67cecb83801dc0d8e4c16bc4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Sep 2025 11:48:48 +0300 +Subject: fs/ntfs3: Support timestamps prior to epoch + +From: Konstantin Komarov + +[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ] + +Before it used an unsigned 64-bit type, which prevented proper handling +of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to +support pre-epoch timestamps. The issue was caught by xfstests. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/ntfs_fs.h | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index ff7f241a25b24..a1040060b081f 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -980,11 +980,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts) + */ + static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) + { +- u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; ++ s32 t32; ++ /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ ++ s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; + +- // WARNING: do_div changes its first argument(!) +- ts->tv_nsec = do_div(t, _100ns2seconds) * 100; +- ts->tv_sec = t; ++ ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); ++ ts->tv_nsec = t32 * 100; + } + + static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb) +-- +2.51.0 + diff --git a/queue-6.12/gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch b/queue-6.12/gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch new file mode 100644 index 0000000000..c218083386 --- /dev/null +++ b/queue-6.12/gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch @@ -0,0 +1,38 @@ +From 14b27fdb4ab6db6476a6390bdc6021813c955316 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 23:27:14 +0000 +Subject: gfs2: Fix "gfs2: Switch to wait_event in gfs2_quotad" + +From: Andreas Gruenbacher + +[ Upstream commit dff1fb6d8b7abe5b1119fa060f5d6b3370bf10ac ] + +Commit e4a8b5481c59a ("gfs2: Switch to wait_event in gfs2_quotad") broke +cyclic statfs syncing, so the numbers reported by "df" could easily get +completely out of sync with reality. Fix this by reverting part of +commit e4a8b5481c59a for now. + +A follow-up commit will clean this code up later. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/quota.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c +index 2e6bc77f4f81c..642584265a6f4 100644 +--- a/fs/gfs2/quota.c ++++ b/fs/gfs2/quota.c +@@ -1617,7 +1617,7 @@ int gfs2_quotad(void *data) + + t = min(quotad_timeo, statfs_timeo); + +- t = wait_event_freezable_timeout(sdp->sd_quota_wait, ++ t -= wait_event_freezable_timeout(sdp->sd_quota_wait, + sdp->sd_statfs_force_sync || + gfs2_withdrawing_or_withdrawn(sdp) || + kthread_should_stop(), +-- +2.51.0 + diff --git a/queue-6.12/gfs2-fix-remote-evict-for-read-only-filesystems.patch b/queue-6.12/gfs2-fix-remote-evict-for-read-only-filesystems.patch new file mode 100644 index 0000000000..b341d17a92 --- /dev/null +++ b/queue-6.12/gfs2-fix-remote-evict-for-read-only-filesystems.patch @@ -0,0 +1,41 @@ +From 7e7ee8b777b4a8f22a2a2736961aaafe9c56768a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 12:14:24 +0000 +Subject: gfs2: fix remote evict for read-only filesystems + +From: Andreas Gruenbacher + +[ Upstream commit 64c10ed9274bc46416f502afea48b4ae11279669 ] + +When a node tries to delete an inode, it first requests exclusive access +to the iopen glock. This triggers demote requests on all remote nodes +currently holding the iopen glock. To satisfy those requests, the +remote nodes evict the inode in question, or they poke the corresponding +inode glock to signal that the inode is still in active use. + +This behavior doesn't depend on whether or not a filesystem is +read-only, so remove the incorrect read-only check. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/glops.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c +index 1ed42f0e6ec7b..d13a050bcb9dc 100644 +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -631,8 +631,7 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote) + struct gfs2_inode *ip = gl->gl_object; + struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; + +- if (!remote || sb_rdonly(sdp->sd_vfs) || +- test_bit(SDF_KILL, &sdp->sd_flags)) ++ if (!remote || test_bit(SDF_KILL, &sdp->sd_flags)) + return; + + if (gl->gl_demote_state == LM_ST_UNLOCKED && +-- +2.51.0 + diff --git a/queue-6.12/gfs2-fix-use-of-bio_chain.patch b/queue-6.12/gfs2-fix-use-of-bio_chain.patch new file mode 100644 index 0000000000..be3a43a9c9 --- /dev/null +++ b/queue-6.12/gfs2-fix-use-of-bio_chain.patch @@ -0,0 +1,37 @@ +From 3f6c5ed1babd5cfa5258f20a96863f5043088a61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 21:19:52 +0000 +Subject: gfs2: Fix use of bio_chain + +From: Andreas Gruenbacher + +[ Upstream commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941 ] + +In gfs2_chain_bio(), the call to bio_chain() has its arguments swapped. +The result is leaked bios and incorrect synchronization (only the last +bio will actually be waited for). This code is only used during mount +and filesystem thaw, so the bug normally won't be noticeable. + +Reported-by: Stephen Zhang +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/lops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c +index 314ec2a70167f..2e92b606d19e0 100644 +--- a/fs/gfs2/lops.c ++++ b/fs/gfs2/lops.c +@@ -485,7 +485,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) + new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); + bio_clone_blkg_association(new, prev); + new->bi_iter.bi_sector = bio_end_sector(prev); +- bio_chain(new, prev); ++ bio_chain(prev, new); + submit_bio(prev); + return new; + } +-- +2.51.0 + diff --git a/queue-6.12/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch b/queue-6.12/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch new file mode 100644 index 0000000000..94163e481f --- /dev/null +++ b/queue-6.12/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch @@ -0,0 +1,91 @@ +From 3d7b02fbc543254f9fd5cc954f4e63285972fa3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 17:39:12 +0800 +Subject: hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create + +From: Yang Chenzhi + +[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ] + +When sync() and link() are called concurrently, both threads may +enter hfs_bnode_find() without finding the node in the hash table +and proceed to create it. + +Thread A: + hfsplus_write_inode() + -> hfsplus_write_system_inode() + -> hfs_btree_write() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +Thread B: + hfsplus_create_cat() + -> hfs_brec_insert() + -> hfs_bnode_split() + -> hfs_bmap_alloc() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +In this case, thread A creates the bnode, sets refcnt=1, and hashes it. +Thread B also tries to create the same bnode, notices it has already +been inserted, drops its own instance, and uses the hashed one without +getting the node. + +``` + + node2 = hfs_bnode_findhash(tree, cnid); + if (!node2) { <- Thread A + hash = hfs_bnode_hash(cnid); + node->next_hash = tree->node_hash[hash]; + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { <- Thread B + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, + !test_bit(HFS_BNODE_NEW, &node2->flags)); + return node2; + } +``` + +However, hfs_bnode_find() requires each call to take a reference. +Here both threads end up setting refcnt=1. When they later put the node, +this triggers: + +BUG_ON(!atomic_read(&node->refcnt)) + +In this scenario, Thread B in fact finds the node in the hash table +rather than creating a new one, and thus must take a reference. + +Fix this by calling hfs_bnode_get() when reusing a bnode newly created by +another thread to ensure the refcount is updated correctly. + +A similar bug was fixed in HFS long ago in commit +a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") +but the same issue remained in HFS+ until now. + +Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com +Signed-off-by: Yang Chenzhi +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index aa095e6fb20e8..c0089849be50e 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -481,6 +481,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { ++ hfs_bnode_get(node2); + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, +-- +2.51.0 + diff --git a/queue-6.12/hfsplus-fix-volume-corruption-issue-for-generic-070.patch b/queue-6.12/hfsplus-fix-volume-corruption-issue-for-generic-070.patch new file mode 100644 index 0000000000..bca91054c7 --- /dev/null +++ b/queue-6.12/hfsplus-fix-volume-corruption-issue-for-generic-070.patch @@ -0,0 +1,122 @@ +From a596ad3b4d8c681d0d176df60b103638a25d000d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:12:30 -0700 +Subject: hfsplus: fix volume corruption issue for generic/070 + +From: Viacheslav Dubeyko + +[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ] + +The xfstests' test-case generic/070 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent +(see xfstests-dev/results//generic/070.full for details) + +Ran: generic/070 +Failures: generic/070 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop50 +** /dev/loop50 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +Unused node is not erased (node = 1) +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 +CBTStat = 0x0000 CatStat = 0x00000000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume test was repaired successfully. + +It is possible to see that fsck.hfsplus detected not +erased and unused node for the case of extents overflow file. +The HFS+ logic has special method that defines if the node +should be erased: + +bool hfs_bnode_need_zeroout(struct hfs_btree *tree) +{ + struct super_block *sb = tree->inode->i_sb; + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + + return tree->cnid == HFSPLUS_CAT_CNID && + volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; +} + +However, it is possible to see that this method works +only for the case of catalog file. But debugging of the issue +has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been +requested for the extents overflow file too: + +catalog file +kernel: hfsplus: node 4, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800 + +extents overflow file +kernel: hfsplus: node 1, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800 + +This patch modifies the hfs_bnode_need_zeroout() by checking +only volume_attr but not the b-tree ID because node zeroing +can be requested for all HFS+ b-tree types. + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 33s ... 34s +Ran: generic/070 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index 407d5152eb411..aa095e6fb20e8 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -704,6 +704,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + +- return tree->cnid == HFSPLUS_CAT_CNID && +- volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; ++ return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + } +-- +2.51.0 + diff --git a/queue-6.12/hfsplus-fix-volume-corruption-issue-for-generic-073.patch b/queue-6.12/hfsplus-fix-volume-corruption-issue-for-generic-073.patch new file mode 100644 index 0000000000..4310cef012 --- /dev/null +++ b/queue-6.12/hfsplus-fix-volume-corruption-issue-for-generic-073.patch @@ -0,0 +1,125 @@ +From 3b23b86ad153c12694148b57cfff44556bda0a58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:25:23 -0800 +Subject: hfsplus: fix volume corruption issue for generic/073 + +From: Viacheslav Dubeyko + +[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ] + +The xfstests' test-case generic/073 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent +(see XFSTESTS-2/xfstests-dev/results//generic/073.full for details) + +Ran: generic/073 +Failures: generic/073 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +Invalid directory item count +(It should be 1 instead of 0) +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 +CBTStat = 0x0000 CatStat = 0x00004000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled was repaired successfully. + +The test is doing these steps on final phase: + +mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo + +So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ +logic decrements the number of entries in testdir_1 and increments number of +entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not +for testdir_2. As a result, this is the reason why fsck.hfsplus detects the +volume corruption afterwards. + +This patch fixes the issue by means of adding the +hfsplus_cat_write_inode() call for old_dir and new_dir in +hfsplus_rename() after the successful ending of +hfsplus_rename_cat(). This method makes modification of in-core +inode objects for old_dir and new_dir but it doesn't save these +modifications in Catalog File's entries. It was expected that +hfsplus_write_inode() will save these modifications afterwards. +However, because generic/073 does fsync only for testdir_1 and foo +then testdir_2 modification hasn't beed saved into Catalog File's +entry and it was flushed without this modification. And it was +detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog +File all modified entries and correct state of Catalog File will +be flushed during hfsplus_file_fsync() call. Finally, it makes +fsck.hfsplus happy. + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 32s ... 32s +Ran: generic/073 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/dir.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c +index f5c4b3e31a1c2..33154c720a4e9 100644 +--- a/fs/hfsplus/dir.c ++++ b/fs/hfsplus/dir.c +@@ -552,8 +552,13 @@ static int hfsplus_rename(struct mnt_idmap *idmap, + res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, + old_dir, &old_dentry->d_name, + new_dir, &new_dentry->d_name); +- if (!res) ++ if (!res) { + new_dentry->d_fsdata = old_dentry->d_fsdata; ++ ++ res = hfsplus_cat_write_inode(old_dir); ++ if (!res) ++ res = hfsplus_cat_write_inode(new_dir); ++ } + return res; + } + +-- +2.51.0 + diff --git a/queue-6.12/hfsplus-verify-inode-mode-when-loading-from-disk.patch b/queue-6.12/hfsplus-verify-inode-mode-when-loading-from-disk.patch new file mode 100644 index 0000000000..a478a00966 --- /dev/null +++ b/queue-6.12/hfsplus-verify-inode-mode-when-loading-from-disk.patch @@ -0,0 +1,105 @@ +From 1b1114ab15039d05d1587a08d53adaea0cad2d35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 18:18:54 +0900 +Subject: hfsplus: Verify inode mode when loading from disk + +From: Tetsuo Handa + +[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ] + +syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when +the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted. + +According to [1], the permissions field was treated as reserved in Mac OS +8 and 9. According to [2], the reserved field was explicitly initialized +with 0, and that field must remain 0 as long as reserved. Therefore, when +the "mode" field is not 0 (i.e. no longer reserved), the file must be +S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ +S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlusPermissions [1] +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#ReservedAndPadFields [2] +Signed-off-by: Tetsuo Handa +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA.ne.jp +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index c85b5802ec0f9..2d68c52f894f9 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -178,13 +178,29 @@ const struct dentry_operations hfsplus_dentry_operations = { + .d_compare = hfsplus_compare_dentry, + }; + +-static void hfsplus_get_perms(struct inode *inode, +- struct hfsplus_perm *perms, int dir) ++static int hfsplus_get_perms(struct inode *inode, ++ struct hfsplus_perm *perms, int dir) + { + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + u16 mode; + + mode = be16_to_cpu(perms->mode); ++ if (dir) { ++ if (mode && !S_ISDIR(mode)) ++ goto bad_type; ++ } else if (mode) { ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ case S_IFLNK: ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: ++ break; ++ default: ++ goto bad_type; ++ } ++ } + + i_uid_write(inode, be32_to_cpu(perms->owner)); + if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) +@@ -210,6 +226,10 @@ static void hfsplus_get_perms(struct inode *inode, + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; ++ return 0; ++bad_type: ++ pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); ++ return -EIO; + } + + static int hfsplus_file_open(struct inode *inode, struct file *file) +@@ -514,7 +534,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); +- hfsplus_get_perms(inode, &folder->permissions, 1); ++ res = hfsplus_get_perms(inode, &folder->permissions, 1); ++ if (res) ++ goto out; + set_nlink(inode, 1); + inode->i_size = 2 + be32_to_cpu(folder->valence); + inode_set_atime_to_ts(inode, hfsp_mt2ut(folder->access_date)); +@@ -543,7 +565,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + + hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? + &file->rsrc_fork : &file->data_fork); +- hfsplus_get_perms(inode, &file->permissions, 0); ++ res = hfsplus_get_perms(inode, &file->permissions, 0); ++ if (res) ++ goto out; + set_nlink(inode, 1); + if (S_ISREG(inode->i_mode)) { + if (file->permissions.dev) +-- +2.51.0 + diff --git a/queue-6.12/iomap-account-for-unaligned-end-offsets-when-truncat.patch b/queue-6.12/iomap-account-for-unaligned-end-offsets-when-truncat.patch new file mode 100644 index 0000000000..47814c399e --- /dev/null +++ b/queue-6.12/iomap-account-for-unaligned-end-offsets-when-truncat.patch @@ -0,0 +1,74 @@ +From 2912ca0855a4a0957f9af2c2a503d1321b875476 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 11:36:51 -0800 +Subject: iomap: account for unaligned end offsets when truncating read range + +From: Joanne Koong + +[ Upstream commit 9d875e0eef8ec15b6b1da0cb9a0f8ed13efee89e ] + +The end position to start truncating from may be at an offset into a +block, which under the current logic would result in overtruncation. + +Adjust the calculation to account for unaligned end offsets. + +Signed-off-by: Joanne Koong +Link: https://patch.msgid.link/20251111193658.3495942-3-joannelkoong@gmail.com +Reviewed-by: Christoph Hellwig +Reviewed-by: Darrick J. Wong +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 258ac7bf658fd..397c96c25c31f 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -227,6 +227,22 @@ static void ifs_free(struct folio *folio) + kfree(ifs); + } + ++/* ++ * Calculate how many bytes to truncate based off the number of blocks to ++ * truncate and the end position to start truncating from. ++ */ ++static size_t iomap_bytes_to_truncate(loff_t end_pos, unsigned block_bits, ++ unsigned blocks_truncated) ++{ ++ unsigned block_size = 1 << block_bits; ++ unsigned block_offset = end_pos & (block_size - 1); ++ ++ if (!block_offset) ++ return blocks_truncated << block_bits; ++ ++ return ((blocks_truncated - 1) << block_bits) + block_offset; ++} ++ + /* + * Calculate the range inside the folio that we actually need to read. + */ +@@ -272,7 +288,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + /* truncate len if we find any trailing uptodate block(s) */ + while (++i <= last) { + if (ifs_block_is_uptodate(ifs, i)) { +- plen -= (last - i + 1) * block_size; ++ plen -= iomap_bytes_to_truncate(*pos + plen, ++ block_bits, last - i + 1); + last = i - 1; + break; + } +@@ -288,7 +305,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + unsigned end = offset_in_folio(folio, isize - 1) >> block_bits; + + if (first <= end && last > end) +- plen -= (last - end) * block_size; ++ plen -= iomap_bytes_to_truncate(*pos + plen, block_bits, ++ last - end); + } + + *offp = poff; +-- +2.51.0 + diff --git a/queue-6.12/iomap-adjust-read-range-correctly-for-non-block-alig.patch b/queue-6.12/iomap-adjust-read-range-correctly-for-non-block-alig.patch new file mode 100644 index 0000000000..2951d94487 --- /dev/null +++ b/queue-6.12/iomap-adjust-read-range-correctly-for-non-block-alig.patch @@ -0,0 +1,67 @@ +From afee34a015fe14693d7b7c072253b3a0b6e2cb4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 11:00:42 -0700 +Subject: iomap: adjust read range correctly for non-block-aligned positions + +From: Joanne Koong + +[ Upstream commit 7aa6bc3e8766990824f66ca76c19596ce10daf3e ] + +iomap_adjust_read_range() assumes that the position and length passed in +are block-aligned. This is not always the case however, as shown in the +syzbot generated case for erofs. This causes too many bytes to be +skipped for uptodate blocks, which results in returning the incorrect +position and length to read in. If all the blocks are uptodate, this +underflows length and returns a position beyond the folio. + +Fix the calculation to also take into account the block offset when +calculating how many bytes can be skipped for uptodate blocks. + +Signed-off-by: Joanne Koong +Tested-by: syzbot@syzkaller.appspotmail.com +Reviewed-by: Brian Foster +Reviewed-by: Christoph Hellwig +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index d4b990938399c..258ac7bf658fd 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -250,17 +250,24 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + * to avoid reading in already uptodate ranges. + */ + if (ifs) { +- unsigned int i; ++ unsigned int i, blocks_skipped; + + /* move forward for each leading block marked uptodate */ +- for (i = first; i <= last; i++) { ++ for (i = first; i <= last; i++) + if (!ifs_block_is_uptodate(ifs, i)) + break; +- *pos += block_size; +- poff += block_size; +- plen -= block_size; +- first++; ++ ++ blocks_skipped = i - first; ++ if (blocks_skipped) { ++ unsigned long block_offset = *pos & (block_size - 1); ++ unsigned bytes_skipped = ++ (blocks_skipped << block_bits) - block_offset; ++ ++ *pos += bytes_skipped; ++ poff += bytes_skipped; ++ plen -= bytes_skipped; + } ++ first = i; + + /* truncate len if we find any trailing uptodate block(s) */ + while (++i <= last) { +-- +2.51.0 + diff --git a/queue-6.12/kbuild-use-objtree-for-module-signing-key-path.patch b/queue-6.12/kbuild-use-objtree-for-module-signing-key-path.patch new file mode 100644 index 0000000000..bc3721e764 --- /dev/null +++ b/queue-6.12/kbuild-use-objtree-for-module-signing-key-path.patch @@ -0,0 +1,58 @@ +From 1125bfde9df8df3ac62d86584984417c40b08494 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 16:34:52 +0000 +Subject: kbuild: Use objtree for module signing key path + +From: Mikhail Malyshev + +[ Upstream commit af61da281f52aba0c5b090bafb3a31c5739850ff ] + +When building out-of-tree modules with CONFIG_MODULE_SIG_FORCE=y, +module signing fails because the private key path uses $(srctree) +while the public key path uses $(objtree). Since signing keys are +generated in the build directory during kernel compilation, both +paths should use $(objtree) for consistency. + +This causes SSL errors like: + SSL error:02001002:system library:fopen:No such file or directory + sign-file: /kernel-src/certs/signing_key.pem + +The issue occurs because: +- sig-key uses: $(srctree)/certs/signing_key.pem (source tree) +- cmd_sign uses: $(objtree)/certs/signing_key.x509 (build tree) + +But both keys are generated in $(objtree) during the build. + +This complements commit 25ff08aa43e37 ("kbuild: Fix signing issue for +external modules") which fixed the scripts path and public key path, +but missed the private key path inconsistency. + +Fixes out-of-tree module signing for configurations with separate +source and build directories (e.g., O=/kernel-out). + +Signed-off-by: Mikhail Malyshev +Reviewed-by: Nathan Chancellor +Tested-by: Nicolas Schier +Link: https://patch.msgid.link/20251015163452.3754286-1-mike.malyshev@gmail.com +Signed-off-by: Nicolas Schier +Signed-off-by: Sasha Levin +--- + scripts/Makefile.modinst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst +index d977209431898..5dd52788a042a 100644 +--- a/scripts/Makefile.modinst ++++ b/scripts/Makefile.modinst +@@ -100,7 +100,7 @@ endif + # Don't stop modules_install even if we can't sign external modules. + # + ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) +-sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) ++sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) + else + sig-key := $(CONFIG_MODULE_SIG_KEY) + endif +-- +2.51.0 + diff --git a/queue-6.12/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch b/queue-6.12/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch new file mode 100644 index 0000000000..6919a15950 --- /dev/null +++ b/queue-6.12/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch @@ -0,0 +1,106 @@ +From cbccc9b3724bab6a70687035af65e45343d9e7cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 09:05:46 +0900 +Subject: ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency + +From: Namjae Jeon + +[ Upstream commit b39a1833cc4a2755b02603eec3a71a85e9dff926 ] + +Under high concurrency, A tree-connection object (tcon) is freed on +a disconnect path while another path still holds a reference and later +executes *_put()/write on it. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/mgmt/tree_connect.c | 18 ++++-------------- + fs/smb/server/mgmt/tree_connect.h | 1 - + fs/smb/server/smb2pdu.c | 3 --- + 3 files changed, 4 insertions(+), 18 deletions(-) + +diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c +index ecfc575086712..d3483d9c757c7 100644 +--- a/fs/smb/server/mgmt/tree_connect.c ++++ b/fs/smb/server/mgmt/tree_connect.c +@@ -78,7 +78,6 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + tree_conn->t_state = TREE_NEW; + status.tree_conn = tree_conn; + atomic_set(&tree_conn->refcount, 1); +- init_waitqueue_head(&tree_conn->refcount_q); + + ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, + KSMBD_DEFAULT_GFP)); +@@ -100,14 +99,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + + void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) + { +- /* +- * Checking waitqueue to releasing tree connect on +- * tree disconnect. waitqueue_active is safe because it +- * uses atomic operation for condition. +- */ +- if (!atomic_dec_return(&tcon->refcount) && +- waitqueue_active(&tcon->refcount_q)) +- wake_up(&tcon->refcount_q); ++ if (atomic_dec_and_test(&tcon->refcount)) ++ kfree(tcon); + } + + int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, +@@ -119,14 +112,11 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, + xa_erase(&sess->tree_conns, tree_conn->id); + write_unlock(&sess->tree_conns_lock); + +- if (!atomic_dec_and_test(&tree_conn->refcount)) +- wait_event(tree_conn->refcount_q, +- atomic_read(&tree_conn->refcount) == 0); +- + ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); + ksmbd_release_tree_conn_id(sess, tree_conn->id); + ksmbd_share_config_put(tree_conn->share_conf); +- kfree(tree_conn); ++ if (atomic_dec_and_test(&tree_conn->refcount)) ++ kfree(tree_conn); + return ret; + } + +diff --git a/fs/smb/server/mgmt/tree_connect.h b/fs/smb/server/mgmt/tree_connect.h +index a42cdd0510411..f0023d86716f2 100644 +--- a/fs/smb/server/mgmt/tree_connect.h ++++ b/fs/smb/server/mgmt/tree_connect.h +@@ -33,7 +33,6 @@ struct ksmbd_tree_connect { + int maximal_access; + bool posix_extensions; + atomic_t refcount; +- wait_queue_head_t refcount_q; + unsigned int t_state; + }; + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index d9e28191c267e..b32df37da70d4 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -2190,7 +2190,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); + tcon->t_state = TREE_DISCONNECTED; + write_unlock(&sess->tree_conns_lock); + +@@ -2200,8 +2199,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- work->tcon = NULL; +- + rsp->StructureSize = cpu_to_le16(4); + err = ksmbd_iov_pin_rsp(work, rsp, + sizeof(struct smb2_tree_disconnect_rsp)); +-- +2.51.0 + diff --git a/queue-6.12/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch b/queue-6.12/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch new file mode 100644 index 0000000000..19dbf68b0c --- /dev/null +++ b/queue-6.12/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch @@ -0,0 +1,190 @@ +From 0e07f5f7c72a40ff874a02c8f9a97b97144d9165 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:05:09 +0900 +Subject: ksmbd: vfs: fix race on m_flags in vfs_cache + +From: Qianchang Zhao + +[ Upstream commit 991f8a79db99b14c48d20d2052c82d65b9186cad ] + +ksmbd maintains delete-on-close and pending-delete state in +ksmbd_inode->m_flags. In vfs_cache.c this field is accessed under +inconsistent locking: some paths read and modify m_flags under +ci->m_lock while others do so without taking the lock at all. + +Examples: + + - ksmbd_query_inode_status() and __ksmbd_inode_close() use + ci->m_lock when checking or updating m_flags. + - ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), + ksmbd_clear_inode_pending_delete() and ksmbd_fd_set_delete_on_close() + used to read and modify m_flags without ci->m_lock. + +This creates a potential data race on m_flags when multiple threads +open, close and delete the same file concurrently. In the worst case +delete-on-close and pending-delete bits can be lost or observed in an +inconsistent state, leading to confusing delete semantics (files that +stay on disk after delete-on-close, or files that disappear while still +in use). + +Fix it by: + + - Making ksmbd_query_inode_status() look at m_flags under ci->m_lock + after dropping inode_hash_lock. + - Adding ci->m_lock protection to all helpers that read or modify + m_flags (ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), + ksmbd_clear_inode_pending_delete(), ksmbd_fd_set_delete_on_close()). + - Keeping the existing ci->m_lock protection in __ksmbd_inode_close(), + and moving the actual unlink/xattr removal outside the lock. + +This unifies the locking around m_flags and removes the data race while +preserving the existing delete-on-close behaviour. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Qianchang Zhao +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/vfs_cache.c | 88 +++++++++++++++++++++++++++------------ + 1 file changed, 62 insertions(+), 26 deletions(-) + +diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c +index dfed6fce89049..6ef116585af64 100644 +--- a/fs/smb/server/vfs_cache.c ++++ b/fs/smb/server/vfs_cache.c +@@ -112,40 +112,62 @@ int ksmbd_query_inode_status(struct dentry *dentry) + + read_lock(&inode_hash_lock); + ci = __ksmbd_inode_lookup(dentry); +- if (ci) { +- ret = KSMBD_INODE_STATUS_OK; +- if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) +- ret = KSMBD_INODE_STATUS_PENDING_DELETE; +- atomic_dec(&ci->m_count); +- } + read_unlock(&inode_hash_lock); ++ if (!ci) ++ return ret; ++ ++ down_read(&ci->m_lock); ++ if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) ++ ret = KSMBD_INODE_STATUS_PENDING_DELETE; ++ else ++ ret = KSMBD_INODE_STATUS_OK; ++ up_read(&ci->m_lock); ++ ++ atomic_dec(&ci->m_count); + return ret; + } + + bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) + { +- return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); ++ struct ksmbd_inode *ci = fp->f_ci; ++ int ret; ++ ++ down_read(&ci->m_lock); ++ ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); ++ up_read(&ci->m_lock); ++ ++ return ret; + } + + void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) + { +- fp->f_ci->m_flags |= S_DEL_PENDING; ++ struct ksmbd_inode *ci = fp->f_ci; ++ ++ down_write(&ci->m_lock); ++ ci->m_flags |= S_DEL_PENDING; ++ up_write(&ci->m_lock); + } + + void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp) + { +- fp->f_ci->m_flags &= ~S_DEL_PENDING; ++ struct ksmbd_inode *ci = fp->f_ci; ++ ++ down_write(&ci->m_lock); ++ ci->m_flags &= ~S_DEL_PENDING; ++ up_write(&ci->m_lock); + } + + void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, + int file_info) + { +- if (ksmbd_stream_fd(fp)) { +- fp->f_ci->m_flags |= S_DEL_ON_CLS_STREAM; +- return; +- } ++ struct ksmbd_inode *ci = fp->f_ci; + +- fp->f_ci->m_flags |= S_DEL_ON_CLS; ++ down_write(&ci->m_lock); ++ if (ksmbd_stream_fd(fp)) ++ ci->m_flags |= S_DEL_ON_CLS_STREAM; ++ else ++ ci->m_flags |= S_DEL_ON_CLS; ++ up_write(&ci->m_lock); + } + + static void ksmbd_inode_hash(struct ksmbd_inode *ci) +@@ -257,27 +279,41 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) + struct file *filp; + + filp = fp->filp; +- if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { +- ci->m_flags &= ~S_DEL_ON_CLS_STREAM; +- err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), +- &filp->f_path, +- fp->stream.name, +- true); +- if (err) +- pr_err("remove xattr failed : %s\n", +- fp->stream.name); ++ ++ if (ksmbd_stream_fd(fp)) { ++ bool remove_stream_xattr = false; ++ ++ down_write(&ci->m_lock); ++ if (ci->m_flags & S_DEL_ON_CLS_STREAM) { ++ ci->m_flags &= ~S_DEL_ON_CLS_STREAM; ++ remove_stream_xattr = true; ++ } ++ up_write(&ci->m_lock); ++ ++ if (remove_stream_xattr) { ++ err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), ++ &filp->f_path, ++ fp->stream.name, ++ true); ++ if (err) ++ pr_err("remove xattr failed : %s\n", ++ fp->stream.name); ++ } + } + + if (atomic_dec_and_test(&ci->m_count)) { ++ bool do_unlink = false; ++ + down_write(&ci->m_lock); + if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { + ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); +- up_write(&ci->m_lock); +- ksmbd_vfs_unlink(filp); +- down_write(&ci->m_lock); ++ do_unlink = true; + } + up_write(&ci->m_lock); + ++ if (do_unlink) ++ ksmbd_vfs_unlink(filp); ++ + ksmbd_inode_free(ci); + } + } +-- +2.51.0 + diff --git a/queue-6.12/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch b/queue-6.12/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch new file mode 100644 index 0000000000..9b0bc6a69e --- /dev/null +++ b/queue-6.12/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch @@ -0,0 +1,88 @@ +From cf9feb9a7c44fc97e1e3d1d6bcec84bbbfc31c51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 10:30:19 -0700 +Subject: livepatch: Match old_sympos 0 and 1 in klp_find_func() + +From: Song Liu + +[ Upstream commit 139560e8b973402140cafeb68c656c1374bd4c20 ] + +When there is only one function of the same name, old_sympos of 0 and 1 +are logically identical. Match them in klp_find_func(). + +This is to avoid a corner case with different toolchain behavior. + +In this specific issue, two versions of kpatch-build were used to +build livepatch for the same kernel. One assigns old_sympos == 0 for +unique local functions, the other assigns old_sympos == 1 for unique +local functions. Both versions work fine by themselves. (PS: This +behavior change was introduced in a downstream version of kpatch-build. +This change does not exist in upstream kpatch-build.) + +However, during livepatch upgrade (with the replace flag set) from a +patch built with one version of kpatch-build to the same fix built with +the other version of kpatch-build, livepatching fails with errors like: + +[ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' +... +[ 14.219466] Call Trace: +[ 14.219468] +[ 14.219469] dump_stack_lvl+0x47/0x60 +[ 14.219474] sysfs_warn_dup.cold+0x17/0x27 +[ 14.219476] sysfs_create_dir_ns+0x95/0xb0 +[ 14.219479] kobject_add_internal+0x9e/0x260 +[ 14.219483] kobject_add+0x68/0x80 +[ 14.219485] ? kstrdup+0x3c/0xa0 +[ 14.219486] klp_enable_patch+0x320/0x830 +[ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] +[ 14.219491] ? 0xffffffffa05eb000 +[ 14.219492] do_one_initcall+0x2e/0x190 +[ 14.219494] do_init_module+0x67/0x270 +[ 14.219496] init_module_from_file+0x75/0xa0 +[ 14.219499] idempotent_init_module+0x15a/0x240 +[ 14.219501] __x64_sys_finit_module+0x61/0xc0 +[ 14.219503] do_syscall_64+0x5b/0x160 +[ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 +[ 14.219507] RIP: 0033:0x7f545a4bd96d +... +[ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with + -EEXIST, don't try to register things with the same name ... + +This happens because klp_find_func() thinks somefunc with old_sympos==0 +is not the same as somefunc with old_sympos==1, and klp_add_object_nops +adds another xxx/func,1 to the list of functions to patch. + +Signed-off-by: Song Liu +Acked-by: Josh Poimboeuf +[pmladek@suse.com: Fixed some typos.] +Reviewed-by: Petr Mladek +Tested-by: Petr Mladek +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + kernel/livepatch/core.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c +index 3c21c31796db0..077e078032e05 100644 +--- a/kernel/livepatch/core.c ++++ b/kernel/livepatch/core.c +@@ -90,8 +90,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj, + struct klp_func *func; + + klp_for_each_func(obj, func) { ++ /* ++ * Besides identical old_sympos, also consider old_sympos ++ * of 0 and 1 are identical. ++ */ + if ((strcmp(old_func->old_name, func->old_name) == 0) && +- (old_func->old_sympos == func->old_sympos)) { ++ ((old_func->old_sympos == func->old_sympos) || ++ (old_func->old_sympos == 0 && func->old_sympos == 1) || ++ (old_func->old_sympos == 1 && func->old_sympos == 0))) { + return func; + } + } +-- +2.51.0 + diff --git a/queue-6.12/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch b/queue-6.12/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch new file mode 100644 index 0000000000..10dfa1573f --- /dev/null +++ b/queue-6.12/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch @@ -0,0 +1,60 @@ +From 2e884c3fed683d62957a0e8f267279ad1f324ef9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:38:50 -0300 +Subject: ntfs: set dummy blocksize to read boot_block when mounting + +From: Pedro Demarchi Gomes + +[ Upstream commit d1693a7d5a38acf6424235a6070bcf5b186a360d ] + +When mounting, sb->s_blocksize is used to read the boot_block without +being defined or validated. Set a dummy blocksize before attempting to +read the boot_block. + +The issue can be triggered with the following syz reproducer: + + mkdirat(0xffffffffffffff9c, &(0x7f0000000080)='./file1\x00', 0x0) + r4 = openat$nullb(0xffffffffffffff9c, &(0x7f0000000040), 0x121403, 0x0) + ioctl$FS_IOC_SETFLAGS(r4, 0x40081271, &(0x7f0000000980)=0x4000) + mount(&(0x7f0000000140)=@nullb, &(0x7f0000000040)='./cgroup\x00', + &(0x7f0000000000)='ntfs3\x00', 0x2208004, 0x0) + syz_clone(0x88200200, 0x0, 0x0, 0x0, 0x0, 0x0) + +Here, the ioctl sets the bdev block size to 16384. During mount, +get_tree_bdev_flags() calls sb_set_blocksize(sb, block_size(bdev)), +but since block_size(bdev) > PAGE_SIZE, sb_set_blocksize() leaves +sb->s_blocksize at zero. + +Later, ntfs_init_from_boot() attempts to read the boot_block while +sb->s_blocksize is still zero, which triggers the bug. + +Reported-by: syzbot+f4f84b57a01d6b8364ad@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=f4f84b57a01d6b8364ad +Signed-off-by: Pedro Demarchi Gomes +[almaz.alexandrovich@paragon-software.com: changed comment style, added +return value handling] +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/super.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index 6a0f6b0a3ab2a..89d126c155c7d 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -892,6 +892,11 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size, + + sbi->volume.blocks = dev_size >> PAGE_SHIFT; + ++ /* Set dummy blocksize to read boot_block. */ ++ if (!sb_min_blocksize(sb, PAGE_SIZE)) { ++ return -EINVAL; ++ } ++ + read_boot: + bh = ntfs_bread(sb, boot_block); + if (!bh) +-- +2.51.0 + diff --git a/queue-6.12/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch b/queue-6.12/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch new file mode 100644 index 0000000000..2346cc7b72 --- /dev/null +++ b/queue-6.12/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch @@ -0,0 +1,83 @@ +From 3266755668f1c062e68e704ef28e7880aa84de21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 08:00:53 -0500 +Subject: perf/x86/amd: Check event before enable to avoid GPF + +From: George Kennedy + +[ Upstream commit 866cf36bfee4fba6a492d2dcc5133f857e3446b0 ] + +On AMD machines cpuc->events[idx] can become NULL in a subtle race +condition with NMI->throttle->x86_pmu_stop(). + +Check event for NULL in amd_pmu_enable_all() before enable to avoid a GPF. +This appears to be an AMD only issue. + +Syzkaller reported a GPF in amd_pmu_enable_all. + +INFO: NMI handler (perf_event_nmi_handler) took too long to run: 13.143 + msecs +Oops: general protection fault, probably for non-canonical address + 0xdffffc0000000034: 0000 PREEMPT SMP KASAN NOPTI +KASAN: null-ptr-deref in range [0x00000000000001a0-0x00000000000001a7] +CPU: 0 UID: 0 PID: 328415 Comm: repro_36674776 Not tainted 6.12.0-rc1-syzk +RIP: 0010:x86_pmu_enable_event (arch/x86/events/perf_event.h:1195 + arch/x86/events/core.c:1430) +RSP: 0018:ffff888118009d60 EFLAGS: 00010012 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: 0000000000000034 RSI: 0000000000000000 RDI: 00000000000001a0 +RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002 +R13: ffff88811802a440 R14: ffff88811802a240 R15: ffff8881132d8601 +FS: 00007f097dfaa700(0000) GS:ffff888118000000(0000) GS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000200001c0 CR3: 0000000103d56000 CR4: 00000000000006f0 +Call Trace: + +amd_pmu_enable_all (arch/x86/events/amd/core.c:760 (discriminator 2)) +x86_pmu_enable (arch/x86/events/core.c:1360) +event_sched_out (kernel/events/core.c:1191 kernel/events/core.c:1186 + kernel/events/core.c:2346) +__perf_remove_from_context (kernel/events/core.c:2435) +event_function (kernel/events/core.c:259) +remote_function (kernel/events/core.c:92 (discriminator 1) + kernel/events/core.c:72 (discriminator 1)) +__flush_smp_call_function_queue (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 ./include/trace/events/csd.h:64 + kernel/smp.c:135 kernel/smp.c:540) +__sysvec_call_function_single (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 + ./arch/x86/include/asm/trace/irq_vectors.h:99 arch/x86/kernel/smp.c:272) +sysvec_call_function_single (arch/x86/kernel/smp.c:266 (discriminator 47) + arch/x86/kernel/smp.c:266 (discriminator 47)) + + +Reported-by: syzkaller +Signed-off-by: George Kennedy +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + arch/x86/events/amd/core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c +index b4a1a2576510e..36d28edf7a535 100644 +--- a/arch/x86/events/amd/core.c ++++ b/arch/x86/events/amd/core.c +@@ -762,7 +762,12 @@ static void amd_pmu_enable_all(int added) + if (!test_bit(idx, cpuc->active_mask)) + continue; + +- amd_pmu_enable_event(cpuc->events[idx]); ++ /* ++ * FIXME: cpuc->events[idx] can become NULL in a subtle race ++ * condition with NMI->throttle->x86_pmu_stop(). ++ */ ++ if (cpuc->events[idx]) ++ amd_pmu_enable_event(cpuc->events[idx]); + } + } + +-- +2.51.0 + diff --git a/queue-6.12/sched-deadline-only-set-free_cpus-for-online-runqueu.patch b/queue-6.12/sched-deadline-only-set-free_cpus-for-online-runqueu.patch new file mode 100644 index 0000000000..ac832f6471 --- /dev/null +++ b/queue-6.12/sched-deadline-only-set-free_cpus-for-online-runqueu.patch @@ -0,0 +1,189 @@ +From fcbd8d36f25d7a06a8638818fbfddf5ecbc3cd95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 18:22:36 -0700 +Subject: sched/deadline: only set free_cpus for online runqueues + +From: Doug Berger + +[ Upstream commit 382748c05e58a9f1935f5a653c352422375566ea ] + +Commit 16b269436b72 ("sched/deadline: Modify cpudl::free_cpus +to reflect rd->online") introduced the cpudl_set/clear_freecpu +functions to allow the cpu_dl::free_cpus mask to be manipulated +by the deadline scheduler class rq_on/offline callbacks so the +mask would also reflect this state. + +Commit 9659e1eeee28 ("sched/deadline: Remove cpu_active_mask +from cpudl_find()") removed the check of the cpu_active_mask to +save some processing on the premise that the cpudl::free_cpus +mask already reflected the runqueue online state. + +Unfortunately, there are cases where it is possible for the +cpudl_clear function to set the free_cpus bit for a CPU when the +deadline runqueue is offline. When this occurs while a CPU is +connected to the default root domain the flag may retain the bad +state after the CPU has been unplugged. Later, a different CPU +that is transitioning through the default root domain may push a +deadline task to the powered down CPU when cpudl_find sees its +free_cpus bit is set. If this happens the task will not have the +opportunity to run. + +One example is outlined here: +https://lore.kernel.org/lkml/20250110233010.2339521-1-opendmb@gmail.com + +Another occurs when the last deadline task is migrated from a +CPU that has an offlined runqueue. The dequeue_task member of +the deadline scheduler class will eventually call cpudl_clear +and set the free_cpus bit for the CPU. + +This commit modifies the cpudl_clear function to be aware of the +online state of the deadline runqueue so that the free_cpus mask +can be updated appropriately. + +It is no longer necessary to manage the mask outside of the +cpudl_set/clear functions so the cpudl_set/clear_freecpu +functions are removed. In addition, since the free_cpus mask is +now only updated under the cpudl lock the code was changed to +use the non-atomic __cpumask functions. + +Signed-off-by: Doug Berger +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + kernel/sched/cpudeadline.c | 34 +++++++++------------------------- + kernel/sched/cpudeadline.h | 4 +--- + kernel/sched/deadline.c | 8 ++++---- + 3 files changed, 14 insertions(+), 32 deletions(-) + +diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c +index 95baa12a10293..59d7b4f48c086 100644 +--- a/kernel/sched/cpudeadline.c ++++ b/kernel/sched/cpudeadline.c +@@ -165,12 +165,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, + * cpudl_clear - remove a CPU from the cpudl max-heap + * @cp: the cpudl max-heap context + * @cpu: the target CPU ++ * @online: the online state of the deadline runqueue + * + * Notes: assumes cpu_rq(cpu)->lock is locked + * + * Returns: (void) + */ +-void cpudl_clear(struct cpudl *cp, int cpu) ++void cpudl_clear(struct cpudl *cp, int cpu, bool online) + { + int old_idx, new_cpu; + unsigned long flags; +@@ -183,7 +184,7 @@ void cpudl_clear(struct cpudl *cp, int cpu) + if (old_idx == IDX_INVALID) { + /* + * Nothing to remove if old_idx was invalid. +- * This could happen if a rq_offline_dl is ++ * This could happen if rq_online_dl or rq_offline_dl is + * called for a CPU without -dl tasks running. + */ + } else { +@@ -194,9 +195,12 @@ void cpudl_clear(struct cpudl *cp, int cpu) + cp->elements[new_cpu].idx = old_idx; + cp->elements[cpu].idx = IDX_INVALID; + cpudl_heapify(cp, old_idx); +- +- cpumask_set_cpu(cpu, cp->free_cpus); + } ++ if (likely(online)) ++ __cpumask_set_cpu(cpu, cp->free_cpus); ++ else ++ __cpumask_clear_cpu(cpu, cp->free_cpus); ++ + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +@@ -227,7 +231,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + cp->elements[new_idx].cpu = cpu; + cp->elements[cpu].idx = new_idx; + cpudl_heapify_up(cp, new_idx); +- cpumask_clear_cpu(cpu, cp->free_cpus); ++ __cpumask_clear_cpu(cpu, cp->free_cpus); + } else { + cp->elements[old_idx].dl = dl; + cpudl_heapify(cp, old_idx); +@@ -236,26 +240,6 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +-/* +- * cpudl_set_freecpu - Set the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_set_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_set_cpu(cpu, cp->free_cpus); +-} +- +-/* +- * cpudl_clear_freecpu - Clear the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_clear_cpu(cpu, cp->free_cpus); +-} +- + /* + * cpudl_init - initialize the cpudl structure + * @cp: the cpudl max-heap context +diff --git a/kernel/sched/cpudeadline.h b/kernel/sched/cpudeadline.h +index 0adeda93b5fb5..ecff718d94aea 100644 +--- a/kernel/sched/cpudeadline.h ++++ b/kernel/sched/cpudeadline.h +@@ -18,9 +18,7 @@ struct cpudl { + #ifdef CONFIG_SMP + int cpudl_find(struct cpudl *cp, struct task_struct *p, struct cpumask *later_mask); + void cpudl_set(struct cpudl *cp, int cpu, u64 dl); +-void cpudl_clear(struct cpudl *cp, int cpu); ++void cpudl_clear(struct cpudl *cp, int cpu, bool online); + int cpudl_init(struct cpudl *cp); +-void cpudl_set_freecpu(struct cpudl *cp, int cpu); +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu); + void cpudl_cleanup(struct cpudl *cp); + #endif /* CONFIG_SMP */ +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index 6ec66fef3f91e..abd0fb2d839c1 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -1852,7 +1852,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline) + if (!dl_rq->dl_nr_running) { + dl_rq->earliest_dl.curr = 0; + dl_rq->earliest_dl.next = 0; +- cpudl_clear(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, rq->online); + cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr); + } else { + struct rb_node *leftmost = rb_first_cached(&dl_rq->root); +@@ -2950,9 +2950,10 @@ static void rq_online_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_set_overload(rq); + +- cpudl_set_freecpu(&rq->rd->cpudl, rq->cpu); + if (rq->dl.dl_nr_running > 0) + cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr); ++ else ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, true); + } + + /* Assumes rq->lock is held */ +@@ -2961,8 +2962,7 @@ static void rq_offline_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_clear_overload(rq); + +- cpudl_clear(&rq->rd->cpudl, rq->cpu); +- cpudl_clear_freecpu(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, false); + } + + void __init init_sched_dl_class(void) +-- +2.51.0 + diff --git a/queue-6.12/sched-fair-revert-max_newidle_lb_cost-bump.patch b/queue-6.12/sched-fair-revert-max_newidle_lb_cost-bump.patch new file mode 100644 index 0000000000..593fdc46ee --- /dev/null +++ b/queue-6.12/sched-fair-revert-max_newidle_lb_cost-bump.patch @@ -0,0 +1,77 @@ +From 71a3ef23ecf39603c28b76c1dbdaec42dd6ff653 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 17:01:20 +0100 +Subject: sched/fair: Revert max_newidle_lb_cost bump + +From: Peter Zijlstra + +[ Upstream commit d206fbad9328ddb68ebabd7cf7413392acd38081 ] + +Many people reported regressions on their database workloads due to: + + 155213a2aed4 ("sched/fair: Bump sd->max_newidle_lb_cost when newidle balance fails") + +For instance Adam Li reported a 6% regression on SpecJBB. + +Conversely this will regress schbench again; on my machine from 2.22 +Mrps/s down to 2.04 Mrps/s. + +Reported-by: Joseph Salisbury +Reported-by: Adam Li +Reported-by: Dietmar Eggemann +Reported-by: Hazem Mohamed Abuelfotoh +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dietmar Eggemann +Tested-by: Dietmar Eggemann +Tested-by: Chris Mason +Link: https://lkml.kernel.org/r/20250626144017.1510594-2-clm@fb.com +Link: https://lkml.kernel.org/r/006c9df2-b691-47f1-82e6-e233c3f91faf@oracle.com +Link: https://patch.msgid.link/20251107161739.406147760@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 19 +++---------------- + 1 file changed, 3 insertions(+), 16 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 62b8c7e914ebc..3ceb7f69f8f7b 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -12238,14 +12238,8 @@ static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) + /* + * Track max cost of a domain to make sure to not delay the + * next wakeup on the CPU. +- * +- * sched_balance_newidle() bumps the cost whenever newidle +- * balance fails, and we don't want things to grow out of +- * control. Use the sysctl_sched_migration_cost as the upper +- * limit, plus a litle extra to avoid off by ones. + */ +- sd->max_newidle_lb_cost = +- min(cost, sysctl_sched_migration_cost + 200); ++ sd->max_newidle_lb_cost = cost; + sd->last_decay_max_lb_cost = jiffies; + } else if (time_after(jiffies, sd->last_decay_max_lb_cost + HZ)) { + /* +@@ -12950,17 +12944,10 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) + + t1 = sched_clock_cpu(this_cpu); + domain_cost = t1 - t0; ++ update_newidle_cost(sd, domain_cost); ++ + curr_cost += domain_cost; + t0 = t1; +- +- /* +- * Failing newidle means it is not effective; +- * bump the cost so we end up doing less of it. +- */ +- if (!pulled_task) +- domain_cost = (3 * sd->max_newidle_lb_cost) / 2; +- +- update_newidle_cost(sd, domain_cost); + } + + /* +-- +2.51.0 + diff --git a/queue-6.12/scripts-faddr2line-fix-argument-list-too-long-error.patch b/queue-6.12/scripts-faddr2line-fix-argument-list-too-long-error.patch new file mode 100644 index 0000000000..4e56d7c408 --- /dev/null +++ b/queue-6.12/scripts-faddr2line-fix-argument-list-too-long-error.patch @@ -0,0 +1,59 @@ +From 2dc3b691e0c6eac8ee66f90c70a4d041a9181e26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 12:03:58 +0200 +Subject: scripts/faddr2line: Fix "Argument list too long" error + +From: Pankaj Raghav + +[ Upstream commit ff5c0466486ba8d07ab2700380e8fd6d5344b4e9 ] + +The run_readelf() function reads the entire output of readelf into a +single shell variable. For large object files with extensive debug +information, the size of this variable can exceed the system's +command-line argument length limit. + +When this variable is subsequently passed to sed via `echo "${out}"`, it +triggers an "Argument list too long" error, causing the script to fail. + +Fix this by redirecting the output of readelf to a temporary file +instead of a variable. The sed commands are then modified to read from +this file, avoiding the argument length limitation entirely. + +Signed-off-by: Pankaj Raghav +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + scripts/faddr2line | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/scripts/faddr2line b/scripts/faddr2line +index 1fa6beef9f978..477b6d2aa3179 100755 +--- a/scripts/faddr2line ++++ b/scripts/faddr2line +@@ -107,14 +107,19 @@ find_dir_prefix() { + + run_readelf() { + local objfile=$1 +- local out=$(${READELF} --file-header --section-headers --symbols --wide $objfile) ++ local tmpfile ++ tmpfile=$(mktemp) ++ ++ ${READELF} --file-header --section-headers --symbols --wide "$objfile" > "$tmpfile" + + # This assumes that readelf first prints the file header, then the section headers, then the symbols. + # Note: It seems that GNU readelf does not prefix section headers with the "There are X section headers" + # line when multiple options are given, so let's also match with the "Section Headers:" line. +- ELF_FILEHEADER=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/q;p') +- ELF_SECHEADERS=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/,$p' | sed -n '/Symbol table .* contains [0-9]* entries:/q;p') +- ELF_SYMS=$(echo "${out}" | sed -n '/Symbol table .* contains [0-9]* entries:/,$p') ++ ELF_FILEHEADER=$(sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/q;p' "$tmpfile") ++ ELF_SECHEADERS=$(sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/,$p' "$tmpfile" | sed -n '/Symbol table .* contains [0-9]* entries:/q;p') ++ ELF_SYMS=$(sed -n '/Symbol table .* contains [0-9]* entries:/,$p' "$tmpfile") ++ ++ rm -f -- "$tmpfile" + } + + check_vmlinux() { +-- +2.51.0 + diff --git a/queue-6.12/series b/queue-6.12/series new file mode 100644 index 0000000000..7cc312b701 --- /dev/null +++ b/queue-6.12/series @@ -0,0 +1,44 @@ +btrfs-do-not-skip-logging-new-dentries-when-logging-.patch +btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch +bpf-arm64-do-not-audit-capability-check-in-do_jit.patch +btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch +shmem-fix-recovery-on-rename-failures.patch +iomap-adjust-read-range-correctly-for-non-block-alig.patch +iomap-account-for-unaligned-end-offsets-when-truncat.patch +scripts-faddr2line-fix-argument-list-too-long-error.patch +perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch +sched-deadline-only-set-free_cpus-for-online-runqueu.patch +sched-fair-revert-max_newidle_lb_cost-bump.patch +x86-ptrace-always-inline-trivial-accessors.patch +acpica-avoid-walking-the-namespace-if-start_node-is-.patch +acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch +cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch +acpi-fan-workaround-for-64-bit-firmware-bug.patch +cpufreq-s5pv210-fix-refcount-leak.patch +cpuidle-menu-use-residency-threshold-in-polling-stat.patch +livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch +fs-ntfs3-support-timestamps-prior-to-epoch.patch +kbuild-use-objtree-for-module-signing-key-path.patch +ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch +hfsplus-fix-volume-corruption-issue-for-generic-070.patch +hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch +hfsplus-verify-inode-mode-when-loading-from-disk.patch +hfsplus-fix-volume-corruption-issue-for-generic-073.patch +fs-ntfs3-check-for-shutdown-in-fsync.patch +wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch +wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch +wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch +wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch +wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch +btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch +gfs2-fix-remote-evict-for-read-only-filesystems.patch +gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch +smb-server-fix-return-value-of-smb2_ioctl.patch +ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch +ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch +bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch +bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch +bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch +bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch +bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch +gfs2-fix-use-of-bio_chain.patch diff --git a/queue-6.12/shmem-fix-recovery-on-rename-failures.patch b/queue-6.12/shmem-fix-recovery-on-rename-failures.patch new file mode 100644 index 0000000000..2670db1c0f --- /dev/null +++ b/queue-6.12/shmem-fix-recovery-on-rename-failures.patch @@ -0,0 +1,179 @@ +From 07a056a25de21ffe5a36c63fa0f5f0238f5e85e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Dec 2025 17:50:23 -0500 +Subject: shmem: fix recovery on rename failures + +From: Al Viro + +[ Upstream commit e1b4c6a58304fd490124cc2b454d80edc786665c ] + +maple_tree insertions can fail if we are seriously short on memory; +simple_offset_rename() does not recover well if it runs into that. +The same goes for simple_offset_rename_exchange(). + +Moreover, shmem_whiteout() expects that if it succeeds, the caller will +progress to d_move(), i.e. that shmem_rename2() won't fail past the +successful call of shmem_whiteout(). + +Not hard to fix, fortunately - mtree_store() can't fail if the index we +are trying to store into is already present in the tree as a singleton. + +For simple_offset_rename_exchange() that's enough - we just need to be +careful about the order of operations. + +For simple_offset_rename() solution is to preinsert the target into the +tree for new_dir; the rest can be done without any potentially failing +operations. + +That preinsertion has to be done in shmem_rename2() rather than in +simple_offset_rename() itself - otherwise we'd need to deal with the +possibility of failure after successful shmem_whiteout(). + +Fixes: a2e459555c5f ("shmem: stable directory offsets") +Reviewed-by: Christian Brauner +Reviewed-by: Chuck Lever +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/libfs.c | 50 +++++++++++++++++++--------------------------- + include/linux/fs.h | 2 +- + mm/shmem.c | 18 ++++++++++++----- + 3 files changed, 35 insertions(+), 35 deletions(-) + +diff --git a/fs/libfs.c b/fs/libfs.c +index 8743241678496..028f2cf729d5d 100644 +--- a/fs/libfs.c ++++ b/fs/libfs.c +@@ -345,22 +345,22 @@ void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry) + * User space expects the directory offset value of the replaced + * (new) directory entry to be unchanged after a rename. + * +- * Returns zero on success, a negative errno value on failure. ++ * Caller must have grabbed a slot for new_dentry in the maple_tree ++ * associated with new_dir, even if dentry is negative. + */ +-int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, +- struct inode *new_dir, struct dentry *new_dentry) ++void simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry) + { + struct offset_ctx *old_ctx = old_dir->i_op->get_offset_ctx(old_dir); + struct offset_ctx *new_ctx = new_dir->i_op->get_offset_ctx(new_dir); + long new_offset = dentry2offset(new_dentry); + +- simple_offset_remove(old_ctx, old_dentry); ++ if (WARN_ON(!new_offset)) ++ return; + +- if (new_offset) { +- offset_set(new_dentry, 0); +- return simple_offset_replace(new_ctx, old_dentry, new_offset); +- } +- return simple_offset_add(new_ctx, old_dentry); ++ simple_offset_remove(old_ctx, old_dentry); ++ offset_set(new_dentry, 0); ++ WARN_ON(simple_offset_replace(new_ctx, old_dentry, new_offset)); + } + + /** +@@ -387,31 +387,23 @@ int simple_offset_rename_exchange(struct inode *old_dir, + long new_index = dentry2offset(new_dentry); + int ret; + +- simple_offset_remove(old_ctx, old_dentry); +- simple_offset_remove(new_ctx, new_dentry); ++ if (WARN_ON(!old_index || !new_index)) ++ return -EINVAL; + +- ret = simple_offset_replace(new_ctx, old_dentry, new_index); +- if (ret) +- goto out_restore; ++ ret = mtree_store(&new_ctx->mt, new_index, old_dentry, GFP_KERNEL); ++ if (WARN_ON(ret)) ++ return ret; + +- ret = simple_offset_replace(old_ctx, new_dentry, old_index); +- if (ret) { +- simple_offset_remove(new_ctx, old_dentry); +- goto out_restore; ++ ret = mtree_store(&old_ctx->mt, old_index, new_dentry, GFP_KERNEL); ++ if (WARN_ON(ret)) { ++ mtree_store(&new_ctx->mt, new_index, new_dentry, GFP_KERNEL); ++ return ret; + } + +- ret = simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); +- if (ret) { +- simple_offset_remove(new_ctx, old_dentry); +- simple_offset_remove(old_ctx, new_dentry); +- goto out_restore; +- } ++ offset_set(old_dentry, new_index); ++ offset_set(new_dentry, old_index); ++ simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); + return 0; +- +-out_restore: +- (void)simple_offset_replace(old_ctx, old_dentry, old_index); +- (void)simple_offset_replace(new_ctx, new_dentry, new_index); +- return ret; + } + + /** +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 37a01c9d96583..87720e1b54192 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -3446,7 +3446,7 @@ struct offset_ctx { + void simple_offset_init(struct offset_ctx *octx); + int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry); + void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry); +-int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, ++void simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); + int simple_offset_rename_exchange(struct inode *old_dir, + struct dentry *old_dentry, +diff --git a/mm/shmem.c b/mm/shmem.c +index 7e07188e82696..0c3113b5b5aaa 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -3749,6 +3749,7 @@ static int shmem_rename2(struct mnt_idmap *idmap, + { + struct inode *inode = d_inode(old_dentry); + int they_are_dirs = S_ISDIR(inode->i_mode); ++ bool had_offset = false; + int error; + + if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) +@@ -3761,16 +3762,23 @@ static int shmem_rename2(struct mnt_idmap *idmap, + if (!simple_empty(new_dentry)) + return -ENOTEMPTY; + ++ error = simple_offset_add(shmem_get_offset_ctx(new_dir), new_dentry); ++ if (error == -EBUSY) ++ had_offset = true; ++ else if (unlikely(error)) ++ return error; ++ + if (flags & RENAME_WHITEOUT) { + error = shmem_whiteout(idmap, old_dir, old_dentry); +- if (error) ++ if (error) { ++ if (!had_offset) ++ simple_offset_remove(shmem_get_offset_ctx(new_dir), ++ new_dentry); + return error; ++ } + } + +- error = simple_offset_rename(old_dir, old_dentry, new_dir, new_dentry); +- if (error) +- return error; +- ++ simple_offset_rename(old_dir, old_dentry, new_dir, new_dentry); + if (d_really_is_positive(new_dentry)) { + (void) shmem_unlink(new_dir, new_dentry); + if (they_are_dirs) { +-- +2.51.0 + diff --git a/queue-6.12/smb-server-fix-return-value-of-smb2_ioctl.patch b/queue-6.12/smb-server-fix-return-value-of-smb2_ioctl.patch new file mode 100644 index 0000000000..9063ae2816 --- /dev/null +++ b/queue-6.12/smb-server-fix-return-value-of-smb2_ioctl.patch @@ -0,0 +1,61 @@ +From 874dad6de6af96a3f669767c321ad5786e1d4462 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:46:10 +0800 +Subject: smb/server: fix return value of smb2_ioctl() + +From: ChenXiaoSong + +[ Upstream commit 269df046c1e15ab34fa26fd90db9381f022a0963 ] + +__process_request() will not print error messages if smb2_ioctl() +always returns 0. + +Fix this by returning the correct value at the end of function. + +Signed-off-by: ChenXiaoSong +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/smb2pdu.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index cd42d25812661..d9e28191c267e 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -8107,7 +8107,7 @@ int smb2_ioctl(struct ksmbd_work *work) + id = req->VolatileFileId; + + if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) { +- rsp->hdr.Status = STATUS_NOT_SUPPORTED; ++ ret = -EOPNOTSUPP; + goto out; + } + +@@ -8127,8 +8127,9 @@ int smb2_ioctl(struct ksmbd_work *work) + case FSCTL_DFS_GET_REFERRALS: + case FSCTL_DFS_GET_REFERRALS_EX: + /* Not support DFS yet */ ++ ret = -EOPNOTSUPP; + rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED; +- goto out; ++ goto out2; + case FSCTL_CREATE_OR_GET_OBJECT_ID: + { + struct file_object_buf_type1_ioctl_rsp *obj_buf; +@@ -8418,8 +8419,10 @@ int smb2_ioctl(struct ksmbd_work *work) + rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL; + else if (ret < 0 || rsp->hdr.Status == 0) + rsp->hdr.Status = STATUS_INVALID_PARAMETER; ++ ++out2: + smb2_set_err_rsp(work); +- return 0; ++ return ret; + } + + /** +-- +2.51.0 + diff --git a/queue-6.12/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch b/queue-6.12/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch new file mode 100644 index 0000000000..61829a6f96 --- /dev/null +++ b/queue-6.12/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch @@ -0,0 +1,61 @@ +From f91f2d21f4dbdf448d603bebdb95fe9eca06ddd4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 11:03:14 +0100 +Subject: wifi: brcmfmac: Add DMI nvram filename quirk for Acer A1 840 tablet + +From: Hans de Goede + +[ Upstream commit a8e5a110c0c38e08e5dd66356cd1156e91cf88e1 ] + +The Acer A1 840 tablet contains quite generic names in the sys_vendor and +product_name DMI strings, without this patch brcmfmac will try to load: +brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file which is a bit +too generic. + +Add a DMI quirk so that a unique and clearly identifiable nvram file name +is used on the Acer A1 840 tablet. + +Acked-by: Arend van Spriel +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20251103100314.353826-1-hansg@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +index c3a602197662b..abe7f6501e5ed 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +@@ -24,6 +24,10 @@ static const struct brcmf_dmi_data acepc_t8_data = { + BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" + }; + ++static const struct brcmf_dmi_data acer_a1_840_data = { ++ BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" ++}; ++ + /* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus + * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. + */ +@@ -91,6 +95,16 @@ static const struct dmi_system_id dmi_platform_data[] = { + }, + .driver_data = (void *)&acepc_t8_data, + }, ++ { ++ /* Acer Iconia One 8 A1-840 (non FHD version) */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), ++ /* Above strings are too generic also match BIOS date */ ++ DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), ++ }, ++ .driver_data = (void *)&acer_a1_840_data, ++ }, + { + /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ + .matches = { +-- +2.51.0 + diff --git a/queue-6.12/wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch b/queue-6.12/wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch new file mode 100644 index 0000000000..386fea5651 --- /dev/null +++ b/queue-6.12/wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch @@ -0,0 +1,85 @@ +From 22c479e3872203391b2532646fa43d4a9bd4fa0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 17:40:21 +0100 +Subject: wifi: cfg80211: stop radar detection in cfg80211_leave() + +From: Johannes Berg + +[ Upstream commit 9f33477b9a31a1edfe2df9f1a0359cccb0e16b4c ] + +If an interface is set down or, per the previous patch, changes +type, radar detection for it should be cancelled. This is done +for AP mode in mac80211 (somewhat needlessly, since cfg80211 can +do it, but didn't until now), but wasn't handled for mesh, so if +radar detection was started and then the interface set down or +its type switched (the latter sometimes happning in the hwsim +test 'mesh_peer_connected_dfs'), radar detection would be around +with the interface unknown to the driver, later leading to some +warnings around chanctx usage. + +Link: https://patch.msgid.link/20251121174021.290120e419e3.I2a5650c9062e29c988992dd8ce0d8eb570d23267@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/core.c | 1 + + net/wireless/core.h | 1 + + net/wireless/mlme.c | 19 +++++++++++++++++++ + 3 files changed, 21 insertions(+) + +diff --git a/net/wireless/core.c b/net/wireless/core.c +index dc207a8986c7f..6bb8a7037d24d 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1343,6 +1343,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, + + cfg80211_pmsr_wdev_down(wdev); + ++ cfg80211_stop_radar_detection(wdev); + cfg80211_stop_background_radar_detection(wdev); + + switch (wdev->iftype) { +diff --git a/net/wireless/core.h b/net/wireless/core.h +index 3b3e3cd7027ac..d4b26cbe3342d 100644 +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -483,6 +483,7 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde + struct wireless_dev *wdev, + struct cfg80211_chan_def *chandef); + ++void cfg80211_stop_radar_detection(struct wireless_dev *wdev); + void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); + + void cfg80211_background_cac_done_wk(struct work_struct *work); +diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c +index d1a66410b9c55..26319522c7abc 100644 +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -1271,6 +1271,25 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde + return 0; + } + ++void cfg80211_stop_radar_detection(struct wireless_dev *wdev) ++{ ++ struct wiphy *wiphy = wdev->wiphy; ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ int link_id; ++ ++ for_each_valid_link(wdev, link_id) { ++ struct cfg80211_chan_def chandef; ++ ++ if (!wdev->links[link_id].cac_started) ++ continue; ++ ++ chandef = *wdev_chandef(wdev, link_id); ++ rdev_end_cac(rdev, wdev->netdev, link_id); ++ nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED, ++ wdev->netdev, GFP_KERNEL); ++ } ++} ++ + void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) + { + struct wiphy *wiphy = wdev->wiphy; +-- +2.51.0 + diff --git a/queue-6.12/wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch b/queue-6.12/wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch new file mode 100644 index 0000000000..d6186acff6 --- /dev/null +++ b/queue-6.12/wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch @@ -0,0 +1,63 @@ +From fa5e0066769f9c49c3b3e828f2801bd98e138630 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 17:40:20 +0100 +Subject: wifi: cfg80211: use cfg80211_leave() in iftype change + +From: Johannes Berg + +[ Upstream commit 7a27b73943a70ee226fa125327101fb18e94701d ] + +When changing the interface type, all activity on the interface has +to be stopped first. This was done independent of existing code in +cfg80211_leave(), so didn't handle e.g. background radar detection. +Use cfg80211_leave() to handle it the same way. + +Note that cfg80211_leave() behaves slightly differently for IBSS in +wireless extensions, it won't send an event in that case. We could +handle that, but since nl80211 was used to change the type, IBSS is +rare, and wext is already a corner case, it doesn't seem worth it. + +Link: https://patch.msgid.link/20251121174021.922ef48ce007.I970c8514252ef8a864a7fbdab9591b71031dee03@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/util.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index b115489a846f8..6aff651a9b68d 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -1230,28 +1230,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, + dev->ieee80211_ptr->use_4addr = false; + rdev_set_qos_map(rdev, dev, NULL); + +- switch (otype) { +- case NL80211_IFTYPE_AP: +- case NL80211_IFTYPE_P2P_GO: +- cfg80211_stop_ap(rdev, dev, -1, true); +- break; +- case NL80211_IFTYPE_ADHOC: +- cfg80211_leave_ibss(rdev, dev, false); +- break; +- case NL80211_IFTYPE_STATION: +- case NL80211_IFTYPE_P2P_CLIENT: +- cfg80211_disconnect(rdev, dev, +- WLAN_REASON_DEAUTH_LEAVING, true); +- break; +- case NL80211_IFTYPE_MESH_POINT: +- /* mesh should be handled? */ +- break; +- case NL80211_IFTYPE_OCB: +- cfg80211_leave_ocb(rdev, dev); +- break; +- default: +- break; +- } ++ cfg80211_leave(rdev, dev->ieee80211_ptr); + + cfg80211_process_rdev_events(rdev); + cfg80211_mlme_purge_registrations(dev->ieee80211_ptr); +-- +2.51.0 + diff --git a/queue-6.12/wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch b/queue-6.12/wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch new file mode 100644 index 0000000000..4dfd2bda78 --- /dev/null +++ b/queue-6.12/wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch @@ -0,0 +1,62 @@ +From cfde773b13a759b669f93140abec1ef518a44dfe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 19:54:54 +0800 +Subject: wifi: mt76: mt792x: fix wifi init fail by setting MCU_RUNNING after + CLC load + +From: Quan Zhou + +[ Upstream commit 066f417be5fd8c7fe581c5550206364735dad7a3 ] + +Set the MT76_STATE_MCU_RUNNING bit only after mt7921_load_clc() +has successfully completed. Previously, the MCU_RUNNING state +was set before loading CLC, which could cause conflict between +chip mcu_init retry and mac_reset flow, result in chip init fail +and chip abnormal status. By moving the state set after CLC load, +firmware initialization becomes robust and resolves init fail issue. + +Signed-off-by: Quan Zhou +Reviewed-by: druth@chromium.org +Link: https://patch.msgid.link/19ec8e4465142e774f17801025accd0ae2214092.1763465933.git.quan.zhou@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- + drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +index 02c1de8620a7f..8d3f3c8b1a889 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +@@ -637,10 +637,10 @@ int mt7921_run_firmware(struct mt792x_dev *dev) + if (err) + return err; + +- set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + err = mt7921_load_clc(dev, mt792x_ram_name(dev)); + if (err) + return err; ++ set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + + return mt7921_mcu_fw_log_2_host(dev, 1); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +index e42b4f0abbe7a..c42b3b376f77e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +@@ -958,10 +958,10 @@ int mt7925_run_firmware(struct mt792x_dev *dev) + if (err) + return err; + +- set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + err = mt7925_load_clc(dev, mt792x_ram_name(dev)); + if (err) + return err; ++ set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + + return mt7925_mcu_fw_log_2_host(dev, 1); + } +-- +2.51.0 + diff --git a/queue-6.12/wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch b/queue-6.12/wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch new file mode 100644 index 0000000000..104734ff4c --- /dev/null +++ b/queue-6.12/wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch @@ -0,0 +1,55 @@ +From dfbba5e14a1b9503eee84f9c4ed1d6eac6f7c4ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 16:10:01 +0200 +Subject: wifi: rtl8xxxu: Fix HT40 channel config for RTL8192CU, RTL8723AU + +From: Bitterblue Smith + +[ Upstream commit 5511ba3de434892e5ef3594d6eabbd12b1629356 ] + +Flip the response rate subchannel. It was backwards, causing low +speeds when using 40 MHz channel width. "iw dev ... station dump" +showed a low RX rate, 11M or less. + +Also fix the channel width field of RF6052_REG_MODE_AG. + +Tested only with RTL8192CU, but these settings are identical for +RTL8723AU. + +Signed-off-by: Bitterblue Smith +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/1f46571d-855b-43e1-8bfc-abacceb96043@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl8xxxu/core.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c +index 260f720550134..b517df2db6d75 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c +@@ -1252,7 +1252,7 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw) + opmode &= ~BW_OPMODE_20MHZ; + rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); + rsr &= ~RSR_RSC_BANDWIDTH_40M; +- if (sec_ch_above) ++ if (!sec_ch_above) + rsr |= RSR_RSC_UPPER_SUB_CHANNEL; + else + rsr |= RSR_RSC_LOWER_SUB_CHANNEL; +@@ -1321,9 +1321,8 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw) + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); +- if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) +- val32 &= ~MODE_AG_CHANNEL_20MHZ; +- else ++ val32 &= ~MODE_AG_BW_MASK; ++ if (hw->conf.chandef.width != NL80211_CHAN_WIDTH_40) + val32 |= MODE_AG_CHANNEL_20MHZ; + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } +-- +2.51.0 + diff --git a/queue-6.12/x86-ptrace-always-inline-trivial-accessors.patch b/queue-6.12/x86-ptrace-always-inline-trivial-accessors.patch new file mode 100644 index 0000000000..7f75bbf91f --- /dev/null +++ b/queue-6.12/x86-ptrace-always-inline-trivial-accessors.patch @@ -0,0 +1,89 @@ +From 649a5e0c099223fcbef5efc867b0151640385bed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 12:04:24 +0100 +Subject: x86/ptrace: Always inline trivial accessors + +From: Peter Zijlstra + +[ Upstream commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa ] + +A KASAN build bloats these single load/store helpers such that +it fails to inline them: + + vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled + +Make sure the compiler isn't allowed to do stupid. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Link: https://patch.msgid.link/20251031105435.GU4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index 5a83fbd9bc0b4..eb5b1e2aa7000 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -187,12 +187,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); + extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); + + +-static inline unsigned long regs_return_value(struct pt_regs *regs) ++static __always_inline unsigned long regs_return_value(struct pt_regs *regs) + { + return regs->ax; + } + +-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) ++static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) + { + regs->ax = rc; + } +@@ -277,34 +277,34 @@ static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) + } + #endif + +-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline unsigned long instruction_pointer(struct pt_regs *regs) ++static __always_inline unsigned long instruction_pointer(struct pt_regs *regs) + { + return regs->ip; + } + +-static inline void instruction_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void instruction_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->ip = val; + } + +-static inline unsigned long frame_pointer(struct pt_regs *regs) ++static __always_inline unsigned long frame_pointer(struct pt_regs *regs) + { + return regs->bp; + } + +-static inline unsigned long user_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long user_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline void user_stack_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->sp = val; + } +-- +2.51.0 + diff --git a/queue-6.18/acpi-fan-workaround-for-64-bit-firmware-bug.patch b/queue-6.18/acpi-fan-workaround-for-64-bit-firmware-bug.patch new file mode 100644 index 0000000000..3551366952 --- /dev/null +++ b/queue-6.18/acpi-fan-workaround-for-64-bit-firmware-bug.patch @@ -0,0 +1,126 @@ +From 4172e342dd38c68af0c40d27050f140e99ff51a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 01:41:45 +0200 +Subject: ACPI: fan: Workaround for 64-bit firmware bug + +From: Armin Wolf + +[ Upstream commit 2e00f7a4bb0ac25ec7477b55fe482da39fb4dce8 ] + +Some firmware implementations use the "Ones" ASL opcode to produce +an integer with all bits set in order to indicate missing speed or +power readings. This however only works when using 32-bit integers, +as the ACPI spec requires a 32-bit integer (0xFFFFFFFF) to be +returned for missing speed/power readings. With 64-bit integers the +"Ones" opcode produces a 64-bit integer with all bits set, violating +the ACPI spec regarding the placeholder value for missing readings. + +Work around such buggy firmware implementation by also checking for +64-bit integers with all bits set when reading _FST. + +Signed-off-by: Armin Wolf +[ rjw: Typo fix in the changelog ] +Link: https://patch.msgid.link/20251007234149.2769-3-W_Armin@gmx.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/fan.h | 33 +++++++++++++++++++++++++++++++++ + drivers/acpi/fan_hwmon.c | 10 +++------- + 2 files changed, 36 insertions(+), 7 deletions(-) + +diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h +index bedbab0e8e4e9..0d73433c38892 100644 +--- a/drivers/acpi/fan.h ++++ b/drivers/acpi/fan.h +@@ -11,6 +11,7 @@ + #define _ACPI_FAN_H_ + + #include ++#include + + #define ACPI_FAN_DEVICE_IDS \ + {"INT3404", }, /* Fan */ \ +@@ -60,6 +61,38 @@ struct acpi_fan { + struct device_attribute fine_grain_control; + }; + ++/** ++ * acpi_fan_speed_valid - Check if fan speed value is valid ++ * @speeed: Speed value returned by the ACPI firmware ++ * ++ * Check if the fan speed value returned by the ACPI firmware is valid. This function is ++ * necessary as ACPI firmware implementations can return 0xFFFFFFFF to signal that the ++ * ACPI fan does not support speed reporting. Additionally, some buggy ACPI firmware ++ * implementations return a value larger than the 32-bit integer value defined by ++ * the ACPI specification when using placeholder values. Such invalid values are also ++ * detected by this function. ++ * ++ * Returns: True if the fan speed value is valid, false otherwise. ++ */ ++static inline bool acpi_fan_speed_valid(u64 speed) ++{ ++ return speed < U32_MAX; ++} ++ ++/** ++ * acpi_fan_power_valid - Check if fan power value is valid ++ * @power: Power value returned by the ACPI firmware ++ * ++ * Check if the fan power value returned by the ACPI firmware is valid. ++ * See acpi_fan_speed_valid() for details. ++ * ++ * Returns: True if the fan power value is valid, false otherwise. ++ */ ++static inline bool acpi_fan_power_valid(u64 power) ++{ ++ return power < U32_MAX; ++} ++ + int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst); + int acpi_fan_create_attributes(struct acpi_device *device); + void acpi_fan_delete_attributes(struct acpi_device *device); +diff --git a/drivers/acpi/fan_hwmon.c b/drivers/acpi/fan_hwmon.c +index 4b2c2007f2d7f..47a02ef5a6067 100644 +--- a/drivers/acpi/fan_hwmon.c ++++ b/drivers/acpi/fan_hwmon.c +@@ -15,10 +15,6 @@ + + #include "fan.h" + +-/* Returned when the ACPI fan does not support speed reporting */ +-#define FAN_SPEED_UNAVAILABLE U32_MAX +-#define FAN_POWER_UNAVAILABLE U32_MAX +- + static struct acpi_fan_fps *acpi_fan_get_current_fps(struct acpi_fan *fan, u64 control) + { + unsigned int i; +@@ -77,7 +73,7 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_ + * when the associated attribute should not be created. + */ + for (i = 0; i < fan->fps_count; i++) { +- if (fan->fps[i].power != FAN_POWER_UNAVAILABLE) ++ if (acpi_fan_power_valid(fan->fps[i].power)) + return 0444; + } + +@@ -106,7 +102,7 @@ static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + case hwmon_fan: + switch (attr) { + case hwmon_fan_input: +- if (fst.speed == FAN_SPEED_UNAVAILABLE) ++ if (!acpi_fan_speed_valid(fst.speed)) + return -ENODEV; + + if (fst.speed > LONG_MAX) +@@ -134,7 +130,7 @@ static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + if (!fps) + return -EIO; + +- if (fps->power == FAN_POWER_UNAVAILABLE) ++ if (!acpi_fan_power_valid(fps->power)) + return -ENODEV; + + if (fps->power > LONG_MAX / MICROWATT_PER_MILLIWATT) +-- +2.51.0 + diff --git a/queue-6.18/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch b/queue-6.18/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch new file mode 100644 index 0000000000..6b88c166c2 --- /dev/null +++ b/queue-6.18/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch @@ -0,0 +1,59 @@ +From e724b89fd74bff6f109383a22dc07545f646ab89 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 13:43:19 +0300 +Subject: ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() + only + +From: Sakari Ailus + +[ Upstream commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 ] + +Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode +property API is somewhat problematic as the latter is used in the +impelementation of the former. Instead of using +fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call +acpi_get_next_subnode() directly instead. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20251001104320.1272752-3-sakari.ailus@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index b12057baaae7b..19737f9e1e16f 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1472,7 +1472,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + + if (!prev) { + do { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + /* + * The names of the port nodes begin with "port@" + * followed by the number of the port node and they also +@@ -1490,13 +1490,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + if (!port) + return NULL; + +- endpoint = fwnode_get_next_child_node(port, prev); ++ endpoint = acpi_get_next_subnode(port, prev); + while (!endpoint) { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + if (!port) + break; + if (is_acpi_graph_node(port, "port")) +- endpoint = fwnode_get_next_child_node(port, NULL); ++ endpoint = acpi_get_next_subnode(port, NULL); + } + + /* +-- +2.51.0 + diff --git a/queue-6.18/acpica-avoid-walking-the-namespace-if-start_node-is-.patch b/queue-6.18/acpica-avoid-walking-the-namespace-if-start_node-is-.patch new file mode 100644 index 0000000000..2978c1da21 --- /dev/null +++ b/queue-6.18/acpica-avoid-walking-the-namespace-if-start_node-is-.patch @@ -0,0 +1,63 @@ +From 12de8016fbf388b8deaa8ce6721eb3ffa413b55b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:14:38 +0800 +Subject: ACPICA: Avoid walking the Namespace if start_node is NULL + +From: Cryolitia PukNgae + +[ Upstream commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 ] + +Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace +if it is not there") fixed the situation when both start_node and +acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed +on Honor Magicbook 14 Pro [1]. + +That happens due to the access to the member of parent_node in +acpi_ns_get_next_node(). The NULL pointer dereference will always +happen, no matter whether or not the start_node is equal to +ACPI_ROOT_OBJECT, so move the check of start_node being NULL +out of the if block. + +Unfortunately, all the attempts to contact Honor have failed, they +refused to provide any technical support for Linux. + +The bad DSDT table's dump could be found on GitHub [2]. + +DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025 + +Link: https://github.com/acpica/acpica/commit/1c1b57b9eba4554cb132ee658dd942c0210ed20d +Link: https://gist.github.com/Cryolitia/a860ffc97437dcd2cd988371d5b73ed7 [1] +Link: https://github.com/denis-bb/honor-fmb-p-dsdt [2] +Signed-off-by: Cryolitia PukNgae +Reviewed-by: WangYuli +[ rjw: Subject adjustment, changelog edits ] +Link: https://patch.msgid.link/20251125-acpica-v1-1-99e63b1b25f8@linux.dev +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/nswalk.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c +index a2ac06a26e921..5670ff5a43cd4 100644 +--- a/drivers/acpi/acpica/nswalk.c ++++ b/drivers/acpi/acpica/nswalk.c +@@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type, + + if (start_node == ACPI_ROOT_OBJECT) { + start_node = acpi_gbl_root_node; +- if (!start_node) { +- return_ACPI_STATUS(AE_NO_NAMESPACE); +- } ++ } ++ ++ /* Avoid walking the namespace if the StartNode is NULL */ ++ ++ if (!start_node) { ++ return_ACPI_STATUS(AE_NO_NAMESPACE); + } + + /* Null child means "get first node" */ +-- +2.51.0 + diff --git a/queue-6.18/bluetooth-btusb-add-new-custom-firmwares.patch b/queue-6.18/bluetooth-btusb-add-new-custom-firmwares.patch new file mode 100644 index 0000000000..b0aa16df46 --- /dev/null +++ b/queue-6.18/bluetooth-btusb-add-new-custom-firmwares.patch @@ -0,0 +1,41 @@ +From 64608f0ed045cac87e5f506bcdf550a1f5bf1fb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 17:24:37 +0800 +Subject: Bluetooth: btusb: add new custom firmwares + +From: Shuai Zhang + +[ Upstream commit a8b38d19857d42a1f2e90c9d9b0f74de2500acd7 ] + +The new platform uses the QCA2066 chip along with a new board ID, which +requires a dedicated firmware file to ensure proper initialization. +Without this entry, the driver cannot locate and load the correct +firmware, resulting in Bluetooth bring-up failure. + +This patch adds a new entry to the firmware table for QCA2066 so that +the driver can correctly identify the board ID and load the appropriate +firmware from 'qca/QCA2066/' in the linux-firmware repository. + +Signed-off-by: Shuai Zhang +Acked-by: Dmitry Baryshkov +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index cc03c8c38b16f..22f1932fe9126 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -3267,6 +3267,7 @@ static const struct qca_device_info qca_devices_table[] = { + + static const struct qca_custom_firmware qca_custom_btfws[] = { + { 0x00130201, 0x030A, "QCA2066" }, ++ { 0x00130201, 0x030B, "QCA2066" }, + { }, + }; + +-- +2.51.0 + diff --git a/queue-6.18/bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch b/queue-6.18/bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch new file mode 100644 index 0000000000..f49dadb58d --- /dev/null +++ b/queue-6.18/bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch @@ -0,0 +1,67 @@ +From 725a92243744c729675b0f8882af9c55d2a1c327 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 13:50:39 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 0x0489/0xE12F for RTL8852BE-VT + +From: Max Chou + +[ Upstream commit 32caa197b9b603e20f49fd3a0dffecd0cd620499 ] + +Add the support ID(0x0489, 0xE12F) to usb_device_id table for +Realtek RTL8852BE-VT. + +The device info from /sys/kernel/debug/usb/devices as below. + +T: Bus=04 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 86 Spd=12 MxCh= 0 +D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e12f Rev= 0.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Max Chou +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index bd26a8db64096..b92bfd131567e 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -587,6 +587,8 @@ static const struct usb_device_id quirks_table[] = { + /* Realtek 8852BT/8852BE-VT Bluetooth devices */ + { USB_DEVICE(0x0bda, 0x8520), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe12f), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8922AE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0x8922), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-6.18/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch b/queue-6.18/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch new file mode 100644 index 0000000000..774992cacf --- /dev/null +++ b/queue-6.18/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch @@ -0,0 +1,67 @@ +From 83d1e892313bf480dafb07014d7a972841bc80c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 15:33:38 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE + +From: Gongwei Li + +[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ] + +Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3533 Rev= 1.10 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Gongwei Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 22f1932fe9126..bd26a8db64096 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -504,6 +504,8 @@ static const struct usb_device_id quirks_table[] = { + /* Realtek 8821CE Bluetooth devices */ + { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-6.18/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch b/queue-6.18/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch new file mode 100644 index 0000000000..b4af43b6de --- /dev/null +++ b/queue-6.18/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch @@ -0,0 +1,67 @@ +From 375fbc18018df455f2d6b1154bb9b248afd3a74e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 16:46:47 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 2b89/6275 for RTL8761BUV + +From: Chingbin Li + +[ Upstream commit 8dbbb5423c0802ec21266765de80fd491868fab1 ] + +Add VID 2b89 & PID 6275 for Realtek RTL8761BUV USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=2b89 ProdID=6275 Rev= 2.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00E04C239987 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Chingbin Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index fa683bb7f0b49..c70e79e69be8d 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -781,6 +781,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x2b89, 0x6275), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Additional Realtek 8821AE Bluetooth devices */ + { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, +-- +2.51.0 + diff --git a/queue-6.18/bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch b/queue-6.18/bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch new file mode 100644 index 0000000000..fa5fca2eb8 --- /dev/null +++ b/queue-6.18/bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch @@ -0,0 +1,78 @@ +From fa32d280d7ce2fdad706925e63eacbb159a83581 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 11:31:49 +0800 +Subject: Bluetooth: btusb: MT7920: Add VID/PID 0489/e135 + +From: Chris Lu + +[ Upstream commit c126f98c011f5796ba118ef2093122d02809d30d ] + +Add VID 0489 & PID e135 for MediaTek MT7920 USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e135 Rev= 1.00 +S: Manufacturer=MediaTek Inc. +S: Product=Wireless_Device +S: SerialNumber=000000000 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA +A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us +I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us + +Signed-off-by: Chris Lu +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 36f18f2657ab8..cc03c8c38b16f 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -621,6 +621,8 @@ static const struct usb_device_id quirks_table[] = { + /* Additional MediaTek MT7920 Bluetooth devices */ + { USB_DEVICE(0x0489, 0xe134), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe135), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3620), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3621), .driver_info = BTUSB_MEDIATEK | +-- +2.51.0 + diff --git a/queue-6.18/bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch b/queue-6.18/bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch new file mode 100644 index 0000000000..ce0c28c487 --- /dev/null +++ b/queue-6.18/bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch @@ -0,0 +1,78 @@ +From 2810cecabc6bd78eda0841a11f9863d3bdd7319a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 11:31:50 +0800 +Subject: Bluetooth: btusb: MT7922: Add VID/PID 0489/e170 + +From: Chris Lu + +[ Upstream commit 5a6700a31c953af9a17a7e2681335f31d922614d ] + +Add VID 0489 & PID e170 for MediaTek MT7922 USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e170 Rev= 1.00 +S: Manufacturer=MediaTek Inc. +S: Product=Wireless_Device +S: SerialNumber=000000000 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA +A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us +I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us + +Signed-off-by: Chris Lu +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index c70e79e69be8d..36f18f2657ab8 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -685,6 +685,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe153), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe170), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK | +-- +2.51.0 + diff --git a/queue-6.18/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch b/queue-6.18/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch new file mode 100644 index 0000000000..997cb0e0a1 --- /dev/null +++ b/queue-6.18/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch @@ -0,0 +1,56 @@ +From 90b702b7122bea4cfb602137ade05b22c95d1d1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Dec 2025 13:59:16 +0100 +Subject: bpf, arm64: Do not audit capability check in do_jit() + +From: Ondrej Mosnacek + +[ Upstream commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c ] + +Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit +capability check in do_jit()"), change the capable() call to +ns_capable_noaudit() in order to avoid spurious SELinux denials in audit +log. + +The commit log from that commit applies here as well: +""" +The failure of this check only results in a security mitigation being +applied, slightly affecting performance of the compiled BPF program. It +doesn't result in a failed syscall, an thus auditing a failed LSM +permission check for it is unwanted. For example with SELinux, it causes +a denial to be reported for confined processes running as root, which +tends to be flagged as a problem to be fixed in the policy. Yet +dontauditing or allowing CAP_SYS_ADMIN to the domain may not be +desirable, as it would allow/silence also other checks - either going +against the principle of least privilege or making debugging potentially +harder. + +Fix it by changing it from capable() to ns_capable_noaudit(), which +instructs the LSMs to not audit the resulting denials. +""" + +Fixes: f300769ead03 ("arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users") +Signed-off-by: Ondrej Mosnacek +Link: https://lore.kernel.org/r/20251204125916.441021-1-omosnace@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + arch/arm64/net/bpf_jit_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index 0c9a50a1e73e7..0dfefeedfe56c 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -1004,7 +1004,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) + arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) + return; + +- if (capable(CAP_SYS_ADMIN)) ++ if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) + return; + + if (supports_clearbhb(SCOPE_SYSTEM)) { +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-truncated-dmabuf-iterator-reads.patch b/queue-6.18/bpf-fix-truncated-dmabuf-iterator-reads.patch new file mode 100644 index 0000000000..aa9890a197 --- /dev/null +++ b/queue-6.18/bpf-fix-truncated-dmabuf-iterator-reads.patch @@ -0,0 +1,121 @@ +From 083612c09059e4c7c318080b23f90840ce58e6b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 16:03:47 -0800 +Subject: bpf: Fix truncated dmabuf iterator reads + +From: T.J. Mercier + +[ Upstream commit 234483565dbb2b264fdd165927c89fbf3ecf4733 ] + +If there is a large number (hundreds) of dmabufs allocated, the text +output generated from dmabuf_iter_seq_show can exceed common user buffer +sizes (e.g. PAGE_SIZE) necessitating multiple start/stop cycles to +iterate through all dmabufs. However the dmabuf iterator currently +returns NULL in dmabuf_iter_seq_start for all non-zero pos values, which +results in the truncation of the output before all dmabufs are handled. + +After dma_buf_iter_begin / dma_buf_iter_next, the refcount of the buffer +is elevated so that the BPF iterator program can run without holding any +locks. When a stop occurs, instead of immediately dropping the reference +on the buffer, stash a pointer to the buffer in seq->priv until +either start is called or the iterator is released. This also enables +the resumption of iteration without first walking through the list of +dmabufs based on the pos value. + +Fixes: 76ea95534995 ("bpf: Add dmabuf iterator") +Signed-off-by: T.J. Mercier +Link: https://lore.kernel.org/r/20251204000348.1413593-1-tjmercier@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/dmabuf_iter.c | 56 +++++++++++++++++++++++++++++++++++----- + 1 file changed, 49 insertions(+), 7 deletions(-) + +diff --git a/kernel/bpf/dmabuf_iter.c b/kernel/bpf/dmabuf_iter.c +index 4dd7ef7c145ca..cd500248abd95 100644 +--- a/kernel/bpf/dmabuf_iter.c ++++ b/kernel/bpf/dmabuf_iter.c +@@ -6,10 +6,33 @@ + #include + #include + ++struct dmabuf_iter_priv { ++ /* ++ * If this pointer is non-NULL, the buffer's refcount is elevated to ++ * prevent destruction between stop/start. If reading is not resumed and ++ * start is never called again, then dmabuf_iter_seq_fini drops the ++ * reference when the iterator is released. ++ */ ++ struct dma_buf *dmabuf; ++}; ++ + static void *dmabuf_iter_seq_start(struct seq_file *seq, loff_t *pos) + { +- if (*pos) +- return NULL; ++ struct dmabuf_iter_priv *p = seq->private; ++ ++ if (*pos) { ++ struct dma_buf *dmabuf = p->dmabuf; ++ ++ if (!dmabuf) ++ return NULL; ++ ++ /* ++ * Always resume from where we stopped, regardless of the value ++ * of pos. ++ */ ++ p->dmabuf = NULL; ++ return dmabuf; ++ } + + return dma_buf_iter_begin(); + } +@@ -54,8 +77,11 @@ static void dmabuf_iter_seq_stop(struct seq_file *seq, void *v) + { + struct dma_buf *dmabuf = v; + +- if (dmabuf) +- dma_buf_put(dmabuf); ++ if (dmabuf) { ++ struct dmabuf_iter_priv *p = seq->private; ++ ++ p->dmabuf = dmabuf; ++ } + } + + static const struct seq_operations dmabuf_iter_seq_ops = { +@@ -71,11 +97,27 @@ static void bpf_iter_dmabuf_show_fdinfo(const struct bpf_iter_aux_info *aux, + seq_puts(seq, "dmabuf iter\n"); + } + ++static int dmabuf_iter_seq_init(void *priv, struct bpf_iter_aux_info *aux) ++{ ++ struct dmabuf_iter_priv *p = (struct dmabuf_iter_priv *)priv; ++ ++ p->dmabuf = NULL; ++ return 0; ++} ++ ++static void dmabuf_iter_seq_fini(void *priv) ++{ ++ struct dmabuf_iter_priv *p = (struct dmabuf_iter_priv *)priv; ++ ++ if (p->dmabuf) ++ dma_buf_put(p->dmabuf); ++} ++ + static const struct bpf_iter_seq_info dmabuf_iter_seq_info = { + .seq_ops = &dmabuf_iter_seq_ops, +- .init_seq_private = NULL, +- .fini_seq_private = NULL, +- .seq_priv_size = 0, ++ .init_seq_private = dmabuf_iter_seq_init, ++ .fini_seq_private = dmabuf_iter_seq_fini, ++ .seq_priv_size = sizeof(struct dmabuf_iter_priv), + }; + + static struct bpf_iter_reg bpf_dmabuf_reg_info = { +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-verifier-assumptions-of-bpf_d_path-s-output-.patch b/queue-6.18/bpf-fix-verifier-assumptions-of-bpf_d_path-s-output-.patch new file mode 100644 index 0000000000..67983739a3 --- /dev/null +++ b/queue-6.18/bpf-fix-verifier-assumptions-of-bpf_d_path-s-output-.patch @@ -0,0 +1,60 @@ +From 3deadd88adf6c205302caf829551a9ae7785ba6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Dec 2025 22:12:09 +0800 +Subject: bpf: Fix verifier assumptions of bpf_d_path's output buffer + +From: Shuran Liu + +[ Upstream commit ac44dcc788b950606793e8f9690c30925f59df02 ] + +Commit 37cce22dbd51 ("bpf: verifier: Refactor helper access type +tracking") started distinguishing read vs write accesses performed by +helpers. + +The second argument of bpf_d_path() is a pointer to a buffer that the +helper fills with the resulting path. However, its prototype currently +uses ARG_PTR_TO_MEM without MEM_WRITE. + +Before 37cce22dbd51, helper accesses were conservatively treated as +potential writes, so this mismatch did not cause issues. Since that +commit, the verifier may incorrectly assume that the buffer contents +are unchanged across the helper call and base its optimizations on this +wrong assumption. This can lead to misbehaviour in BPF programs that +read back the buffer, such as prefix comparisons on the returned path. + +Fix this by marking the second argument of bpf_d_path() as +ARG_PTR_TO_MEM | MEM_WRITE so that the verifier correctly models the +write to the caller-provided buffer. + +Fixes: 37cce22dbd51 ("bpf: verifier: Refactor helper access type tracking") +Co-developed-by: Zesen Liu +Signed-off-by: Zesen Liu +Co-developed-by: Peili Gao +Signed-off-by: Peili Gao +Co-developed-by: Haoran Ni +Signed-off-by: Haoran Ni +Signed-off-by: Shuran Liu +Reviewed-by: Matt Bobrowski +Link: https://lore.kernel.org/r/20251206141210.3148-2-electronlsr@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/trace/bpf_trace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index 4f87c16d915a0..49e0bdaa7a1bf 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -965,7 +965,7 @@ static const struct bpf_func_proto bpf_d_path_proto = { + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_BTF_ID, + .arg1_btf_id = &bpf_d_path_btf_ids[0], +- .arg2_type = ARG_PTR_TO_MEM, ++ .arg2_type = ARG_PTR_TO_MEM | MEM_WRITE, + .arg3_type = ARG_CONST_SIZE_OR_ZERO, + .allowed = bpf_d_path_allowed, + }; +-- +2.51.0 + diff --git a/queue-6.18/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch b/queue-6.18/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch new file mode 100644 index 0000000000..7486a6ba19 --- /dev/null +++ b/queue-6.18/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch @@ -0,0 +1,72 @@ +From b43c276ae508477a120ead98cc7781b7a17ed8b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 17:02:00 +0000 +Subject: btrfs: do not skip logging new dentries when logging a new name + +From: Filipe Manana + +[ Upstream commit 5630f7557de61264ccb4f031d4734a1a97eaed16 ] + +When we are logging a directory and the log context indicates that we +are logging a new name for some other file (that is or was inside that +directory), we skip logging the inodes for new dentries in the directory. + +This is ok most of the time, but if after the rename or link operation +that triggered the logging of that directory, we have an explicit fsync +of that directory without the directory inode being evicted and reloaded, +we end up never logging the inodes for the new dentries that we found +during the new name logging, as the next directory fsync will only process +dentries that were added after the last time we logged the directory (we +are doing an incremental directory logging). + +So make sure we always log new dentries for a directory even if we are +in a context of logging a new name. + +We started skipping logging inodes for new dentries as of commit +c48792c6ee7a ("btrfs: do not log new dentries when logging that a new name +exists") and it was fine back then, because when logging a directory we +always iterated over all the directory entries (for leaves changed in the +current transaction) so a subsequent fsync would always log anything that +was previously skipped while logging a directory when logging a new name +(with btrfs_log_new_name()). But later support for incrementally logging +a directory was added in commit dc2872247ec0 ("btrfs: keep track of the +last logged keys when logging a directory"), to avoid checking all dir +items every time we log a directory, so the check to skip dentry logging +added in the first commit should have been removed when the incremental +support for logging a directory was added. + +A test case for fstests will follow soon. + +Reported-by: Vyacheslav Kovalevsky +Link: https://lore.kernel.org/linux-btrfs/84c4e713-85d6-42b9-8dcf-0722ed26cb05@gmail.com/ +Fixes: dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory") +Reviewed-by: Boris Burkov +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tree-log.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 30f3c3b849c14..f55d886debe2f 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -5872,14 +5872,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, + struct btrfs_inode *curr_inode = start_inode; + int ret = 0; + +- /* +- * If we are logging a new name, as part of a link or rename operation, +- * don't bother logging new dentries, as we just want to log the names +- * of an inode and that any new parents exist. +- */ +- if (ctx->logging_new_name) +- return 0; +- + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.18/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch b/queue-6.18/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch new file mode 100644 index 0000000000..53ffab2dc3 --- /dev/null +++ b/queue-6.18/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch @@ -0,0 +1,49 @@ +From cd8f264d2ce8dfe2fccdd0678c9b60feb80448fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 18:49:56 +1030 +Subject: btrfs: fix a potential path leak in print_data_reloc_error() + +From: Qu Wenruo + +[ Upstream commit 313ef70a9f0f637a09d9ef45222f5bdcf30a354b ] + +Inside print_data_reloc_error(), if extent_from_logical() failed we +return immediately. + +However there are the following cases where extent_from_logical() can +return error but still holds a path: + +- btrfs_search_slot() returned 0 + +- No backref item found in extent tree + +- No flags_ret provided + This is not possible in this call site though. + +So for the above two cases, we can return without releasing the path, +causing extent buffer leaks. + +Fixes: b9a9a85059cd ("btrfs: output affected files when relocation fails") +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 6282911e536f0..51401d586a7b6 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -256,6 +256,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off + if (ret < 0) { + btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d", + logical, ret); ++ btrfs_release_path(&path); + return; + } + eb = path.nodes[0]; +-- +2.51.0 + diff --git a/queue-6.18/btrfs-fix-changeset-leak-on-mmap-write-after-failure.patch b/queue-6.18/btrfs-fix-changeset-leak-on-mmap-write-after-failure.patch new file mode 100644 index 0000000000..b6a9d85cd2 --- /dev/null +++ b/queue-6.18/btrfs-fix-changeset-leak-on-mmap-write-after-failure.patch @@ -0,0 +1,51 @@ +From e534053528ec26f026e86bf63800695e5c3ad748 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Dec 2025 11:51:19 +0000 +Subject: btrfs: fix changeset leak on mmap write after failure to reserve + metadata + +From: Filipe Manana + +[ Upstream commit 37343524f000d2a64359867d7024a73233d3b438 ] + +If the call to btrfs_delalloc_reserve_metadata() fails we jump to the +'out_noreserve' label and there we never free the extent_changeset +allocated by the previous call to btrfs_check_data_free_space() (if +qgroups are enabled). Fix this by calling extent_changeset_free() under +the 'out_noreserve' label. + +Fixes: 6599716de2d6 ("btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents") +Reported-by: syzbot+2f8aa76e6acc9fce6638@syzkaller.appspotmail.com +Link: https://lore.kernel.org/linux-btrfs/693a635a.a70a0220.33cd7b.0029.GAE@google.com/ +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/file.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index fa82def46e395..0fee45d35a5f8 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -2018,13 +2018,14 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) + else + btrfs_delalloc_release_space(inode, data_reserved, page_start, + reserved_space, true); +- extent_changeset_free(data_reserved); + out_noreserve: + if (only_release_metadata) + btrfs_check_nocow_unlock(inode); + + sb_end_pagefault(inode->vfs_inode.i_sb); + ++ extent_changeset_free(data_reserved); ++ + if (ret < 0) + return vmf_error(ret); + +-- +2.51.0 + diff --git a/queue-6.18/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch b/queue-6.18/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch new file mode 100644 index 0000000000..82b245c1d5 --- /dev/null +++ b/queue-6.18/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch @@ -0,0 +1,51 @@ +From b6b54bb3f74df09e7df8ea7c4f8a5e62e65f13b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 18:58:07 +0530 +Subject: btrfs: fix memory leak of fs_devices in degraded seed device path + +From: Deepanshu Kartikey + +[ Upstream commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 ] + +In open_seed_devices(), when find_fsid() fails and we're in DEGRADED +mode, a new fs_devices is allocated via alloc_fs_devices() but is never +added to the seed_list before returning. This contrasts with the normal +path where fs_devices is properly added via list_add(). + +If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), +the cleanup code iterates seed_list to free seed devices, but this +orphaned fs_devices is never found and never freed, causing a memory +leak. Any devices allocated via add_missing_dev() and attached to this +fs_devices are also leaked. + +Fix this by adding the newly allocated fs_devices to seed_list in the +degraded path, consistent with the normal path. + +Fixes: 5f37583569442 ("Btrfs: move the missing device to its own fs device list") +Reported-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=eadd98df8bceb15d7fed +Tested-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Reviewed-by: Qu Wenruo +Signed-off-by: Deepanshu Kartikey +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/volumes.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 2bec544d8ba30..48e717c105c35 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -7178,6 +7178,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, + + fs_devices->seeding = true; + fs_devices->opened = 1; ++ list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); + return fs_devices; + } + +-- +2.51.0 + diff --git a/queue-6.18/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch b/queue-6.18/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch new file mode 100644 index 0000000000..4182e3fd11 --- /dev/null +++ b/queue-6.18/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch @@ -0,0 +1,90 @@ +From 8c17738d240482b4267877d4e1eaeecff1e2737c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 12:51:09 +1030 +Subject: btrfs: scrub: always update btrfs_scrub_progress::last_physical + +From: Qu Wenruo + +[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ] + +[BUG] +When a scrub failed immediately without any byte scrubbed, the returned +btrfs_scrub_progress::last_physical will always be 0, even if there is a +non-zero @start passed into btrfs_scrub_dev() for resume cases. + +This will reset the progress and make later scrub resume start from the +beginning. + +[CAUSE] +The function btrfs_scrub_dev() accepts a @progress parameter to copy its +updated progress to the caller, there are cases where we either don't +touch progress::last_physical at all or copy 0 into last_physical: + +- last_physical not updated at all + If some error happened before scrubbing any super block or chunk, we + will not copy the progress, leaving the @last_physical untouched. + + E.g. failed to allocate @sctx, scrubbing a missing device or even + there is already a running scrub and so on. + + All those cases won't touch @progress at all, resulting the + last_physical untouched and will be left as 0 for most cases. + +- Error out before scrubbing any bytes + In those case we allocated @sctx, and sctx->stat.last_physical is all + zero (initialized by kvzalloc()). + Unfortunately some critical errors happened during + scrub_enumerate_chunks() or scrub_supers() before any stripe is really + scrubbed. + + In that case although we will copy sctx->stat back to @progress, since + no byte is really scrubbed, last_physical will be overwritten to 0. + +[FIX] +Make sure the parameter @progress always has its @last_physical member +updated to @start parameter inside btrfs_scrub_dev(). + +At the very beginning of the function, set @progress->last_physical to +@start, so that even if we error out without doing progress copying, +last_physical is still at @start. + +Then after we got @sctx allocated, set sctx->stat.last_physical to +@start, this will make sure even if we didn't get any byte scrubbed, at +the progress copying stage the @last_physical is not left as zero. + +This should resolve the resume progress reset problem. + +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index 65361af302343..b6a7ea105eb13 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -3039,6 +3039,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + unsigned int nofs_flag; + bool need_commit = false; + ++ /* Set the basic fallback @last_physical before we got a sctx. */ ++ if (progress) ++ progress->last_physical = start; ++ + if (btrfs_fs_closing(fs_info)) + return -EAGAIN; + +@@ -3057,6 +3061,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + sctx = scrub_setup_ctx(fs_info, is_dev_replace); + if (IS_ERR(sctx)) + return PTR_ERR(sctx); ++ sctx->stat.last_physical = start; + + ret = scrub_workers_get(fs_info); + if (ret) +-- +2.51.0 + diff --git a/queue-6.18/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch b/queue-6.18/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch new file mode 100644 index 0000000000..58150d0313 --- /dev/null +++ b/queue-6.18/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch @@ -0,0 +1,35 @@ +From f922a9b37397e7db449e3fa61c33c542ad783f87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 16:00:48 +0800 +Subject: cpufreq: dt-platdev: Add JH7110S SOC to the allowlist + +From: Hal Feng + +[ Upstream commit 6e7970cab51d01b8f7c56f120486c571c22e1b80 ] + +Add the compatible strings for supporting the generic +cpufreq driver on the StarFive JH7110S SoC. + +Signed-off-by: Hal Feng +Reviewed-by: Heinrich Schuchardt +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index cd1816a12bb99..dc11b62399ad5 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -87,6 +87,7 @@ static const struct of_device_id allowlist[] __initconst = { + { .compatible = "st-ericsson,u9540", }, + + { .compatible = "starfive,jh7110", }, ++ { .compatible = "starfive,jh7110s", }, + + { .compatible = "ti,omap2", }, + { .compatible = "ti,omap4", }, +-- +2.51.0 + diff --git a/queue-6.18/cpufreq-s5pv210-fix-refcount-leak.patch b/queue-6.18/cpufreq-s5pv210-fix-refcount-leak.patch new file mode 100644 index 0000000000..3b0a3f1e0e --- /dev/null +++ b/queue-6.18/cpufreq-s5pv210-fix-refcount-leak.patch @@ -0,0 +1,62 @@ +From f50fcf00ce4e16345fc8f831e9aa846a5e191a37 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 03:31:17 +0800 +Subject: cpufreq: s5pv210: fix refcount leak + +From: Shuhao Fu + +[ Upstream commit 2de5cb96060a1664880d65b120e59485a73588a8 ] + +In function `s5pv210_cpu_init`, a possible refcount inconsistency has +been identified, causing a resource leak. + +Why it is a bug: +1. For every clk_get, there should be a matching clk_put on every +successive error handling path. +2. After calling `clk_get(dmc1_clk)`, variable `dmc1_clk` will not be +freed even if any error happens. + +How it is fixed: For every failed path, an extra goto label is added to +ensure `dmc1_clk` will be freed regardlessly. + +Signed-off-by: Shuhao Fu +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c +index 4215621deb3fe..ba8a1c96427a1 100644 +--- a/drivers/cpufreq/s5pv210-cpufreq.c ++++ b/drivers/cpufreq/s5pv210-cpufreq.c +@@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + + if (policy->cpu != 0) { + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* +@@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { + pr_err("CPUFreq doesn't support this memory type\n"); + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* Find current refresh counter and frequency each DMC */ +@@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + cpufreq_generic_init(policy, s5pv210_freq_table, 40000); + return 0; + ++out: ++ clk_put(dmc1_clk); + out_dmc1: + clk_put(dmc0_clk); + out_dmc0: +-- +2.51.0 + diff --git a/queue-6.18/cpuidle-menu-use-residency-threshold-in-polling-stat.patch b/queue-6.18/cpuidle-menu-use-residency-threshold-in-polling-stat.patch new file mode 100644 index 0000000000..877fe03177 --- /dev/null +++ b/queue-6.18/cpuidle-menu-use-residency-threshold-in-polling-stat.patch @@ -0,0 +1,99 @@ +From 058a2f940eee2f9ee67065bfb3b45472ced1b3a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 07:09:54 +0530 +Subject: cpuidle: menu: Use residency threshold in polling state override + decisions + +From: Aboorva Devarajan + +[ Upstream commit 07d815701274d156ad8c7c088a52e01642156fb8 ] + +On virtualized PowerPC (pseries) systems, where only one polling state +(Snooze) and one deep state (CEDE) are available, selecting CEDE when +the predicted idle duration is less than the target residency of CEDE +state can hurt performance. In such cases, the entry/exit overhead of +CEDE outweighs the power savings, leading to unnecessary state +transitions and higher latency. + +Menu governor currently contains a special-case rule that prioritizes +the first non-polling state over polling, even when its target residency +is much longer than the predicted idle duration. On PowerPC/pseries, +where the gap between the polling state (Snooze) and the first non-polling +state (CEDE) is large, this behavior causes performance regressions. + +Refine that special case by adding an extra requirement: the first +non-polling state can only be chosen if its target residency is below +the defined RESIDENCY_THRESHOLD_NS. If this condition is not satisfied, +polling is allowed instead, avoiding suboptimal non-polling state +entries. + +This change is limited to the single special-case rule for the first +non-polling state. The general non-polling state selection logic in the +menu governor remains unchanged. + +Performance improvement observed with pgbench on PowerPC (pseries) +system: ++---------------------------+------------+------------+------------+ +| Metric | Baseline | Patched | Change (%) | ++---------------------------+------------+------------+------------+ +| Transactions/sec (TPS) | 495,210 | 536,982 | +8.45% | +| Avg latency (ms) | 0.163 | 0.150 | -7.98% | ++---------------------------+------------+------------+------------+ + +CPUIdle state usage: ++--------------+--------------+-------------+ +| Metric | Baseline | Patched | ++--------------+--------------+-------------+ +| Total usage | 12,735,820 | 13,918,442 | +| Above usage | 11,401,520 | 1,598,210 | +| Below usage | 20,145 | 702,395 | ++--------------+--------------+-------------+ + +Above/Total and Below/Total usage percentages: ++------------------------+-----------+---------+ +| Metric | Baseline | Patched | ++------------------------+-----------+---------+ +| Above % (Above/Total) | 89.56% | 11.49% | +| Below % (Below/Total) | 0.16% | 5.05% | +| Total cpuidle miss (%) | 89.72% | 16.54% | ++------------------------+-----------+---------+ + +The results indicate that restricting CEDE selection to cases where +its residency matches the predicted idle time reduces mispredictions, +lowers unnecessary state transitions, and improves overall throughput. + +Reviewed-by: Christian Loehle +Signed-off-by: Aboorva Devarajan +[ rjw: Changelog edits, rebase ] +Link: https://patch.msgid.link/20251006013954.17972-1-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/governors/menu.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index 23239b0c04f95..64d6f7a1c7766 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -317,12 +317,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + } + + /* +- * Use a physical idle state, not busy polling, unless a timer +- * is going to trigger soon enough or the exit latency of the +- * idle state in question is greater than the predicted idle +- * duration. ++ * Use a physical idle state instead of busy polling so long as ++ * its target residency is below the residency threshold, its ++ * exit latency is not greater than the predicted idle duration, ++ * and the next timer doesn't expire soon. + */ + if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && ++ s->target_residency_ns < RESIDENCY_THRESHOLD_NS && + s->target_residency_ns <= data->next_timer_ns && + s->exit_latency_ns <= predicted_ns) { + predicted_ns = s->target_residency_ns; +-- +2.51.0 + diff --git a/queue-6.18/crypto-ccp-add-support-for-pci-device-0x115a.patch b/queue-6.18/crypto-ccp-add-support-for-pci-device-0x115a.patch new file mode 100644 index 0000000000..fcd012214b --- /dev/null +++ b/queue-6.18/crypto-ccp-add-support-for-pci-device-0x115a.patch @@ -0,0 +1,67 @@ +From 3edb1d604bd5cef9e79fef579d0170092f1b8adc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:15:01 -0500 +Subject: crypto: ccp - Add support for PCI device 0x115A + +From: Mario Limonciello (AMD) + +[ Upstream commit 9fc6290117259a8dbf8247cb54559df62fd1550f ] + +PCI device 0x115A is similar to pspv5, except it doesn't have platform +access mailbox support. + +Signed-off-by: Mario Limonciello (AMD) +Acked-by: Tom Lendacky +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccp/sp-pci.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c +index e7bb803912a6d..8891ceee1d7d0 100644 +--- a/drivers/crypto/ccp/sp-pci.c ++++ b/drivers/crypto/ccp/sp-pci.c +@@ -459,6 +459,17 @@ static const struct psp_vdata pspv6 = { + .intsts_reg = 0x10514, /* P2CMSG_INTSTS */ + }; + ++static const struct psp_vdata pspv7 = { ++ .tee = &teev2, ++ .cmdresp_reg = 0x10944, /* C2PMSG_17 */ ++ .cmdbuff_addr_lo_reg = 0x10948, /* C2PMSG_18 */ ++ .cmdbuff_addr_hi_reg = 0x1094c, /* C2PMSG_19 */ ++ .bootloader_info_reg = 0x109ec, /* C2PMSG_59 */ ++ .feature_reg = 0x109fc, /* C2PMSG_63 */ ++ .inten_reg = 0x10510, /* P2CMSG_INTEN */ ++ .intsts_reg = 0x10514, /* P2CMSG_INTSTS */ ++}; ++ + #endif + + static const struct sp_dev_vdata dev_vdata[] = { +@@ -525,6 +536,13 @@ static const struct sp_dev_vdata dev_vdata[] = { + .psp_vdata = &pspv6, + #endif + }, ++ { /* 9 */ ++ .bar = 2, ++#ifdef CONFIG_CRYPTO_DEV_SP_PSP ++ .psp_vdata = &pspv7, ++#endif ++ }, ++ + }; + static const struct pci_device_id sp_pci_table[] = { + { PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] }, +@@ -539,6 +557,7 @@ static const struct pci_device_id sp_pci_table[] = { + { PCI_VDEVICE(AMD, 0x17E0), (kernel_ulong_t)&dev_vdata[7] }, + { PCI_VDEVICE(AMD, 0x156E), (kernel_ulong_t)&dev_vdata[8] }, + { PCI_VDEVICE(AMD, 0x17D8), (kernel_ulong_t)&dev_vdata[8] }, ++ { PCI_VDEVICE(AMD, 0x115A), (kernel_ulong_t)&dev_vdata[9] }, + /* Last entry must be zero */ + { 0, } + }; +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-check-for-shutdown-in-fsync.patch b/queue-6.18/fs-ntfs3-check-for-shutdown-in-fsync.patch new file mode 100644 index 0000000000..ef388d8e03 --- /dev/null +++ b/queue-6.18/fs-ntfs3-check-for-shutdown-in-fsync.patch @@ -0,0 +1,53 @@ +From 8a67956ba273301f8c4d2e9d5cd74db194d8d26a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 16:17:19 +0300 +Subject: fs/ntfs3: check for shutdown in fsync + +From: Konstantin Komarov + +[ Upstream commit 1b2ae190ea43bebb8c73d21f076addc8a8c71849 ] + +Ensure fsync() returns -EIO when the ntfs3 filesystem is in forced +shutdown, instead of silently succeeding via generic_file_fsync(). + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 4c90ec2fa2eae..83f0072f0896c 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -1375,6 +1375,18 @@ static ssize_t ntfs_file_splice_write(struct pipe_inode_info *pipe, + return iter_file_splice_write(pipe, file, ppos, len, flags); + } + ++/* ++ * ntfs_file_fsync - file_operations::fsync ++ */ ++static int ntfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) ++{ ++ struct inode *inode = file_inode(file); ++ if (unlikely(ntfs3_forced_shutdown(inode->i_sb))) ++ return -EIO; ++ ++ return generic_file_fsync(file, start, end, datasync); ++} ++ + // clang-format off + const struct inode_operations ntfs_file_inode_operations = { + .getattr = ntfs_getattr, +@@ -1397,7 +1409,7 @@ const struct file_operations ntfs_file_operations = { + .splice_write = ntfs_file_splice_write, + .mmap_prepare = ntfs_file_mmap_prepare, + .open = ntfs_file_open, +- .fsync = generic_file_fsync, ++ .fsync = ntfs_file_fsync, + .fallocate = ntfs_fallocate, + .release = ntfs_file_release, + }; +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-support-timestamps-prior-to-epoch.patch b/queue-6.18/fs-ntfs3-support-timestamps-prior-to-epoch.patch new file mode 100644 index 0000000000..84aa701620 --- /dev/null +++ b/queue-6.18/fs-ntfs3-support-timestamps-prior-to-epoch.patch @@ -0,0 +1,43 @@ +From 83ad8327f39ccccf9a9a27502f2a5ad4a3c56f96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Sep 2025 11:48:48 +0300 +Subject: fs/ntfs3: Support timestamps prior to epoch + +From: Konstantin Komarov + +[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ] + +Before it used an unsigned 64-bit type, which prevented proper handling +of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to +support pre-epoch timestamps. The issue was caught by xfstests. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/ntfs_fs.h | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index 630128716ea73..2649fbe16669d 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -979,11 +979,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts) + */ + static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) + { +- u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; ++ s32 t32; ++ /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ ++ s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; + +- // WARNING: do_div changes its first argument(!) +- ts->tv_nsec = do_div(t, _100ns2seconds) * 100; +- ts->tv_sec = t; ++ ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); ++ ts->tv_nsec = t32 * 100; + } + + static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb) +-- +2.51.0 + diff --git a/queue-6.18/gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch b/queue-6.18/gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch new file mode 100644 index 0000000000..9a823c01ac --- /dev/null +++ b/queue-6.18/gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch @@ -0,0 +1,38 @@ +From c4ca6a0738d12db1e39c0d6871142159f1090974 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 23:27:14 +0000 +Subject: gfs2: Fix "gfs2: Switch to wait_event in gfs2_quotad" + +From: Andreas Gruenbacher + +[ Upstream commit dff1fb6d8b7abe5b1119fa060f5d6b3370bf10ac ] + +Commit e4a8b5481c59a ("gfs2: Switch to wait_event in gfs2_quotad") broke +cyclic statfs syncing, so the numbers reported by "df" could easily get +completely out of sync with reality. Fix this by reverting part of +commit e4a8b5481c59a for now. + +A follow-up commit will clean this code up later. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/quota.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c +index 2298e06797ac3..f2df01f801b81 100644 +--- a/fs/gfs2/quota.c ++++ b/fs/gfs2/quota.c +@@ -1616,7 +1616,7 @@ int gfs2_quotad(void *data) + + t = min(quotad_timeo, statfs_timeo); + +- t = wait_event_freezable_timeout(sdp->sd_quota_wait, ++ t -= wait_event_freezable_timeout(sdp->sd_quota_wait, + sdp->sd_statfs_force_sync || + gfs2_withdrawing_or_withdrawn(sdp) || + kthread_should_stop(), +-- +2.51.0 + diff --git a/queue-6.18/gfs2-fix-remote-evict-for-read-only-filesystems.patch b/queue-6.18/gfs2-fix-remote-evict-for-read-only-filesystems.patch new file mode 100644 index 0000000000..cc6fbb30a2 --- /dev/null +++ b/queue-6.18/gfs2-fix-remote-evict-for-read-only-filesystems.patch @@ -0,0 +1,41 @@ +From d6db7ca6d0c51516500f2e038373c65913765e17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 12:14:24 +0000 +Subject: gfs2: fix remote evict for read-only filesystems + +From: Andreas Gruenbacher + +[ Upstream commit 64c10ed9274bc46416f502afea48b4ae11279669 ] + +When a node tries to delete an inode, it first requests exclusive access +to the iopen glock. This triggers demote requests on all remote nodes +currently holding the iopen glock. To satisfy those requests, the +remote nodes evict the inode in question, or they poke the corresponding +inode glock to signal that the inode is still in active use. + +This behavior doesn't depend on whether or not a filesystem is +read-only, so remove the incorrect read-only check. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/glops.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c +index 0c0a80b3bacab..0c68ab4432b08 100644 +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -630,8 +630,7 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote) + struct gfs2_inode *ip = gl->gl_object; + struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; + +- if (!remote || sb_rdonly(sdp->sd_vfs) || +- test_bit(SDF_KILL, &sdp->sd_flags)) ++ if (!remote || test_bit(SDF_KILL, &sdp->sd_flags)) + return; + + if (gl->gl_demote_state == LM_ST_UNLOCKED && +-- +2.51.0 + diff --git a/queue-6.18/gfs2-fix-use-of-bio_chain.patch b/queue-6.18/gfs2-fix-use-of-bio_chain.patch new file mode 100644 index 0000000000..4203df19e7 --- /dev/null +++ b/queue-6.18/gfs2-fix-use-of-bio_chain.patch @@ -0,0 +1,37 @@ +From 42bb4e2a7e538a42e07c35ecd4b0eec0c60003e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 21:19:52 +0000 +Subject: gfs2: Fix use of bio_chain + +From: Andreas Gruenbacher + +[ Upstream commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941 ] + +In gfs2_chain_bio(), the call to bio_chain() has its arguments swapped. +The result is leaked bios and incorrect synchronization (only the last +bio will actually be waited for). This code is only used during mount +and filesystem thaw, so the bug normally won't be noticeable. + +Reported-by: Stephen Zhang +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/lops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c +index 9c8c305a75c46..914d03f6c4e82 100644 +--- a/fs/gfs2/lops.c ++++ b/fs/gfs2/lops.c +@@ -487,7 +487,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) + new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); + bio_clone_blkg_association(new, prev); + new->bi_iter.bi_sector = bio_end_sector(prev); +- bio_chain(new, prev); ++ bio_chain(prev, new); + submit_bio(prev); + return new; + } +-- +2.51.0 + diff --git a/queue-6.18/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch b/queue-6.18/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch new file mode 100644 index 0000000000..ea39a18f61 --- /dev/null +++ b/queue-6.18/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch @@ -0,0 +1,91 @@ +From ba5ccea5ccf999ea068140f5346e5079eb39919f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 17:39:12 +0800 +Subject: hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create + +From: Yang Chenzhi + +[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ] + +When sync() and link() are called concurrently, both threads may +enter hfs_bnode_find() without finding the node in the hash table +and proceed to create it. + +Thread A: + hfsplus_write_inode() + -> hfsplus_write_system_inode() + -> hfs_btree_write() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +Thread B: + hfsplus_create_cat() + -> hfs_brec_insert() + -> hfs_bnode_split() + -> hfs_bmap_alloc() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +In this case, thread A creates the bnode, sets refcnt=1, and hashes it. +Thread B also tries to create the same bnode, notices it has already +been inserted, drops its own instance, and uses the hashed one without +getting the node. + +``` + + node2 = hfs_bnode_findhash(tree, cnid); + if (!node2) { <- Thread A + hash = hfs_bnode_hash(cnid); + node->next_hash = tree->node_hash[hash]; + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { <- Thread B + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, + !test_bit(HFS_BNODE_NEW, &node2->flags)); + return node2; + } +``` + +However, hfs_bnode_find() requires each call to take a reference. +Here both threads end up setting refcnt=1. When they later put the node, +this triggers: + +BUG_ON(!atomic_read(&node->refcnt)) + +In this scenario, Thread B in fact finds the node in the hash table +rather than creating a new one, and thus must take a reference. + +Fix this by calling hfs_bnode_get() when reusing a bnode newly created by +another thread to ensure the refcount is updated correctly. + +A similar bug was fixed in HFS long ago in commit +a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") +but the same issue remained in HFS+ until now. + +Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com +Signed-off-by: Yang Chenzhi +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index edf7e27e1e375..482a6c5faa197 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -481,6 +481,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { ++ hfs_bnode_get(node2); + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, +-- +2.51.0 + diff --git a/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-070.patch b/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-070.patch new file mode 100644 index 0000000000..fb31e6bf9b --- /dev/null +++ b/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-070.patch @@ -0,0 +1,122 @@ +From edc3df90aae399e2281126e1e4249fcc7c7ef606 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:12:30 -0700 +Subject: hfsplus: fix volume corruption issue for generic/070 + +From: Viacheslav Dubeyko + +[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ] + +The xfstests' test-case generic/070 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent +(see xfstests-dev/results//generic/070.full for details) + +Ran: generic/070 +Failures: generic/070 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop50 +** /dev/loop50 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +Unused node is not erased (node = 1) +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 +CBTStat = 0x0000 CatStat = 0x00000000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume test was repaired successfully. + +It is possible to see that fsck.hfsplus detected not +erased and unused node for the case of extents overflow file. +The HFS+ logic has special method that defines if the node +should be erased: + +bool hfs_bnode_need_zeroout(struct hfs_btree *tree) +{ + struct super_block *sb = tree->inode->i_sb; + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + + return tree->cnid == HFSPLUS_CAT_CNID && + volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; +} + +However, it is possible to see that this method works +only for the case of catalog file. But debugging of the issue +has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been +requested for the extents overflow file too: + +catalog file +kernel: hfsplus: node 4, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800 + +extents overflow file +kernel: hfsplus: node 1, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800 + +This patch modifies the hfs_bnode_need_zeroout() by checking +only volume_attr but not the b-tree ID because node zeroing +can be requested for all HFS+ b-tree types. + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 33s ... 34s +Ran: generic/070 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index 63e652ad1e0de..edf7e27e1e375 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -704,6 +704,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + +- return tree->cnid == HFSPLUS_CAT_CNID && +- volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; ++ return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + } +-- +2.51.0 + diff --git a/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-073.patch b/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-073.patch new file mode 100644 index 0000000000..2c383fcc8c --- /dev/null +++ b/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-073.patch @@ -0,0 +1,125 @@ +From 2d9a9d046903ec814d77cdce9029f5d29d5b9eb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:25:23 -0800 +Subject: hfsplus: fix volume corruption issue for generic/073 + +From: Viacheslav Dubeyko + +[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ] + +The xfstests' test-case generic/073 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent +(see XFSTESTS-2/xfstests-dev/results//generic/073.full for details) + +Ran: generic/073 +Failures: generic/073 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +Invalid directory item count +(It should be 1 instead of 0) +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 +CBTStat = 0x0000 CatStat = 0x00004000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled was repaired successfully. + +The test is doing these steps on final phase: + +mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo + +So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ +logic decrements the number of entries in testdir_1 and increments number of +entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not +for testdir_2. As a result, this is the reason why fsck.hfsplus detects the +volume corruption afterwards. + +This patch fixes the issue by means of adding the +hfsplus_cat_write_inode() call for old_dir and new_dir in +hfsplus_rename() after the successful ending of +hfsplus_rename_cat(). This method makes modification of in-core +inode objects for old_dir and new_dir but it doesn't save these +modifications in Catalog File's entries. It was expected that +hfsplus_write_inode() will save these modifications afterwards. +However, because generic/073 does fsync only for testdir_1 and foo +then testdir_2 modification hasn't beed saved into Catalog File's +entry and it was flushed without this modification. And it was +detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog +File all modified entries and correct state of Catalog File will +be flushed during hfsplus_file_fsync() call. Finally, it makes +fsck.hfsplus happy. + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 32s ... 32s +Ran: generic/073 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/dir.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c +index 1b3e27a0d5e03..cadf0b5f93422 100644 +--- a/fs/hfsplus/dir.c ++++ b/fs/hfsplus/dir.c +@@ -552,8 +552,13 @@ static int hfsplus_rename(struct mnt_idmap *idmap, + res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, + old_dir, &old_dentry->d_name, + new_dir, &new_dentry->d_name); +- if (!res) ++ if (!res) { + new_dentry->d_fsdata = old_dentry->d_fsdata; ++ ++ res = hfsplus_cat_write_inode(old_dir); ++ if (!res) ++ res = hfsplus_cat_write_inode(new_dir); ++ } + return res; + } + +-- +2.51.0 + diff --git a/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-101.patch b/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-101.patch new file mode 100644 index 0000000000..7aafb313c5 --- /dev/null +++ b/queue-6.18/hfsplus-fix-volume-corruption-issue-for-generic-101.patch @@ -0,0 +1,281 @@ +From c22520adf4330594110889c7b889a3d0dbb22a02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:32:20 -0800 +Subject: hfsplus: fix volume corruption issue for generic/101 + +From: Viacheslav Dubeyko + +[ Upstream commit 3f04ee216bc1406cb6214ceaa7e544114108e0fa ] + +The xfstests' test-case generic/101 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/101 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/101 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent +(see XFSTESTS-2/xfstests-dev/results//generic/101.full for details) + +Ran: generic/101 +Failures: generic/101 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Invalid volume free block count +(It should be 2614350 instead of 2614382) +Verify Status: VIStat = 0x8000, ABTStat = 0x0000 EBTStat = 0x0000 +CBTStat = 0x0000 CatStat = 0x00000000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled was repaired successfully. + +This test executes such steps: "Test that if we truncate a file +to a smaller size, then truncate it to its original size or +a larger size, then fsyncing it and a power failure happens, +the file will have the range [first_truncate_size, last_size[ with +all bytes having a value of 0x00 if we read it the next time +the filesystem is mounted.". + +HFS+ keeps volume's free block count in the superblock. +However, hfsplus_file_fsync() doesn't store superblock's +content. As a result, superblock contains not correct +value of free blocks if a power failure happens. + +This patch adds functionality of saving superblock's +content during hfsplus_file_fsync() call. + +sudo ./check generic/101 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #96 SMP PREEMPT_DYNAMIC Wed Nov 19 12:47:37 PST 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/101 32s ... 30s +Ran: generic/101 +Passed all 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 + Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. + Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. + The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled appears to be OK. + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251119223219.1824434-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/hfsplus_fs.h | 2 + + fs/hfsplus/inode.c | 9 +++++ + fs/hfsplus/super.c | 87 +++++++++++++++++++++++++---------------- + 3 files changed, 65 insertions(+), 33 deletions(-) + +diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h +index 89e8b19c127b0..de801942ae471 100644 +--- a/fs/hfsplus/hfsplus_fs.h ++++ b/fs/hfsplus/hfsplus_fs.h +@@ -477,6 +477,8 @@ int hfs_part_find(struct super_block *sb, sector_t *part_start, + /* super.c */ + struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino); + void hfsplus_mark_mdb_dirty(struct super_block *sb); ++void hfsplus_prepare_volume_header_for_commit(struct hfsplus_vh *vhdr); ++int hfsplus_commit_superblock(struct super_block *sb); + + /* tables.c */ + extern u16 hfsplus_case_fold_table[]; +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index e290e417ed3a7..7ae6745ca7ae1 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -325,6 +325,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, + struct inode *inode = file->f_mapping->host; + struct hfsplus_inode_info *hip = HFSPLUS_I(inode); + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); ++ struct hfsplus_vh *vhdr = sbi->s_vhdr; + int error = 0, error2; + + error = file_write_and_wait_range(file, start, end); +@@ -368,6 +369,14 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, + error = error2; + } + ++ mutex_lock(&sbi->vh_mutex); ++ hfsplus_prepare_volume_header_for_commit(vhdr); ++ mutex_unlock(&sbi->vh_mutex); ++ ++ error2 = hfsplus_commit_superblock(inode->i_sb); ++ if (!error) ++ error = error2; ++ + if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) + blkdev_issue_flush(inode->i_sb->s_bdev); + +diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c +index 16bc4abc67e08..67a7a2a093476 100644 +--- a/fs/hfsplus/super.c ++++ b/fs/hfsplus/super.c +@@ -187,40 +187,15 @@ static void hfsplus_evict_inode(struct inode *inode) + } + } + +-static int hfsplus_sync_fs(struct super_block *sb, int wait) ++int hfsplus_commit_superblock(struct super_block *sb) + { + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + struct hfsplus_vh *vhdr = sbi->s_vhdr; + int write_backup = 0; +- int error, error2; +- +- if (!wait) +- return 0; ++ int error = 0, error2; + + hfs_dbg("starting...\n"); + +- /* +- * Explicitly write out the special metadata inodes. +- * +- * While these special inodes are marked as hashed and written +- * out peridocically by the flusher threads we redirty them +- * during writeout of normal inodes, and thus the life lock +- * prevents us from getting the latest state to disk. +- */ +- error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); +- error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); +- if (!error) +- error = error2; +- if (sbi->attr_tree) { +- error2 = +- filemap_write_and_wait(sbi->attr_tree->inode->i_mapping); +- if (!error) +- error = error2; +- } +- error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); +- if (!error) +- error = error2; +- + mutex_lock(&sbi->vh_mutex); + mutex_lock(&sbi->alloc_mutex); + vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); +@@ -249,11 +224,52 @@ static int hfsplus_sync_fs(struct super_block *sb, int wait) + sbi->part_start + sbi->sect_count - 2, + sbi->s_backup_vhdr_buf, NULL, REQ_OP_WRITE); + if (!error) +- error2 = error; ++ error = error2; + out: + mutex_unlock(&sbi->alloc_mutex); + mutex_unlock(&sbi->vh_mutex); + ++ hfs_dbg("finished: err %d\n", error); ++ ++ return error; ++} ++ ++static int hfsplus_sync_fs(struct super_block *sb, int wait) ++{ ++ struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); ++ int error, error2; ++ ++ if (!wait) ++ return 0; ++ ++ hfs_dbg("starting...\n"); ++ ++ /* ++ * Explicitly write out the special metadata inodes. ++ * ++ * While these special inodes are marked as hashed and written ++ * out peridocically by the flusher threads we redirty them ++ * during writeout of normal inodes, and thus the life lock ++ * prevents us from getting the latest state to disk. ++ */ ++ error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); ++ error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); ++ if (!error) ++ error = error2; ++ if (sbi->attr_tree) { ++ error2 = ++ filemap_write_and_wait(sbi->attr_tree->inode->i_mapping); ++ if (!error) ++ error = error2; ++ } ++ error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); ++ if (!error) ++ error = error2; ++ ++ error2 = hfsplus_commit_superblock(sb); ++ if (!error) ++ error = error2; ++ + if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) + blkdev_issue_flush(sb->s_bdev); + +@@ -395,6 +411,15 @@ static const struct super_operations hfsplus_sops = { + .show_options = hfsplus_show_options, + }; + ++void hfsplus_prepare_volume_header_for_commit(struct hfsplus_vh *vhdr) ++{ ++ vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); ++ vhdr->modify_date = hfsp_now2mt(); ++ be32_add_cpu(&vhdr->write_count, 1); ++ vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); ++ vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); ++} ++ + static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc) + { + struct hfsplus_vh *vhdr; +@@ -562,11 +587,7 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc) + * H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused + * all three are registered with Apple for our use + */ +- vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); +- vhdr->modify_date = hfsp_now2mt(); +- be32_add_cpu(&vhdr->write_count, 1); +- vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); +- vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); ++ hfsplus_prepare_volume_header_for_commit(vhdr); + hfsplus_sync_fs(sb, 1); + + if (!sbi->hidden_dir) { +-- +2.51.0 + diff --git a/queue-6.18/hfsplus-verify-inode-mode-when-loading-from-disk.patch b/queue-6.18/hfsplus-verify-inode-mode-when-loading-from-disk.patch new file mode 100644 index 0000000000..42afc25a92 --- /dev/null +++ b/queue-6.18/hfsplus-verify-inode-mode-when-loading-from-disk.patch @@ -0,0 +1,105 @@ +From 2ee0320b14b81be1799cd8a520da171e421a52bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 18:18:54 +0900 +Subject: hfsplus: Verify inode mode when loading from disk + +From: Tetsuo Handa + +[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ] + +syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when +the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted. + +According to [1], the permissions field was treated as reserved in Mac OS +8 and 9. According to [2], the reserved field was explicitly initialized +with 0, and that field must remain 0 as long as reserved. Therefore, when +the "mode" field is not 0 (i.e. no longer reserved), the file must be +S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ +S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlusPermissions [1] +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#ReservedAndPadFields [2] +Signed-off-by: Tetsuo Handa +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA.ne.jp +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index b51a411ecd237..e290e417ed3a7 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -180,13 +180,29 @@ const struct dentry_operations hfsplus_dentry_operations = { + .d_compare = hfsplus_compare_dentry, + }; + +-static void hfsplus_get_perms(struct inode *inode, +- struct hfsplus_perm *perms, int dir) ++static int hfsplus_get_perms(struct inode *inode, ++ struct hfsplus_perm *perms, int dir) + { + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + u16 mode; + + mode = be16_to_cpu(perms->mode); ++ if (dir) { ++ if (mode && !S_ISDIR(mode)) ++ goto bad_type; ++ } else if (mode) { ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ case S_IFLNK: ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: ++ break; ++ default: ++ goto bad_type; ++ } ++ } + + i_uid_write(inode, be32_to_cpu(perms->owner)); + if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) +@@ -212,6 +228,10 @@ static void hfsplus_get_perms(struct inode *inode, + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; ++ return 0; ++bad_type: ++ pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); ++ return -EIO; + } + + static int hfsplus_file_open(struct inode *inode, struct file *file) +@@ -516,7 +536,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); +- hfsplus_get_perms(inode, &folder->permissions, 1); ++ res = hfsplus_get_perms(inode, &folder->permissions, 1); ++ if (res) ++ goto out; + set_nlink(inode, 1); + inode->i_size = 2 + be32_to_cpu(folder->valence); + inode_set_atime_to_ts(inode, hfsp_mt2ut(folder->access_date)); +@@ -545,7 +567,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + + hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? + &file->rsrc_fork : &file->data_fork); +- hfsplus_get_perms(inode, &file->permissions, 0); ++ res = hfsplus_get_perms(inode, &file->permissions, 0); ++ if (res) ++ goto out; + set_nlink(inode, 1); + if (S_ISREG(inode->i_mode)) { + if (file->permissions.dev) +-- +2.51.0 + diff --git a/queue-6.18/iomap-account-for-unaligned-end-offsets-when-truncat.patch b/queue-6.18/iomap-account-for-unaligned-end-offsets-when-truncat.patch new file mode 100644 index 0000000000..f88a77ba6e --- /dev/null +++ b/queue-6.18/iomap-account-for-unaligned-end-offsets-when-truncat.patch @@ -0,0 +1,74 @@ +From 0d5613637489735aee96c94f4b4aa6520e38720e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 11:36:51 -0800 +Subject: iomap: account for unaligned end offsets when truncating read range + +From: Joanne Koong + +[ Upstream commit 9d875e0eef8ec15b6b1da0cb9a0f8ed13efee89e ] + +The end position to start truncating from may be at an offset into a +block, which under the current logic would result in overtruncation. + +Adjust the calculation to account for unaligned end offsets. + +Signed-off-by: Joanne Koong +Link: https://patch.msgid.link/20251111193658.3495942-3-joannelkoong@gmail.com +Reviewed-by: Christoph Hellwig +Reviewed-by: Darrick J. Wong +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 1c95a0a7b302d..c0fa6acf19375 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -217,6 +217,22 @@ static void ifs_free(struct folio *folio) + kfree(ifs); + } + ++/* ++ * Calculate how many bytes to truncate based off the number of blocks to ++ * truncate and the end position to start truncating from. ++ */ ++static size_t iomap_bytes_to_truncate(loff_t end_pos, unsigned block_bits, ++ unsigned blocks_truncated) ++{ ++ unsigned block_size = 1 << block_bits; ++ unsigned block_offset = end_pos & (block_size - 1); ++ ++ if (!block_offset) ++ return blocks_truncated << block_bits; ++ ++ return ((blocks_truncated - 1) << block_bits) + block_offset; ++} ++ + /* + * Calculate the range inside the folio that we actually need to read. + */ +@@ -262,7 +278,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + /* truncate len if we find any trailing uptodate block(s) */ + while (++i <= last) { + if (ifs_block_is_uptodate(ifs, i)) { +- plen -= (last - i + 1) * block_size; ++ plen -= iomap_bytes_to_truncate(*pos + plen, ++ block_bits, last - i + 1); + last = i - 1; + break; + } +@@ -278,7 +295,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + unsigned end = offset_in_folio(folio, isize - 1) >> block_bits; + + if (first <= end && last > end) +- plen -= (last - end) * block_size; ++ plen -= iomap_bytes_to_truncate(*pos + plen, block_bits, ++ last - end); + } + + *offp = poff; +-- +2.51.0 + diff --git a/queue-6.18/iomap-adjust-read-range-correctly-for-non-block-alig.patch b/queue-6.18/iomap-adjust-read-range-correctly-for-non-block-alig.patch new file mode 100644 index 0000000000..ee8a1f6386 --- /dev/null +++ b/queue-6.18/iomap-adjust-read-range-correctly-for-non-block-alig.patch @@ -0,0 +1,67 @@ +From 7dd7ee4d0a47e4332ba097dc4c2e25e0b18e93e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 11:00:42 -0700 +Subject: iomap: adjust read range correctly for non-block-aligned positions + +From: Joanne Koong + +[ Upstream commit 7aa6bc3e8766990824f66ca76c19596ce10daf3e ] + +iomap_adjust_read_range() assumes that the position and length passed in +are block-aligned. This is not always the case however, as shown in the +syzbot generated case for erofs. This causes too many bytes to be +skipped for uptodate blocks, which results in returning the incorrect +position and length to read in. If all the blocks are uptodate, this +underflows length and returns a position beyond the folio. + +Fix the calculation to also take into account the block offset when +calculating how many bytes can be skipped for uptodate blocks. + +Signed-off-by: Joanne Koong +Tested-by: syzbot@syzkaller.appspotmail.com +Reviewed-by: Brian Foster +Reviewed-by: Christoph Hellwig +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 8b847a1e27f13..1c95a0a7b302d 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -240,17 +240,24 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + * to avoid reading in already uptodate ranges. + */ + if (ifs) { +- unsigned int i; ++ unsigned int i, blocks_skipped; + + /* move forward for each leading block marked uptodate */ +- for (i = first; i <= last; i++) { ++ for (i = first; i <= last; i++) + if (!ifs_block_is_uptodate(ifs, i)) + break; +- *pos += block_size; +- poff += block_size; +- plen -= block_size; +- first++; ++ ++ blocks_skipped = i - first; ++ if (blocks_skipped) { ++ unsigned long block_offset = *pos & (block_size - 1); ++ unsigned bytes_skipped = ++ (blocks_skipped << block_bits) - block_offset; ++ ++ *pos += bytes_skipped; ++ poff += bytes_skipped; ++ plen -= bytes_skipped; + } ++ first = i; + + /* truncate len if we find any trailing uptodate block(s) */ + while (++i <= last) { +-- +2.51.0 + diff --git a/queue-6.18/kbuild-use-objtree-for-module-signing-key-path.patch b/queue-6.18/kbuild-use-objtree-for-module-signing-key-path.patch new file mode 100644 index 0000000000..bb312c0dc2 --- /dev/null +++ b/queue-6.18/kbuild-use-objtree-for-module-signing-key-path.patch @@ -0,0 +1,58 @@ +From ae1a997206fcacb080ebb1624c8587a37522cd9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 16:34:52 +0000 +Subject: kbuild: Use objtree for module signing key path + +From: Mikhail Malyshev + +[ Upstream commit af61da281f52aba0c5b090bafb3a31c5739850ff ] + +When building out-of-tree modules with CONFIG_MODULE_SIG_FORCE=y, +module signing fails because the private key path uses $(srctree) +while the public key path uses $(objtree). Since signing keys are +generated in the build directory during kernel compilation, both +paths should use $(objtree) for consistency. + +This causes SSL errors like: + SSL error:02001002:system library:fopen:No such file or directory + sign-file: /kernel-src/certs/signing_key.pem + +The issue occurs because: +- sig-key uses: $(srctree)/certs/signing_key.pem (source tree) +- cmd_sign uses: $(objtree)/certs/signing_key.x509 (build tree) + +But both keys are generated in $(objtree) during the build. + +This complements commit 25ff08aa43e37 ("kbuild: Fix signing issue for +external modules") which fixed the scripts path and public key path, +but missed the private key path inconsistency. + +Fixes out-of-tree module signing for configurations with separate +source and build directories (e.g., O=/kernel-out). + +Signed-off-by: Mikhail Malyshev +Reviewed-by: Nathan Chancellor +Tested-by: Nicolas Schier +Link: https://patch.msgid.link/20251015163452.3754286-1-mike.malyshev@gmail.com +Signed-off-by: Nicolas Schier +Signed-off-by: Sasha Levin +--- + scripts/Makefile.modinst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst +index 1628198f3e830..9ba45e5b32b18 100644 +--- a/scripts/Makefile.modinst ++++ b/scripts/Makefile.modinst +@@ -100,7 +100,7 @@ endif + # Don't stop modules_install even if we can't sign external modules. + # + ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) +-sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) ++sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) + else + sig-key := $(CONFIG_MODULE_SIG_KEY) + endif +-- +2.51.0 + diff --git a/queue-6.18/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch b/queue-6.18/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch new file mode 100644 index 0000000000..625893b64c --- /dev/null +++ b/queue-6.18/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch @@ -0,0 +1,106 @@ +From 5aa87f79cb0fdccb4066370784845ea2f7b62314 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 09:05:46 +0900 +Subject: ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency + +From: Namjae Jeon + +[ Upstream commit b39a1833cc4a2755b02603eec3a71a85e9dff926 ] + +Under high concurrency, A tree-connection object (tcon) is freed on +a disconnect path while another path still holds a reference and later +executes *_put()/write on it. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/mgmt/tree_connect.c | 18 ++++-------------- + fs/smb/server/mgmt/tree_connect.h | 1 - + fs/smb/server/smb2pdu.c | 3 --- + 3 files changed, 4 insertions(+), 18 deletions(-) + +diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c +index ecfc575086712..d3483d9c757c7 100644 +--- a/fs/smb/server/mgmt/tree_connect.c ++++ b/fs/smb/server/mgmt/tree_connect.c +@@ -78,7 +78,6 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + tree_conn->t_state = TREE_NEW; + status.tree_conn = tree_conn; + atomic_set(&tree_conn->refcount, 1); +- init_waitqueue_head(&tree_conn->refcount_q); + + ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, + KSMBD_DEFAULT_GFP)); +@@ -100,14 +99,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + + void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) + { +- /* +- * Checking waitqueue to releasing tree connect on +- * tree disconnect. waitqueue_active is safe because it +- * uses atomic operation for condition. +- */ +- if (!atomic_dec_return(&tcon->refcount) && +- waitqueue_active(&tcon->refcount_q)) +- wake_up(&tcon->refcount_q); ++ if (atomic_dec_and_test(&tcon->refcount)) ++ kfree(tcon); + } + + int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, +@@ -119,14 +112,11 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, + xa_erase(&sess->tree_conns, tree_conn->id); + write_unlock(&sess->tree_conns_lock); + +- if (!atomic_dec_and_test(&tree_conn->refcount)) +- wait_event(tree_conn->refcount_q, +- atomic_read(&tree_conn->refcount) == 0); +- + ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); + ksmbd_release_tree_conn_id(sess, tree_conn->id); + ksmbd_share_config_put(tree_conn->share_conf); +- kfree(tree_conn); ++ if (atomic_dec_and_test(&tree_conn->refcount)) ++ kfree(tree_conn); + return ret; + } + +diff --git a/fs/smb/server/mgmt/tree_connect.h b/fs/smb/server/mgmt/tree_connect.h +index a42cdd0510411..f0023d86716f2 100644 +--- a/fs/smb/server/mgmt/tree_connect.h ++++ b/fs/smb/server/mgmt/tree_connect.h +@@ -33,7 +33,6 @@ struct ksmbd_tree_connect { + int maximal_access; + bool posix_extensions; + atomic_t refcount; +- wait_queue_head_t refcount_q; + unsigned int t_state; + }; + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index a2830ec67e782..dba29881debdc 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -2200,7 +2200,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); + tcon->t_state = TREE_DISCONNECTED; + write_unlock(&sess->tree_conns_lock); + +@@ -2210,8 +2209,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- work->tcon = NULL; +- + rsp->StructureSize = cpu_to_le16(4); + err = ksmbd_iov_pin_rsp(work, rsp, + sizeof(struct smb2_tree_disconnect_rsp)); +-- +2.51.0 + diff --git a/queue-6.18/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch b/queue-6.18/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch new file mode 100644 index 0000000000..626d3bf3b5 --- /dev/null +++ b/queue-6.18/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch @@ -0,0 +1,190 @@ +From 540915f0f5a733eab9e6ff4135597f664999731f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:05:09 +0900 +Subject: ksmbd: vfs: fix race on m_flags in vfs_cache + +From: Qianchang Zhao + +[ Upstream commit 991f8a79db99b14c48d20d2052c82d65b9186cad ] + +ksmbd maintains delete-on-close and pending-delete state in +ksmbd_inode->m_flags. In vfs_cache.c this field is accessed under +inconsistent locking: some paths read and modify m_flags under +ci->m_lock while others do so without taking the lock at all. + +Examples: + + - ksmbd_query_inode_status() and __ksmbd_inode_close() use + ci->m_lock when checking or updating m_flags. + - ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), + ksmbd_clear_inode_pending_delete() and ksmbd_fd_set_delete_on_close() + used to read and modify m_flags without ci->m_lock. + +This creates a potential data race on m_flags when multiple threads +open, close and delete the same file concurrently. In the worst case +delete-on-close and pending-delete bits can be lost or observed in an +inconsistent state, leading to confusing delete semantics (files that +stay on disk after delete-on-close, or files that disappear while still +in use). + +Fix it by: + + - Making ksmbd_query_inode_status() look at m_flags under ci->m_lock + after dropping inode_hash_lock. + - Adding ci->m_lock protection to all helpers that read or modify + m_flags (ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), + ksmbd_clear_inode_pending_delete(), ksmbd_fd_set_delete_on_close()). + - Keeping the existing ci->m_lock protection in __ksmbd_inode_close(), + and moving the actual unlink/xattr removal outside the lock. + +This unifies the locking around m_flags and removes the data race while +preserving the existing delete-on-close behaviour. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Qianchang Zhao +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/vfs_cache.c | 88 +++++++++++++++++++++++++++------------ + 1 file changed, 62 insertions(+), 26 deletions(-) + +diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c +index dfed6fce89049..6ef116585af64 100644 +--- a/fs/smb/server/vfs_cache.c ++++ b/fs/smb/server/vfs_cache.c +@@ -112,40 +112,62 @@ int ksmbd_query_inode_status(struct dentry *dentry) + + read_lock(&inode_hash_lock); + ci = __ksmbd_inode_lookup(dentry); +- if (ci) { +- ret = KSMBD_INODE_STATUS_OK; +- if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) +- ret = KSMBD_INODE_STATUS_PENDING_DELETE; +- atomic_dec(&ci->m_count); +- } + read_unlock(&inode_hash_lock); ++ if (!ci) ++ return ret; ++ ++ down_read(&ci->m_lock); ++ if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) ++ ret = KSMBD_INODE_STATUS_PENDING_DELETE; ++ else ++ ret = KSMBD_INODE_STATUS_OK; ++ up_read(&ci->m_lock); ++ ++ atomic_dec(&ci->m_count); + return ret; + } + + bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) + { +- return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); ++ struct ksmbd_inode *ci = fp->f_ci; ++ int ret; ++ ++ down_read(&ci->m_lock); ++ ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); ++ up_read(&ci->m_lock); ++ ++ return ret; + } + + void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) + { +- fp->f_ci->m_flags |= S_DEL_PENDING; ++ struct ksmbd_inode *ci = fp->f_ci; ++ ++ down_write(&ci->m_lock); ++ ci->m_flags |= S_DEL_PENDING; ++ up_write(&ci->m_lock); + } + + void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp) + { +- fp->f_ci->m_flags &= ~S_DEL_PENDING; ++ struct ksmbd_inode *ci = fp->f_ci; ++ ++ down_write(&ci->m_lock); ++ ci->m_flags &= ~S_DEL_PENDING; ++ up_write(&ci->m_lock); + } + + void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, + int file_info) + { +- if (ksmbd_stream_fd(fp)) { +- fp->f_ci->m_flags |= S_DEL_ON_CLS_STREAM; +- return; +- } ++ struct ksmbd_inode *ci = fp->f_ci; + +- fp->f_ci->m_flags |= S_DEL_ON_CLS; ++ down_write(&ci->m_lock); ++ if (ksmbd_stream_fd(fp)) ++ ci->m_flags |= S_DEL_ON_CLS_STREAM; ++ else ++ ci->m_flags |= S_DEL_ON_CLS; ++ up_write(&ci->m_lock); + } + + static void ksmbd_inode_hash(struct ksmbd_inode *ci) +@@ -257,27 +279,41 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) + struct file *filp; + + filp = fp->filp; +- if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { +- ci->m_flags &= ~S_DEL_ON_CLS_STREAM; +- err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), +- &filp->f_path, +- fp->stream.name, +- true); +- if (err) +- pr_err("remove xattr failed : %s\n", +- fp->stream.name); ++ ++ if (ksmbd_stream_fd(fp)) { ++ bool remove_stream_xattr = false; ++ ++ down_write(&ci->m_lock); ++ if (ci->m_flags & S_DEL_ON_CLS_STREAM) { ++ ci->m_flags &= ~S_DEL_ON_CLS_STREAM; ++ remove_stream_xattr = true; ++ } ++ up_write(&ci->m_lock); ++ ++ if (remove_stream_xattr) { ++ err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), ++ &filp->f_path, ++ fp->stream.name, ++ true); ++ if (err) ++ pr_err("remove xattr failed : %s\n", ++ fp->stream.name); ++ } + } + + if (atomic_dec_and_test(&ci->m_count)) { ++ bool do_unlink = false; ++ + down_write(&ci->m_lock); + if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { + ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); +- up_write(&ci->m_lock); +- ksmbd_vfs_unlink(filp); +- down_write(&ci->m_lock); ++ do_unlink = true; + } + up_write(&ci->m_lock); + ++ if (do_unlink) ++ ksmbd_vfs_unlink(filp); ++ + ksmbd_inode_free(ci); + } + } +-- +2.51.0 + diff --git a/queue-6.18/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch b/queue-6.18/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch new file mode 100644 index 0000000000..8cf9734b0c --- /dev/null +++ b/queue-6.18/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch @@ -0,0 +1,88 @@ +From 48a7fd5f764635cefde4e32a74f24de83513a124 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 10:30:19 -0700 +Subject: livepatch: Match old_sympos 0 and 1 in klp_find_func() + +From: Song Liu + +[ Upstream commit 139560e8b973402140cafeb68c656c1374bd4c20 ] + +When there is only one function of the same name, old_sympos of 0 and 1 +are logically identical. Match them in klp_find_func(). + +This is to avoid a corner case with different toolchain behavior. + +In this specific issue, two versions of kpatch-build were used to +build livepatch for the same kernel. One assigns old_sympos == 0 for +unique local functions, the other assigns old_sympos == 1 for unique +local functions. Both versions work fine by themselves. (PS: This +behavior change was introduced in a downstream version of kpatch-build. +This change does not exist in upstream kpatch-build.) + +However, during livepatch upgrade (with the replace flag set) from a +patch built with one version of kpatch-build to the same fix built with +the other version of kpatch-build, livepatching fails with errors like: + +[ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' +... +[ 14.219466] Call Trace: +[ 14.219468] +[ 14.219469] dump_stack_lvl+0x47/0x60 +[ 14.219474] sysfs_warn_dup.cold+0x17/0x27 +[ 14.219476] sysfs_create_dir_ns+0x95/0xb0 +[ 14.219479] kobject_add_internal+0x9e/0x260 +[ 14.219483] kobject_add+0x68/0x80 +[ 14.219485] ? kstrdup+0x3c/0xa0 +[ 14.219486] klp_enable_patch+0x320/0x830 +[ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] +[ 14.219491] ? 0xffffffffa05eb000 +[ 14.219492] do_one_initcall+0x2e/0x190 +[ 14.219494] do_init_module+0x67/0x270 +[ 14.219496] init_module_from_file+0x75/0xa0 +[ 14.219499] idempotent_init_module+0x15a/0x240 +[ 14.219501] __x64_sys_finit_module+0x61/0xc0 +[ 14.219503] do_syscall_64+0x5b/0x160 +[ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 +[ 14.219507] RIP: 0033:0x7f545a4bd96d +... +[ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with + -EEXIST, don't try to register things with the same name ... + +This happens because klp_find_func() thinks somefunc with old_sympos==0 +is not the same as somefunc with old_sympos==1, and klp_add_object_nops +adds another xxx/func,1 to the list of functions to patch. + +Signed-off-by: Song Liu +Acked-by: Josh Poimboeuf +[pmladek@suse.com: Fixed some typos.] +Reviewed-by: Petr Mladek +Tested-by: Petr Mladek +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + kernel/livepatch/core.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c +index 0e73fac55f8eb..4e7a5cbc40a91 100644 +--- a/kernel/livepatch/core.c ++++ b/kernel/livepatch/core.c +@@ -88,8 +88,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj, + struct klp_func *func; + + klp_for_each_func(obj, func) { ++ /* ++ * Besides identical old_sympos, also consider old_sympos ++ * of 0 and 1 are identical. ++ */ + if ((strcmp(old_func->old_name, func->old_name) == 0) && +- (old_func->old_sympos == func->old_sympos)) { ++ ((old_func->old_sympos == func->old_sympos) || ++ (old_func->old_sympos == 0 && func->old_sympos == 1) || ++ (old_func->old_sympos == 1 && func->old_sympos == 0))) { + return func; + } + } +-- +2.51.0 + diff --git a/queue-6.18/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch b/queue-6.18/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch new file mode 100644 index 0000000000..053ae5af72 --- /dev/null +++ b/queue-6.18/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch @@ -0,0 +1,60 @@ +From 9afb825d4118d00fb5723dd6417b5bb6bd522edc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:38:50 -0300 +Subject: ntfs: set dummy blocksize to read boot_block when mounting + +From: Pedro Demarchi Gomes + +[ Upstream commit d1693a7d5a38acf6424235a6070bcf5b186a360d ] + +When mounting, sb->s_blocksize is used to read the boot_block without +being defined or validated. Set a dummy blocksize before attempting to +read the boot_block. + +The issue can be triggered with the following syz reproducer: + + mkdirat(0xffffffffffffff9c, &(0x7f0000000080)='./file1\x00', 0x0) + r4 = openat$nullb(0xffffffffffffff9c, &(0x7f0000000040), 0x121403, 0x0) + ioctl$FS_IOC_SETFLAGS(r4, 0x40081271, &(0x7f0000000980)=0x4000) + mount(&(0x7f0000000140)=@nullb, &(0x7f0000000040)='./cgroup\x00', + &(0x7f0000000000)='ntfs3\x00', 0x2208004, 0x0) + syz_clone(0x88200200, 0x0, 0x0, 0x0, 0x0, 0x0) + +Here, the ioctl sets the bdev block size to 16384. During mount, +get_tree_bdev_flags() calls sb_set_blocksize(sb, block_size(bdev)), +but since block_size(bdev) > PAGE_SIZE, sb_set_blocksize() leaves +sb->s_blocksize at zero. + +Later, ntfs_init_from_boot() attempts to read the boot_block while +sb->s_blocksize is still zero, which triggers the bug. + +Reported-by: syzbot+f4f84b57a01d6b8364ad@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=f4f84b57a01d6b8364ad +Signed-off-by: Pedro Demarchi Gomes +[almaz.alexandrovich@paragon-software.com: changed comment style, added +return value handling] +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/super.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index ddff94c091b8c..e6c0908e27c29 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -933,6 +933,11 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size, + + sbi->volume.blocks = dev_size >> PAGE_SHIFT; + ++ /* Set dummy blocksize to read boot_block. */ ++ if (!sb_min_blocksize(sb, PAGE_SIZE)) { ++ return -EINVAL; ++ } ++ + read_boot: + bh = ntfs_bread(sb, boot_block); + if (!bh) +-- +2.51.0 + diff --git a/queue-6.18/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch b/queue-6.18/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch new file mode 100644 index 0000000000..26d85d9c85 --- /dev/null +++ b/queue-6.18/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch @@ -0,0 +1,83 @@ +From 0435e2425704b59eb133f0e9c2e10b3e3a7720dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 08:00:53 -0500 +Subject: perf/x86/amd: Check event before enable to avoid GPF + +From: George Kennedy + +[ Upstream commit 866cf36bfee4fba6a492d2dcc5133f857e3446b0 ] + +On AMD machines cpuc->events[idx] can become NULL in a subtle race +condition with NMI->throttle->x86_pmu_stop(). + +Check event for NULL in amd_pmu_enable_all() before enable to avoid a GPF. +This appears to be an AMD only issue. + +Syzkaller reported a GPF in amd_pmu_enable_all. + +INFO: NMI handler (perf_event_nmi_handler) took too long to run: 13.143 + msecs +Oops: general protection fault, probably for non-canonical address + 0xdffffc0000000034: 0000 PREEMPT SMP KASAN NOPTI +KASAN: null-ptr-deref in range [0x00000000000001a0-0x00000000000001a7] +CPU: 0 UID: 0 PID: 328415 Comm: repro_36674776 Not tainted 6.12.0-rc1-syzk +RIP: 0010:x86_pmu_enable_event (arch/x86/events/perf_event.h:1195 + arch/x86/events/core.c:1430) +RSP: 0018:ffff888118009d60 EFLAGS: 00010012 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: 0000000000000034 RSI: 0000000000000000 RDI: 00000000000001a0 +RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002 +R13: ffff88811802a440 R14: ffff88811802a240 R15: ffff8881132d8601 +FS: 00007f097dfaa700(0000) GS:ffff888118000000(0000) GS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000200001c0 CR3: 0000000103d56000 CR4: 00000000000006f0 +Call Trace: + +amd_pmu_enable_all (arch/x86/events/amd/core.c:760 (discriminator 2)) +x86_pmu_enable (arch/x86/events/core.c:1360) +event_sched_out (kernel/events/core.c:1191 kernel/events/core.c:1186 + kernel/events/core.c:2346) +__perf_remove_from_context (kernel/events/core.c:2435) +event_function (kernel/events/core.c:259) +remote_function (kernel/events/core.c:92 (discriminator 1) + kernel/events/core.c:72 (discriminator 1)) +__flush_smp_call_function_queue (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 ./include/trace/events/csd.h:64 + kernel/smp.c:135 kernel/smp.c:540) +__sysvec_call_function_single (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 + ./arch/x86/include/asm/trace/irq_vectors.h:99 arch/x86/kernel/smp.c:272) +sysvec_call_function_single (arch/x86/kernel/smp.c:266 (discriminator 47) + arch/x86/kernel/smp.c:266 (discriminator 47)) + + +Reported-by: syzkaller +Signed-off-by: George Kennedy +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + arch/x86/events/amd/core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c +index b20661b8621d1..8868f5f5379ba 100644 +--- a/arch/x86/events/amd/core.c ++++ b/arch/x86/events/amd/core.c +@@ -763,7 +763,12 @@ static void amd_pmu_enable_all(int added) + if (!test_bit(idx, cpuc->active_mask)) + continue; + +- amd_pmu_enable_event(cpuc->events[idx]); ++ /* ++ * FIXME: cpuc->events[idx] can become NULL in a subtle race ++ * condition with NMI->throttle->x86_pmu_stop(). ++ */ ++ if (cpuc->events[idx]) ++ amd_pmu_enable_event(cpuc->events[idx]); + } + } + +-- +2.51.0 + diff --git a/queue-6.18/sched-deadline-only-set-free_cpus-for-online-runqueu.patch b/queue-6.18/sched-deadline-only-set-free_cpus-for-online-runqueu.patch new file mode 100644 index 0000000000..75e6e257ed --- /dev/null +++ b/queue-6.18/sched-deadline-only-set-free_cpus-for-online-runqueu.patch @@ -0,0 +1,188 @@ +From c65c04937680f0e5fd490b7f78f33bab1ab94dcf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 18:22:36 -0700 +Subject: sched/deadline: only set free_cpus for online runqueues + +From: Doug Berger + +[ Upstream commit 382748c05e58a9f1935f5a653c352422375566ea ] + +Commit 16b269436b72 ("sched/deadline: Modify cpudl::free_cpus +to reflect rd->online") introduced the cpudl_set/clear_freecpu +functions to allow the cpu_dl::free_cpus mask to be manipulated +by the deadline scheduler class rq_on/offline callbacks so the +mask would also reflect this state. + +Commit 9659e1eeee28 ("sched/deadline: Remove cpu_active_mask +from cpudl_find()") removed the check of the cpu_active_mask to +save some processing on the premise that the cpudl::free_cpus +mask already reflected the runqueue online state. + +Unfortunately, there are cases where it is possible for the +cpudl_clear function to set the free_cpus bit for a CPU when the +deadline runqueue is offline. When this occurs while a CPU is +connected to the default root domain the flag may retain the bad +state after the CPU has been unplugged. Later, a different CPU +that is transitioning through the default root domain may push a +deadline task to the powered down CPU when cpudl_find sees its +free_cpus bit is set. If this happens the task will not have the +opportunity to run. + +One example is outlined here: +https://lore.kernel.org/lkml/20250110233010.2339521-1-opendmb@gmail.com + +Another occurs when the last deadline task is migrated from a +CPU that has an offlined runqueue. The dequeue_task member of +the deadline scheduler class will eventually call cpudl_clear +and set the free_cpus bit for the CPU. + +This commit modifies the cpudl_clear function to be aware of the +online state of the deadline runqueue so that the free_cpus mask +can be updated appropriately. + +It is no longer necessary to manage the mask outside of the +cpudl_set/clear functions so the cpudl_set/clear_freecpu +functions are removed. In addition, since the free_cpus mask is +now only updated under the cpudl lock the code was changed to +use the non-atomic __cpumask functions. + +Signed-off-by: Doug Berger +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + kernel/sched/cpudeadline.c | 34 +++++++++------------------------- + kernel/sched/cpudeadline.h | 4 +--- + kernel/sched/deadline.c | 8 ++++---- + 3 files changed, 14 insertions(+), 32 deletions(-) + +diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c +index cdd740b3f7743..37b572cc8aca2 100644 +--- a/kernel/sched/cpudeadline.c ++++ b/kernel/sched/cpudeadline.c +@@ -166,12 +166,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, + * cpudl_clear - remove a CPU from the cpudl max-heap + * @cp: the cpudl max-heap context + * @cpu: the target CPU ++ * @online: the online state of the deadline runqueue + * + * Notes: assumes cpu_rq(cpu)->lock is locked + * + * Returns: (void) + */ +-void cpudl_clear(struct cpudl *cp, int cpu) ++void cpudl_clear(struct cpudl *cp, int cpu, bool online) + { + int old_idx, new_cpu; + unsigned long flags; +@@ -184,7 +185,7 @@ void cpudl_clear(struct cpudl *cp, int cpu) + if (old_idx == IDX_INVALID) { + /* + * Nothing to remove if old_idx was invalid. +- * This could happen if a rq_offline_dl is ++ * This could happen if rq_online_dl or rq_offline_dl is + * called for a CPU without -dl tasks running. + */ + } else { +@@ -195,9 +196,12 @@ void cpudl_clear(struct cpudl *cp, int cpu) + cp->elements[new_cpu].idx = old_idx; + cp->elements[cpu].idx = IDX_INVALID; + cpudl_heapify(cp, old_idx); +- +- cpumask_set_cpu(cpu, cp->free_cpus); + } ++ if (likely(online)) ++ __cpumask_set_cpu(cpu, cp->free_cpus); ++ else ++ __cpumask_clear_cpu(cpu, cp->free_cpus); ++ + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +@@ -228,7 +232,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + cp->elements[new_idx].cpu = cpu; + cp->elements[cpu].idx = new_idx; + cpudl_heapify_up(cp, new_idx); +- cpumask_clear_cpu(cpu, cp->free_cpus); ++ __cpumask_clear_cpu(cpu, cp->free_cpus); + } else { + cp->elements[old_idx].dl = dl; + cpudl_heapify(cp, old_idx); +@@ -237,26 +241,6 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +-/* +- * cpudl_set_freecpu - Set the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_set_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_set_cpu(cpu, cp->free_cpus); +-} +- +-/* +- * cpudl_clear_freecpu - Clear the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_clear_cpu(cpu, cp->free_cpus); +-} +- + /* + * cpudl_init - initialize the cpudl structure + * @cp: the cpudl max-heap context +diff --git a/kernel/sched/cpudeadline.h b/kernel/sched/cpudeadline.h +index 11c0f1faa7e11..d7699468eedd5 100644 +--- a/kernel/sched/cpudeadline.h ++++ b/kernel/sched/cpudeadline.h +@@ -19,8 +19,6 @@ struct cpudl { + + int cpudl_find(struct cpudl *cp, struct task_struct *p, struct cpumask *later_mask); + void cpudl_set(struct cpudl *cp, int cpu, u64 dl); +-void cpudl_clear(struct cpudl *cp, int cpu); ++void cpudl_clear(struct cpudl *cp, int cpu, bool online); + int cpudl_init(struct cpudl *cp); +-void cpudl_set_freecpu(struct cpudl *cp, int cpu); +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu); + void cpudl_cleanup(struct cpudl *cp); +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index 7b7671060bf9e..19b1a8b81c76c 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -1811,7 +1811,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline) + if (!dl_rq->dl_nr_running) { + dl_rq->earliest_dl.curr = 0; + dl_rq->earliest_dl.next = 0; +- cpudl_clear(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, rq->online); + cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr); + } else { + struct rb_node *leftmost = rb_first_cached(&dl_rq->root); +@@ -2883,9 +2883,10 @@ static void rq_online_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_set_overload(rq); + +- cpudl_set_freecpu(&rq->rd->cpudl, rq->cpu); + if (rq->dl.dl_nr_running > 0) + cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr); ++ else ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, true); + } + + /* Assumes rq->lock is held */ +@@ -2894,8 +2895,7 @@ static void rq_offline_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_clear_overload(rq); + +- cpudl_clear(&rq->rd->cpudl, rq->cpu); +- cpudl_clear_freecpu(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, false); + } + + void __init init_sched_dl_class(void) +-- +2.51.0 + diff --git a/queue-6.18/sched-fair-revert-max_newidle_lb_cost-bump.patch b/queue-6.18/sched-fair-revert-max_newidle_lb_cost-bump.patch new file mode 100644 index 0000000000..c33762eea5 --- /dev/null +++ b/queue-6.18/sched-fair-revert-max_newidle_lb_cost-bump.patch @@ -0,0 +1,77 @@ +From 793b456396c070bbc966b8e77035712905b7ff06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 17:01:20 +0100 +Subject: sched/fair: Revert max_newidle_lb_cost bump + +From: Peter Zijlstra + +[ Upstream commit d206fbad9328ddb68ebabd7cf7413392acd38081 ] + +Many people reported regressions on their database workloads due to: + + 155213a2aed4 ("sched/fair: Bump sd->max_newidle_lb_cost when newidle balance fails") + +For instance Adam Li reported a 6% regression on SpecJBB. + +Conversely this will regress schbench again; on my machine from 2.22 +Mrps/s down to 2.04 Mrps/s. + +Reported-by: Joseph Salisbury +Reported-by: Adam Li +Reported-by: Dietmar Eggemann +Reported-by: Hazem Mohamed Abuelfotoh +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dietmar Eggemann +Tested-by: Dietmar Eggemann +Tested-by: Chris Mason +Link: https://lkml.kernel.org/r/20250626144017.1510594-2-clm@fb.com +Link: https://lkml.kernel.org/r/006c9df2-b691-47f1-82e6-e233c3f91faf@oracle.com +Link: https://patch.msgid.link/20251107161739.406147760@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 19 +++---------------- + 1 file changed, 3 insertions(+), 16 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 71d3f4125b0e7..967ca52fb2311 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -12174,14 +12174,8 @@ static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) + /* + * Track max cost of a domain to make sure to not delay the + * next wakeup on the CPU. +- * +- * sched_balance_newidle() bumps the cost whenever newidle +- * balance fails, and we don't want things to grow out of +- * control. Use the sysctl_sched_migration_cost as the upper +- * limit, plus a litle extra to avoid off by ones. + */ +- sd->max_newidle_lb_cost = +- min(cost, sysctl_sched_migration_cost + 200); ++ sd->max_newidle_lb_cost = cost; + sd->last_decay_max_lb_cost = jiffies; + } else if (time_after(jiffies, sd->last_decay_max_lb_cost + HZ)) { + /* +@@ -12873,17 +12867,10 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) + + t1 = sched_clock_cpu(this_cpu); + domain_cost = t1 - t0; ++ update_newidle_cost(sd, domain_cost); ++ + curr_cost += domain_cost; + t0 = t1; +- +- /* +- * Failing newidle means it is not effective; +- * bump the cost so we end up doing less of it. +- */ +- if (!pulled_task) +- domain_cost = (3 * sd->max_newidle_lb_cost) / 2; +- +- update_newidle_cost(sd, domain_cost); + } + + /* +-- +2.51.0 + diff --git a/queue-6.18/scripts-faddr2line-fix-argument-list-too-long-error.patch b/queue-6.18/scripts-faddr2line-fix-argument-list-too-long-error.patch new file mode 100644 index 0000000000..bb0f7aeedf --- /dev/null +++ b/queue-6.18/scripts-faddr2line-fix-argument-list-too-long-error.patch @@ -0,0 +1,59 @@ +From 76449b694bccd3f9a0a3e91c12577e4767837e09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 12:03:58 +0200 +Subject: scripts/faddr2line: Fix "Argument list too long" error + +From: Pankaj Raghav + +[ Upstream commit ff5c0466486ba8d07ab2700380e8fd6d5344b4e9 ] + +The run_readelf() function reads the entire output of readelf into a +single shell variable. For large object files with extensive debug +information, the size of this variable can exceed the system's +command-line argument length limit. + +When this variable is subsequently passed to sed via `echo "${out}"`, it +triggers an "Argument list too long" error, causing the script to fail. + +Fix this by redirecting the output of readelf to a temporary file +instead of a variable. The sed commands are then modified to read from +this file, avoiding the argument length limitation entirely. + +Signed-off-by: Pankaj Raghav +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + scripts/faddr2line | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/scripts/faddr2line b/scripts/faddr2line +index 1fa6beef9f978..477b6d2aa3179 100755 +--- a/scripts/faddr2line ++++ b/scripts/faddr2line +@@ -107,14 +107,19 @@ find_dir_prefix() { + + run_readelf() { + local objfile=$1 +- local out=$(${READELF} --file-header --section-headers --symbols --wide $objfile) ++ local tmpfile ++ tmpfile=$(mktemp) ++ ++ ${READELF} --file-header --section-headers --symbols --wide "$objfile" > "$tmpfile" + + # This assumes that readelf first prints the file header, then the section headers, then the symbols. + # Note: It seems that GNU readelf does not prefix section headers with the "There are X section headers" + # line when multiple options are given, so let's also match with the "Section Headers:" line. +- ELF_FILEHEADER=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/q;p') +- ELF_SECHEADERS=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/,$p' | sed -n '/Symbol table .* contains [0-9]* entries:/q;p') +- ELF_SYMS=$(echo "${out}" | sed -n '/Symbol table .* contains [0-9]* entries:/,$p') ++ ELF_FILEHEADER=$(sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/q;p' "$tmpfile") ++ ELF_SECHEADERS=$(sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/,$p' "$tmpfile" | sed -n '/Symbol table .* contains [0-9]* entries:/q;p') ++ ELF_SYMS=$(sed -n '/Symbol table .* contains [0-9]* entries:/,$p' "$tmpfile") ++ ++ rm -f -- "$tmpfile" + } + + check_vmlinux() { +-- +2.51.0 + diff --git a/queue-6.18/scripts-kdoc_parser.py-warn-about-python-version-onl.patch b/queue-6.18/scripts-kdoc_parser.py-warn-about-python-version-onl.patch new file mode 100644 index 0000000000..15fb2e92fe --- /dev/null +++ b/queue-6.18/scripts-kdoc_parser.py-warn-about-python-version-onl.patch @@ -0,0 +1,66 @@ +From 9061cb407d41fcdee9f89776ea128b28ccce3ae7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 13:54:55 +0200 +Subject: scripts: kdoc_parser.py: warn about Python version only once + +From: Mauro Carvalho Chehab + +[ Upstream commit ade9b9576e2f000fb2ef0ac3bcd26e1167fd813b ] + +When running kernel-doc over multiple documents, it emits +one error message per file with is not what we want: + + $ python3.6 scripts/kernel-doc.py . --none + ... + Warning: ./include/trace/events/swiotlb.h:0 Python 3.7 or later is required for correct results + Warning: ./include/trace/events/iommu.h:0 Python 3.7 or later is required for correct results + Warning: ./include/trace/events/sock.h:0 Python 3.7 or later is required for correct results + ... + +Change the logic to warn it only once at the library: + + $ python3.6 scripts/kernel-doc.py . --none + Warning: Python 3.7 or later is required for correct results + Warning: ./include/cxl/features.h:0 Python 3.7 or later is required for correct results + +When running from command line, it warns twice, but that sounds +ok. + +Signed-off-by: Mauro Carvalho Chehab +Message-ID: <68e54cf8b1201d1f683aad9bc710a99421910356.1758196090.git.mchehab+huawei@kernel.org> +Signed-off-by: Jonathan Corbet +Signed-off-by: Sasha Levin +--- + scripts/lib/kdoc/kdoc_parser.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/scripts/lib/kdoc/kdoc_parser.py b/scripts/lib/kdoc/kdoc_parser.py +index 2376f180b1fa9..89d920e0b65ca 100644 +--- a/scripts/lib/kdoc/kdoc_parser.py ++++ b/scripts/lib/kdoc/kdoc_parser.py +@@ -350,6 +350,7 @@ class KernelEntry: + self.section = SECTION_DEFAULT + self._contents = [] + ++python_warning = False + + class KernelDoc: + """ +@@ -383,9 +384,13 @@ class KernelDoc: + # We need Python 3.7 for its "dicts remember the insertion + # order" guarantee + # +- if sys.version_info.major == 3 and sys.version_info.minor < 7: ++ global python_warning ++ if (not python_warning and ++ sys.version_info.major == 3 and sys.version_info.minor < 7): ++ + self.emit_msg(0, + 'Python 3.7 or later is required for correct results') ++ python_warning = True + + def emit_msg(self, ln, msg, warning=True): + """Emit a message""" +-- +2.51.0 + diff --git a/queue-6.18/series b/queue-6.18/series new file mode 100644 index 0000000000..3b072faff5 --- /dev/null +++ b/queue-6.18/series @@ -0,0 +1,52 @@ +btrfs-do-not-skip-logging-new-dentries-when-logging-.patch +btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch +bpf-arm64-do-not-audit-capability-check-in-do_jit.patch +bpf-fix-truncated-dmabuf-iterator-reads.patch +bpf-fix-verifier-assumptions-of-bpf_d_path-s-output-.patch +btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch +btrfs-fix-changeset-leak-on-mmap-write-after-failure.patch +shmem-fix-recovery-on-rename-failures.patch +iomap-adjust-read-range-correctly-for-non-block-alig.patch +iomap-account-for-unaligned-end-offsets-when-truncat.patch +scripts-faddr2line-fix-argument-list-too-long-error.patch +perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch +sched-deadline-only-set-free_cpus-for-online-runqueu.patch +sched-fair-revert-max_newidle_lb_cost-bump.patch +x86-ptrace-always-inline-trivial-accessors.patch +acpica-avoid-walking-the-namespace-if-start_node-is-.patch +acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch +cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch +acpi-fan-workaround-for-64-bit-firmware-bug.patch +cpufreq-s5pv210-fix-refcount-leak.patch +cpuidle-menu-use-residency-threshold-in-polling-stat.patch +x86-microcode-mark-early_parse_cmdline-as-__init.patch +scripts-kdoc_parser.py-warn-about-python-version-onl.patch +livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch +crypto-ccp-add-support-for-pci-device-0x115a.patch +fs-ntfs3-support-timestamps-prior-to-epoch.patch +kbuild-use-objtree-for-module-signing-key-path.patch +ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch +hfsplus-fix-volume-corruption-issue-for-generic-070.patch +hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch +hfsplus-verify-inode-mode-when-loading-from-disk.patch +hfsplus-fix-volume-corruption-issue-for-generic-073.patch +fs-ntfs3-check-for-shutdown-in-fsync.patch +wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch +wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch +wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch +wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch +wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch +btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch +hfsplus-fix-volume-corruption-issue-for-generic-101.patch +gfs2-fix-remote-evict-for-read-only-filesystems.patch +gfs2-fix-gfs2-switch-to-wait_event-in-gfs2_quotad.patch +smb-server-fix-return-value-of-smb2_ioctl.patch +ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch +ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch +bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch +bluetooth-btusb-mt7922-add-vid-pid-0489-e170.patch +bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch +bluetooth-btusb-add-new-custom-firmwares.patch +bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch +bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch +gfs2-fix-use-of-bio_chain.patch diff --git a/queue-6.18/shmem-fix-recovery-on-rename-failures.patch b/queue-6.18/shmem-fix-recovery-on-rename-failures.patch new file mode 100644 index 0000000000..a295beb452 --- /dev/null +++ b/queue-6.18/shmem-fix-recovery-on-rename-failures.patch @@ -0,0 +1,179 @@ +From 88c67f76ca2fad1a3fe56a20ec3c04dc32a912b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Dec 2025 17:50:23 -0500 +Subject: shmem: fix recovery on rename failures + +From: Al Viro + +[ Upstream commit e1b4c6a58304fd490124cc2b454d80edc786665c ] + +maple_tree insertions can fail if we are seriously short on memory; +simple_offset_rename() does not recover well if it runs into that. +The same goes for simple_offset_rename_exchange(). + +Moreover, shmem_whiteout() expects that if it succeeds, the caller will +progress to d_move(), i.e. that shmem_rename2() won't fail past the +successful call of shmem_whiteout(). + +Not hard to fix, fortunately - mtree_store() can't fail if the index we +are trying to store into is already present in the tree as a singleton. + +For simple_offset_rename_exchange() that's enough - we just need to be +careful about the order of operations. + +For simple_offset_rename() solution is to preinsert the target into the +tree for new_dir; the rest can be done without any potentially failing +operations. + +That preinsertion has to be done in shmem_rename2() rather than in +simple_offset_rename() itself - otherwise we'd need to deal with the +possibility of failure after successful shmem_whiteout(). + +Fixes: a2e459555c5f ("shmem: stable directory offsets") +Reviewed-by: Christian Brauner +Reviewed-by: Chuck Lever +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/libfs.c | 50 +++++++++++++++++++--------------------------- + include/linux/fs.h | 2 +- + mm/shmem.c | 18 ++++++++++++----- + 3 files changed, 35 insertions(+), 35 deletions(-) + +diff --git a/fs/libfs.c b/fs/libfs.c +index ce8c496a6940a..6be233c787fd8 100644 +--- a/fs/libfs.c ++++ b/fs/libfs.c +@@ -346,22 +346,22 @@ void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry) + * User space expects the directory offset value of the replaced + * (new) directory entry to be unchanged after a rename. + * +- * Returns zero on success, a negative errno value on failure. ++ * Caller must have grabbed a slot for new_dentry in the maple_tree ++ * associated with new_dir, even if dentry is negative. + */ +-int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, +- struct inode *new_dir, struct dentry *new_dentry) ++void simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry) + { + struct offset_ctx *old_ctx = old_dir->i_op->get_offset_ctx(old_dir); + struct offset_ctx *new_ctx = new_dir->i_op->get_offset_ctx(new_dir); + long new_offset = dentry2offset(new_dentry); + +- simple_offset_remove(old_ctx, old_dentry); ++ if (WARN_ON(!new_offset)) ++ return; + +- if (new_offset) { +- offset_set(new_dentry, 0); +- return simple_offset_replace(new_ctx, old_dentry, new_offset); +- } +- return simple_offset_add(new_ctx, old_dentry); ++ simple_offset_remove(old_ctx, old_dentry); ++ offset_set(new_dentry, 0); ++ WARN_ON(simple_offset_replace(new_ctx, old_dentry, new_offset)); + } + + /** +@@ -388,31 +388,23 @@ int simple_offset_rename_exchange(struct inode *old_dir, + long new_index = dentry2offset(new_dentry); + int ret; + +- simple_offset_remove(old_ctx, old_dentry); +- simple_offset_remove(new_ctx, new_dentry); ++ if (WARN_ON(!old_index || !new_index)) ++ return -EINVAL; + +- ret = simple_offset_replace(new_ctx, old_dentry, new_index); +- if (ret) +- goto out_restore; ++ ret = mtree_store(&new_ctx->mt, new_index, old_dentry, GFP_KERNEL); ++ if (WARN_ON(ret)) ++ return ret; + +- ret = simple_offset_replace(old_ctx, new_dentry, old_index); +- if (ret) { +- simple_offset_remove(new_ctx, old_dentry); +- goto out_restore; ++ ret = mtree_store(&old_ctx->mt, old_index, new_dentry, GFP_KERNEL); ++ if (WARN_ON(ret)) { ++ mtree_store(&new_ctx->mt, new_index, new_dentry, GFP_KERNEL); ++ return ret; + } + +- ret = simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); +- if (ret) { +- simple_offset_remove(new_ctx, old_dentry); +- simple_offset_remove(old_ctx, new_dentry); +- goto out_restore; +- } ++ offset_set(old_dentry, new_index); ++ offset_set(new_dentry, old_index); ++ simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); + return 0; +- +-out_restore: +- (void)simple_offset_replace(old_ctx, old_dentry, old_index); +- (void)simple_offset_replace(new_ctx, new_dentry, new_index); +- return ret; + } + + /** +diff --git a/include/linux/fs.h b/include/linux/fs.h +index dd3b57cfadeeb..9b2230fb2332f 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -3676,7 +3676,7 @@ struct offset_ctx { + void simple_offset_init(struct offset_ctx *octx); + int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry); + void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry); +-int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, ++void simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); + int simple_offset_rename_exchange(struct inode *old_dir, + struct dentry *old_dentry, +diff --git a/mm/shmem.c b/mm/shmem.c +index 5a3f0f754dc0c..d09ccb2ba21e9 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -4039,6 +4039,7 @@ static int shmem_rename2(struct mnt_idmap *idmap, + { + struct inode *inode = d_inode(old_dentry); + int they_are_dirs = S_ISDIR(inode->i_mode); ++ bool had_offset = false; + int error; + + if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) +@@ -4051,16 +4052,23 @@ static int shmem_rename2(struct mnt_idmap *idmap, + if (!simple_empty(new_dentry)) + return -ENOTEMPTY; + ++ error = simple_offset_add(shmem_get_offset_ctx(new_dir), new_dentry); ++ if (error == -EBUSY) ++ had_offset = true; ++ else if (unlikely(error)) ++ return error; ++ + if (flags & RENAME_WHITEOUT) { + error = shmem_whiteout(idmap, old_dir, old_dentry); +- if (error) ++ if (error) { ++ if (!had_offset) ++ simple_offset_remove(shmem_get_offset_ctx(new_dir), ++ new_dentry); + return error; ++ } + } + +- error = simple_offset_rename(old_dir, old_dentry, new_dir, new_dentry); +- if (error) +- return error; +- ++ simple_offset_rename(old_dir, old_dentry, new_dir, new_dentry); + if (d_really_is_positive(new_dentry)) { + (void) shmem_unlink(new_dir, new_dentry); + if (they_are_dirs) { +-- +2.51.0 + diff --git a/queue-6.18/smb-server-fix-return-value-of-smb2_ioctl.patch b/queue-6.18/smb-server-fix-return-value-of-smb2_ioctl.patch new file mode 100644 index 0000000000..50d3e9c887 --- /dev/null +++ b/queue-6.18/smb-server-fix-return-value-of-smb2_ioctl.patch @@ -0,0 +1,61 @@ +From 286176c465dec1a784a5fac2933172ed2ba32329 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:46:10 +0800 +Subject: smb/server: fix return value of smb2_ioctl() + +From: ChenXiaoSong + +[ Upstream commit 269df046c1e15ab34fa26fd90db9381f022a0963 ] + +__process_request() will not print error messages if smb2_ioctl() +always returns 0. + +Fix this by returning the correct value at the end of function. + +Signed-off-by: ChenXiaoSong +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/smb2pdu.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index f901ae18e68ad..a2830ec67e782 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -8164,7 +8164,7 @@ int smb2_ioctl(struct ksmbd_work *work) + id = req->VolatileFileId; + + if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) { +- rsp->hdr.Status = STATUS_NOT_SUPPORTED; ++ ret = -EOPNOTSUPP; + goto out; + } + +@@ -8184,8 +8184,9 @@ int smb2_ioctl(struct ksmbd_work *work) + case FSCTL_DFS_GET_REFERRALS: + case FSCTL_DFS_GET_REFERRALS_EX: + /* Not support DFS yet */ ++ ret = -EOPNOTSUPP; + rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED; +- goto out; ++ goto out2; + case FSCTL_CREATE_OR_GET_OBJECT_ID: + { + struct file_object_buf_type1_ioctl_rsp *obj_buf; +@@ -8475,8 +8476,10 @@ int smb2_ioctl(struct ksmbd_work *work) + rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL; + else if (ret < 0 || rsp->hdr.Status == 0) + rsp->hdr.Status = STATUS_INVALID_PARAMETER; ++ ++out2: + smb2_set_err_rsp(work); +- return 0; ++ return ret; + } + + /** +-- +2.51.0 + diff --git a/queue-6.18/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch b/queue-6.18/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch new file mode 100644 index 0000000000..383734cd8e --- /dev/null +++ b/queue-6.18/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch @@ -0,0 +1,61 @@ +From 8ac9e632e035619d273e532be5996b827af07c4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 11:03:14 +0100 +Subject: wifi: brcmfmac: Add DMI nvram filename quirk for Acer A1 840 tablet + +From: Hans de Goede + +[ Upstream commit a8e5a110c0c38e08e5dd66356cd1156e91cf88e1 ] + +The Acer A1 840 tablet contains quite generic names in the sys_vendor and +product_name DMI strings, without this patch brcmfmac will try to load: +brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file which is a bit +too generic. + +Add a DMI quirk so that a unique and clearly identifiable nvram file name +is used on the Acer A1 840 tablet. + +Acked-by: Arend van Spriel +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20251103100314.353826-1-hansg@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +index c3a602197662b..abe7f6501e5ed 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +@@ -24,6 +24,10 @@ static const struct brcmf_dmi_data acepc_t8_data = { + BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" + }; + ++static const struct brcmf_dmi_data acer_a1_840_data = { ++ BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" ++}; ++ + /* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus + * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. + */ +@@ -91,6 +95,16 @@ static const struct dmi_system_id dmi_platform_data[] = { + }, + .driver_data = (void *)&acepc_t8_data, + }, ++ { ++ /* Acer Iconia One 8 A1-840 (non FHD version) */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), ++ /* Above strings are too generic also match BIOS date */ ++ DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), ++ }, ++ .driver_data = (void *)&acer_a1_840_data, ++ }, + { + /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ + .matches = { +-- +2.51.0 + diff --git a/queue-6.18/wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch b/queue-6.18/wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch new file mode 100644 index 0000000000..1244509c4f --- /dev/null +++ b/queue-6.18/wifi-cfg80211-stop-radar-detection-in-cfg80211_leave.patch @@ -0,0 +1,85 @@ +From 0611300c35b44447fe05440a6803dce4f7ce1615 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 17:40:21 +0100 +Subject: wifi: cfg80211: stop radar detection in cfg80211_leave() + +From: Johannes Berg + +[ Upstream commit 9f33477b9a31a1edfe2df9f1a0359cccb0e16b4c ] + +If an interface is set down or, per the previous patch, changes +type, radar detection for it should be cancelled. This is done +for AP mode in mac80211 (somewhat needlessly, since cfg80211 can +do it, but didn't until now), but wasn't handled for mesh, so if +radar detection was started and then the interface set down or +its type switched (the latter sometimes happning in the hwsim +test 'mesh_peer_connected_dfs'), radar detection would be around +with the interface unknown to the driver, later leading to some +warnings around chanctx usage. + +Link: https://patch.msgid.link/20251121174021.290120e419e3.I2a5650c9062e29c988992dd8ce0d8eb570d23267@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/core.c | 1 + + net/wireless/core.h | 1 + + net/wireless/mlme.c | 19 +++++++++++++++++++ + 3 files changed, 21 insertions(+) + +diff --git a/net/wireless/core.c b/net/wireless/core.c +index 54a34d8d356e0..5e5c1bc380a89 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1365,6 +1365,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, + + cfg80211_pmsr_wdev_down(wdev); + ++ cfg80211_stop_radar_detection(wdev); + cfg80211_stop_background_radar_detection(wdev); + + switch (wdev->iftype) { +diff --git a/net/wireless/core.h b/net/wireless/core.h +index b6bd7f4d6385a..d5d78752227af 100644 +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -489,6 +489,7 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde + struct wireless_dev *wdev, + struct cfg80211_chan_def *chandef); + ++void cfg80211_stop_radar_detection(struct wireless_dev *wdev); + void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); + + void cfg80211_background_cac_done_wk(struct work_struct *work); +diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c +index 46394eb2086f6..3fc175f9f8686 100644 +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -1295,6 +1295,25 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde + return 0; + } + ++void cfg80211_stop_radar_detection(struct wireless_dev *wdev) ++{ ++ struct wiphy *wiphy = wdev->wiphy; ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ int link_id; ++ ++ for_each_valid_link(wdev, link_id) { ++ struct cfg80211_chan_def chandef; ++ ++ if (!wdev->links[link_id].cac_started) ++ continue; ++ ++ chandef = *wdev_chandef(wdev, link_id); ++ rdev_end_cac(rdev, wdev->netdev, link_id); ++ nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED, ++ wdev->netdev, GFP_KERNEL); ++ } ++} ++ + void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) + { + struct wiphy *wiphy = wdev->wiphy; +-- +2.51.0 + diff --git a/queue-6.18/wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch b/queue-6.18/wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch new file mode 100644 index 0000000000..d5f1901eb3 --- /dev/null +++ b/queue-6.18/wifi-cfg80211-use-cfg80211_leave-in-iftype-change.patch @@ -0,0 +1,63 @@ +From 2720a85b0f37e51f242063256ee1292610eb7bfd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 17:40:20 +0100 +Subject: wifi: cfg80211: use cfg80211_leave() in iftype change + +From: Johannes Berg + +[ Upstream commit 7a27b73943a70ee226fa125327101fb18e94701d ] + +When changing the interface type, all activity on the interface has +to be stopped first. This was done independent of existing code in +cfg80211_leave(), so didn't handle e.g. background radar detection. +Use cfg80211_leave() to handle it the same way. + +Note that cfg80211_leave() behaves slightly differently for IBSS in +wireless extensions, it won't send an event in that case. We could +handle that, but since nl80211 was used to change the type, IBSS is +rare, and wext is already a corner case, it doesn't seem worth it. + +Link: https://patch.msgid.link/20251121174021.922ef48ce007.I970c8514252ef8a864a7fbdab9591b71031dee03@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/util.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 56724b33af045..4eb028ad16836 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -1203,28 +1203,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, + dev->ieee80211_ptr->use_4addr = false; + rdev_set_qos_map(rdev, dev, NULL); + +- switch (otype) { +- case NL80211_IFTYPE_AP: +- case NL80211_IFTYPE_P2P_GO: +- cfg80211_stop_ap(rdev, dev, -1, true); +- break; +- case NL80211_IFTYPE_ADHOC: +- cfg80211_leave_ibss(rdev, dev, false); +- break; +- case NL80211_IFTYPE_STATION: +- case NL80211_IFTYPE_P2P_CLIENT: +- cfg80211_disconnect(rdev, dev, +- WLAN_REASON_DEAUTH_LEAVING, true); +- break; +- case NL80211_IFTYPE_MESH_POINT: +- /* mesh should be handled? */ +- break; +- case NL80211_IFTYPE_OCB: +- cfg80211_leave_ocb(rdev, dev); +- break; +- default: +- break; +- } ++ cfg80211_leave(rdev, dev->ieee80211_ptr); + + cfg80211_process_rdev_events(rdev); + cfg80211_mlme_purge_registrations(dev->ieee80211_ptr); +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch b/queue-6.18/wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch new file mode 100644 index 0000000000..afb8d87bd9 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt792x-fix-wifi-init-fail-by-setting-mcu_r.patch @@ -0,0 +1,62 @@ +From d7208dacd958ea051a54df4d96c87688c76b068f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 19:54:54 +0800 +Subject: wifi: mt76: mt792x: fix wifi init fail by setting MCU_RUNNING after + CLC load + +From: Quan Zhou + +[ Upstream commit 066f417be5fd8c7fe581c5550206364735dad7a3 ] + +Set the MT76_STATE_MCU_RUNNING bit only after mt7921_load_clc() +has successfully completed. Previously, the MCU_RUNNING state +was set before loading CLC, which could cause conflict between +chip mcu_init retry and mac_reset flow, result in chip init fail +and chip abnormal status. By moving the state set after CLC load, +firmware initialization becomes robust and resolves init fail issue. + +Signed-off-by: Quan Zhou +Reviewed-by: druth@chromium.org +Link: https://patch.msgid.link/19ec8e4465142e774f17801025accd0ae2214092.1763465933.git.quan.zhou@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- + drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +index 86bd33b916a9d..edc1df3c071e5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +@@ -646,10 +646,10 @@ int mt7921_run_firmware(struct mt792x_dev *dev) + if (err) + return err; + +- set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + err = mt7921_load_clc(dev, mt792x_ram_name(dev)); + if (err) + return err; ++ set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + + return mt7921_mcu_fw_log_2_host(dev, 1); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +index 8eda407e4135e..c12b71b71cfc7 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +@@ -1003,10 +1003,10 @@ int mt7925_run_firmware(struct mt792x_dev *dev) + if (err) + return err; + +- set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + err = mt7925_load_clc(dev, mt792x_ram_name(dev)); + if (err) + return err; ++ set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); + + return mt7925_mcu_fw_log_2_host(dev, 1); + } +-- +2.51.0 + diff --git a/queue-6.18/wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch b/queue-6.18/wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch new file mode 100644 index 0000000000..a59a084cd9 --- /dev/null +++ b/queue-6.18/wifi-rtl8xxxu-fix-ht40-channel-config-for-rtl8192cu-.patch @@ -0,0 +1,55 @@ +From d73207eeb547b2f34d954420d8fa49467b2101df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 16:10:01 +0200 +Subject: wifi: rtl8xxxu: Fix HT40 channel config for RTL8192CU, RTL8723AU + +From: Bitterblue Smith + +[ Upstream commit 5511ba3de434892e5ef3594d6eabbd12b1629356 ] + +Flip the response rate subchannel. It was backwards, causing low +speeds when using 40 MHz channel width. "iw dev ... station dump" +showed a low RX rate, 11M or less. + +Also fix the channel width field of RF6052_REG_MODE_AG. + +Tested only with RTL8192CU, but these settings are identical for +RTL8723AU. + +Signed-off-by: Bitterblue Smith +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/1f46571d-855b-43e1-8bfc-abacceb96043@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl8xxxu/core.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c +index be39463bd6c46..3e87c571e2419 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c +@@ -1252,7 +1252,7 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw) + opmode &= ~BW_OPMODE_20MHZ; + rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); + rsr &= ~RSR_RSC_BANDWIDTH_40M; +- if (sec_ch_above) ++ if (!sec_ch_above) + rsr |= RSR_RSC_UPPER_SUB_CHANNEL; + else + rsr |= RSR_RSC_LOWER_SUB_CHANNEL; +@@ -1321,9 +1321,8 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw) + + for (i = RF_A; i < priv->rf_paths; i++) { + val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); +- if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) +- val32 &= ~MODE_AG_CHANNEL_20MHZ; +- else ++ val32 &= ~MODE_AG_BW_MASK; ++ if (hw->conf.chandef.width != NL80211_CHAN_WIDTH_40) + val32 |= MODE_AG_CHANNEL_20MHZ; + rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); + } +-- +2.51.0 + diff --git a/queue-6.18/x86-microcode-mark-early_parse_cmdline-as-__init.patch b/queue-6.18/x86-microcode-mark-early_parse_cmdline-as-__init.patch new file mode 100644 index 0000000000..c94bfca4fc --- /dev/null +++ b/queue-6.18/x86-microcode-mark-early_parse_cmdline-as-__init.patch @@ -0,0 +1,44 @@ +From 4848471da2556e1eacf385e6afe5c9edaf5aa955 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:37:57 +0800 +Subject: x86/microcode: Mark early_parse_cmdline() as __init + +From: Yu Peng + +[ Upstream commit ca8313fd83399ea1d18e695c2ae9b259985c9e1f ] + +Fix section mismatch warning reported by modpost: + + .text:early_parse_cmdline() -> .init.data:boot_command_line + +The function early_parse_cmdline() is only called during init and accesses +init data, so mark it __init to match its usage. + + [ bp: This happens only when the toolchain fails to inline the function and + I haven't been able to reproduce it with any toolchain I'm using. Patch is + obviously correct regardless. ] + +Signed-off-by: Yu Peng +Signed-off-by: Borislav Petkov (AMD) +Link: https://patch.msgid.link/all/20251030123757.1410904-1-pengyu@kylinos.cn +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/microcode/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c +index f75c140906d00..539edd6d6dc8c 100644 +--- a/arch/x86/kernel/cpu/microcode/core.c ++++ b/arch/x86/kernel/cpu/microcode/core.c +@@ -136,7 +136,7 @@ bool __init microcode_loader_disabled(void) + return dis_ucode_ldr; + } + +-static void early_parse_cmdline(void) ++static void __init early_parse_cmdline(void) + { + char cmd_buf[64] = {}; + char *s, *p = cmd_buf; +-- +2.51.0 + diff --git a/queue-6.18/x86-ptrace-always-inline-trivial-accessors.patch b/queue-6.18/x86-ptrace-always-inline-trivial-accessors.patch new file mode 100644 index 0000000000..6d44544a60 --- /dev/null +++ b/queue-6.18/x86-ptrace-always-inline-trivial-accessors.patch @@ -0,0 +1,89 @@ +From 0f41e44bdc98ceee2c598a3c7203095419f3de5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 12:04:24 +0100 +Subject: x86/ptrace: Always inline trivial accessors + +From: Peter Zijlstra + +[ Upstream commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa ] + +A KASAN build bloats these single load/store helpers such that +it fails to inline them: + + vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled + +Make sure the compiler isn't allowed to do stupid. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Link: https://patch.msgid.link/20251031105435.GU4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index 50f75467f73d0..b5dec859bc75a 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -187,12 +187,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); + extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); + + +-static inline unsigned long regs_return_value(struct pt_regs *regs) ++static __always_inline unsigned long regs_return_value(struct pt_regs *regs) + { + return regs->ax; + } + +-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) ++static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) + { + regs->ax = rc; + } +@@ -277,34 +277,34 @@ static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) + } + #endif + +-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline unsigned long instruction_pointer(struct pt_regs *regs) ++static __always_inline unsigned long instruction_pointer(struct pt_regs *regs) + { + return regs->ip; + } + +-static inline void instruction_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void instruction_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->ip = val; + } + +-static inline unsigned long frame_pointer(struct pt_regs *regs) ++static __always_inline unsigned long frame_pointer(struct pt_regs *regs) + { + return regs->bp; + } + +-static inline unsigned long user_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long user_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline void user_stack_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->sp = val; + } +-- +2.51.0 + diff --git a/queue-6.6/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch b/queue-6.6/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch new file mode 100644 index 0000000000..ef13293e72 --- /dev/null +++ b/queue-6.6/acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch @@ -0,0 +1,59 @@ +From 2fa32f697fca15d9b165b976a682f970e7b2f364 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 13:43:19 +0300 +Subject: ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() + only + +From: Sakari Ailus + +[ Upstream commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 ] + +Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode +property API is somewhat problematic as the latter is used in the +impelementation of the former. Instead of using +fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call +acpi_get_next_subnode() directly instead. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20251001104320.1272752-3-sakari.ailus@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 1b8f3958b0edb..6bb85c12b5a02 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1370,7 +1370,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + + if (!prev) { + do { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + /* + * The names of the port nodes begin with "port@" + * followed by the number of the port node and they also +@@ -1388,13 +1388,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( + if (!port) + return NULL; + +- endpoint = fwnode_get_next_child_node(port, prev); ++ endpoint = acpi_get_next_subnode(port, prev); + while (!endpoint) { +- port = fwnode_get_next_child_node(fwnode, port); ++ port = acpi_get_next_subnode(fwnode, port); + if (!port) + break; + if (is_acpi_graph_node(port, "port")) +- endpoint = fwnode_get_next_child_node(port, NULL); ++ endpoint = acpi_get_next_subnode(port, NULL); + } + + /* +-- +2.51.0 + diff --git a/queue-6.6/acpica-avoid-walking-the-namespace-if-start_node-is-.patch b/queue-6.6/acpica-avoid-walking-the-namespace-if-start_node-is-.patch new file mode 100644 index 0000000000..d6060dd054 --- /dev/null +++ b/queue-6.6/acpica-avoid-walking-the-namespace-if-start_node-is-.patch @@ -0,0 +1,63 @@ +From 31057ae0d4943311f4a118c48e967977fab25755 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:14:38 +0800 +Subject: ACPICA: Avoid walking the Namespace if start_node is NULL + +From: Cryolitia PukNgae + +[ Upstream commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 ] + +Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace +if it is not there") fixed the situation when both start_node and +acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed +on Honor Magicbook 14 Pro [1]. + +That happens due to the access to the member of parent_node in +acpi_ns_get_next_node(). The NULL pointer dereference will always +happen, no matter whether or not the start_node is equal to +ACPI_ROOT_OBJECT, so move the check of start_node being NULL +out of the if block. + +Unfortunately, all the attempts to contact Honor have failed, they +refused to provide any technical support for Linux. + +The bad DSDT table's dump could be found on GitHub [2]. + +DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025 + +Link: https://github.com/acpica/acpica/commit/1c1b57b9eba4554cb132ee658dd942c0210ed20d +Link: https://gist.github.com/Cryolitia/a860ffc97437dcd2cd988371d5b73ed7 [1] +Link: https://github.com/denis-bb/honor-fmb-p-dsdt [2] +Signed-off-by: Cryolitia PukNgae +Reviewed-by: WangYuli +[ rjw: Subject adjustment, changelog edits ] +Link: https://patch.msgid.link/20251125-acpica-v1-1-99e63b1b25f8@linux.dev +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/nswalk.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c +index eee396a77baec..1b000ccbf8e1f 100644 +--- a/drivers/acpi/acpica/nswalk.c ++++ b/drivers/acpi/acpica/nswalk.c +@@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type, + + if (start_node == ACPI_ROOT_OBJECT) { + start_node = acpi_gbl_root_node; +- if (!start_node) { +- return_ACPI_STATUS(AE_NO_NAMESPACE); +- } ++ } ++ ++ /* Avoid walking the namespace if the StartNode is NULL */ ++ ++ if (!start_node) { ++ return_ACPI_STATUS(AE_NO_NAMESPACE); + } + + /* Null child means "get first node" */ +-- +2.51.0 + diff --git a/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch b/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch new file mode 100644 index 0000000000..5c1dac8101 --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch @@ -0,0 +1,67 @@ +From b05aaf1894ca459074519bd0ad60c1946a2a92d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 15:33:38 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE + +From: Gongwei Li + +[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ] + +Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3533 Rev= 1.10 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Gongwei Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 798537ee56a5f..7bc7ee4eebd30 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -498,6 +498,8 @@ static const struct usb_device_id quirks_table[] = { + /* Realtek 8821CE Bluetooth devices */ + { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | +-- +2.51.0 + diff --git a/queue-6.6/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch b/queue-6.6/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch new file mode 100644 index 0000000000..8a898f1929 --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch @@ -0,0 +1,67 @@ +From f588c002b8cf64749195199eda0df4c073d38f52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 16:46:47 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 2b89/6275 for RTL8761BUV + +From: Chingbin Li + +[ Upstream commit 8dbbb5423c0802ec21266765de80fd491868fab1 ] + +Add VID 2b89 & PID 6275 for Realtek RTL8761BUV USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=2b89 ProdID=6275 Rev= 2.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00E04C239987 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Chingbin Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 74d264b64b534..798537ee56a5f 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -735,6 +735,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x2b89, 0x6275), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Additional Realtek 8821AE Bluetooth devices */ + { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, +-- +2.51.0 + diff --git a/queue-6.6/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch b/queue-6.6/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch new file mode 100644 index 0000000000..ed4f7a80ce --- /dev/null +++ b/queue-6.6/bpf-arm64-do-not-audit-capability-check-in-do_jit.patch @@ -0,0 +1,56 @@ +From 573a853e5a1a2022d3696b1b3f81fdcd01e11bf3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Dec 2025 13:59:16 +0100 +Subject: bpf, arm64: Do not audit capability check in do_jit() + +From: Ondrej Mosnacek + +[ Upstream commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c ] + +Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit +capability check in do_jit()"), change the capable() call to +ns_capable_noaudit() in order to avoid spurious SELinux denials in audit +log. + +The commit log from that commit applies here as well: +""" +The failure of this check only results in a security mitigation being +applied, slightly affecting performance of the compiled BPF program. It +doesn't result in a failed syscall, an thus auditing a failed LSM +permission check for it is unwanted. For example with SELinux, it causes +a denial to be reported for confined processes running as root, which +tends to be flagged as a problem to be fixed in the policy. Yet +dontauditing or allowing CAP_SYS_ADMIN to the domain may not be +desirable, as it would allow/silence also other checks - either going +against the principle of least privilege or making debugging potentially +harder. + +Fix it by changing it from capable() to ns_capable_noaudit(), which +instructs the LSMs to not audit the resulting denials. +""" + +Fixes: f300769ead03 ("arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users") +Signed-off-by: Ondrej Mosnacek +Link: https://lore.kernel.org/r/20251204125916.441021-1-omosnace@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + arch/arm64/net/bpf_jit_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index d8012d1a2e152..f11de7484ced8 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -666,7 +666,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) + arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) + return; + +- if (capable(CAP_SYS_ADMIN)) ++ if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) + return; + + if (supports_clearbhb(SCOPE_SYSTEM)) { +-- +2.51.0 + diff --git a/queue-6.6/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch b/queue-6.6/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch new file mode 100644 index 0000000000..f85009cbe2 --- /dev/null +++ b/queue-6.6/btrfs-do-not-skip-logging-new-dentries-when-logging-.patch @@ -0,0 +1,72 @@ +From 3859e1e8ec77e8cc2ea9f835dacf6078a42031ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 17:02:00 +0000 +Subject: btrfs: do not skip logging new dentries when logging a new name + +From: Filipe Manana + +[ Upstream commit 5630f7557de61264ccb4f031d4734a1a97eaed16 ] + +When we are logging a directory and the log context indicates that we +are logging a new name for some other file (that is or was inside that +directory), we skip logging the inodes for new dentries in the directory. + +This is ok most of the time, but if after the rename or link operation +that triggered the logging of that directory, we have an explicit fsync +of that directory without the directory inode being evicted and reloaded, +we end up never logging the inodes for the new dentries that we found +during the new name logging, as the next directory fsync will only process +dentries that were added after the last time we logged the directory (we +are doing an incremental directory logging). + +So make sure we always log new dentries for a directory even if we are +in a context of logging a new name. + +We started skipping logging inodes for new dentries as of commit +c48792c6ee7a ("btrfs: do not log new dentries when logging that a new name +exists") and it was fine back then, because when logging a directory we +always iterated over all the directory entries (for leaves changed in the +current transaction) so a subsequent fsync would always log anything that +was previously skipped while logging a directory when logging a new name +(with btrfs_log_new_name()). But later support for incrementally logging +a directory was added in commit dc2872247ec0 ("btrfs: keep track of the +last logged keys when logging a directory"), to avoid checking all dir +items every time we log a directory, so the check to skip dentry logging +added in the first commit should have been removed when the incremental +support for logging a directory was added. + +A test case for fstests will follow soon. + +Reported-by: Vyacheslav Kovalevsky +Link: https://lore.kernel.org/linux-btrfs/84c4e713-85d6-42b9-8dcf-0722ed26cb05@gmail.com/ +Fixes: dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory") +Reviewed-by: Boris Burkov +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tree-log.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 256116a6e07c6..ca01f2daac6e4 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -5526,14 +5526,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, + struct btrfs_inode *curr_inode = start_inode; + int ret = 0; + +- /* +- * If we are logging a new name, as part of a link or rename operation, +- * don't bother logging new dentries, as we just want to log the names +- * of an inode and that any new parents exist. +- */ +- if (ctx->logging_new_name) +- return 0; +- + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.6/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch b/queue-6.6/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch new file mode 100644 index 0000000000..6f3fc267c4 --- /dev/null +++ b/queue-6.6/btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch @@ -0,0 +1,49 @@ +From 45fa3df1dae0b7c9f0516ac15a7eb6376c5534b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 18:49:56 +1030 +Subject: btrfs: fix a potential path leak in print_data_reloc_error() + +From: Qu Wenruo + +[ Upstream commit 313ef70a9f0f637a09d9ef45222f5bdcf30a354b ] + +Inside print_data_reloc_error(), if extent_from_logical() failed we +return immediately. + +However there are the following cases where extent_from_logical() can +return error but still holds a path: + +- btrfs_search_slot() returned 0 + +- No backref item found in extent tree + +- No flags_ret provided + This is not possible in this call site though. + +So for the above two cases, we can return without releasing the path, +causing extent buffer leaks. + +Fixes: b9a9a85059cd ("btrfs: output affected files when relocation fails") +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index b1be3e0fe7282..68bb5079aef74 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -266,6 +266,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off + if (ret < 0) { + btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d", + logical, ret); ++ btrfs_release_path(&path); + return; + } + eb = path.nodes[0]; +-- +2.51.0 + diff --git a/queue-6.6/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch b/queue-6.6/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch new file mode 100644 index 0000000000..2b4bb7978f --- /dev/null +++ b/queue-6.6/btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch @@ -0,0 +1,51 @@ +From 2555df8c97a936baae31c0b1ea44401270cc2f71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 18:58:07 +0530 +Subject: btrfs: fix memory leak of fs_devices in degraded seed device path + +From: Deepanshu Kartikey + +[ Upstream commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 ] + +In open_seed_devices(), when find_fsid() fails and we're in DEGRADED +mode, a new fs_devices is allocated via alloc_fs_devices() but is never +added to the seed_list before returning. This contrasts with the normal +path where fs_devices is properly added via list_add(). + +If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), +the cleanup code iterates seed_list to free seed devices, but this +orphaned fs_devices is never found and never freed, causing a memory +leak. Any devices allocated via add_missing_dev() and attached to this +fs_devices are also leaked. + +Fix this by adding the newly allocated fs_devices to seed_list in the +degraded path, consistent with the normal path. + +Fixes: 5f37583569442 ("Btrfs: move the missing device to its own fs device list") +Reported-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=eadd98df8bceb15d7fed +Tested-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com +Reviewed-by: Qu Wenruo +Signed-off-by: Deepanshu Kartikey +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/volumes.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 1eb543602ff12..8207b0b4c43a0 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -6966,6 +6966,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, + + fs_devices->seeding = true; + fs_devices->opened = 1; ++ list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); + return fs_devices; + } + +-- +2.51.0 + diff --git a/queue-6.6/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch b/queue-6.6/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch new file mode 100644 index 0000000000..5f1944218b --- /dev/null +++ b/queue-6.6/btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch @@ -0,0 +1,90 @@ +From 13321e2f5dd033ea1f6a14703df063d8d12a6228 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 12:51:09 +1030 +Subject: btrfs: scrub: always update btrfs_scrub_progress::last_physical + +From: Qu Wenruo + +[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ] + +[BUG] +When a scrub failed immediately without any byte scrubbed, the returned +btrfs_scrub_progress::last_physical will always be 0, even if there is a +non-zero @start passed into btrfs_scrub_dev() for resume cases. + +This will reset the progress and make later scrub resume start from the +beginning. + +[CAUSE] +The function btrfs_scrub_dev() accepts a @progress parameter to copy its +updated progress to the caller, there are cases where we either don't +touch progress::last_physical at all or copy 0 into last_physical: + +- last_physical not updated at all + If some error happened before scrubbing any super block or chunk, we + will not copy the progress, leaving the @last_physical untouched. + + E.g. failed to allocate @sctx, scrubbing a missing device or even + there is already a running scrub and so on. + + All those cases won't touch @progress at all, resulting the + last_physical untouched and will be left as 0 for most cases. + +- Error out before scrubbing any bytes + In those case we allocated @sctx, and sctx->stat.last_physical is all + zero (initialized by kvzalloc()). + Unfortunately some critical errors happened during + scrub_enumerate_chunks() or scrub_supers() before any stripe is really + scrubbed. + + In that case although we will copy sctx->stat back to @progress, since + no byte is really scrubbed, last_physical will be overwritten to 0. + +[FIX] +Make sure the parameter @progress always has its @last_physical member +updated to @start parameter inside btrfs_scrub_dev(). + +At the very beginning of the function, set @progress->last_physical to +@start, so that even if we error out without doing progress copying, +last_physical is still at @start. + +Then after we got @sctx allocated, set sctx->stat.last_physical to +@start, this will make sure even if we didn't get any byte scrubbed, at +the progress copying stage the @last_physical is not left as zero. + +This should resolve the resume progress reset problem. + +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index a69dce114c5ba..3338e2e7a9a02 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -2858,6 +2858,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + unsigned int nofs_flag; + bool need_commit = false; + ++ /* Set the basic fallback @last_physical before we got a sctx. */ ++ if (progress) ++ progress->last_physical = start; ++ + if (btrfs_fs_closing(fs_info)) + return -EAGAIN; + +@@ -2876,6 +2880,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, + sctx = scrub_setup_ctx(fs_info, is_dev_replace); + if (IS_ERR(sctx)) + return PTR_ERR(sctx); ++ sctx->stat.last_physical = start; + + ret = scrub_workers_get(fs_info); + if (ret) +-- +2.51.0 + diff --git a/queue-6.6/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch b/queue-6.6/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch new file mode 100644 index 0000000000..b58a94244c --- /dev/null +++ b/queue-6.6/cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch @@ -0,0 +1,35 @@ +From 62295dd3b326acf42f033124c4a48278b71b53a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 16:00:48 +0800 +Subject: cpufreq: dt-platdev: Add JH7110S SOC to the allowlist + +From: Hal Feng + +[ Upstream commit 6e7970cab51d01b8f7c56f120486c571c22e1b80 ] + +Add the compatible strings for supporting the generic +cpufreq driver on the StarFive JH7110S SoC. + +Signed-off-by: Hal Feng +Reviewed-by: Heinrich Schuchardt +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index c58c1defd7458..8b53388280d73 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -87,6 +87,7 @@ static const struct of_device_id allowlist[] __initconst = { + { .compatible = "st-ericsson,u9540", }, + + { .compatible = "starfive,jh7110", }, ++ { .compatible = "starfive,jh7110s", }, + + { .compatible = "ti,omap2", }, + { .compatible = "ti,omap4", }, +-- +2.51.0 + diff --git a/queue-6.6/cpufreq-s5pv210-fix-refcount-leak.patch b/queue-6.6/cpufreq-s5pv210-fix-refcount-leak.patch new file mode 100644 index 0000000000..dcaacac589 --- /dev/null +++ b/queue-6.6/cpufreq-s5pv210-fix-refcount-leak.patch @@ -0,0 +1,62 @@ +From d1d1e32d8fddbb9196048dd515b2c07df17200aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 03:31:17 +0800 +Subject: cpufreq: s5pv210: fix refcount leak + +From: Shuhao Fu + +[ Upstream commit 2de5cb96060a1664880d65b120e59485a73588a8 ] + +In function `s5pv210_cpu_init`, a possible refcount inconsistency has +been identified, causing a resource leak. + +Why it is a bug: +1. For every clk_get, there should be a matching clk_put on every +successive error handling path. +2. After calling `clk_get(dmc1_clk)`, variable `dmc1_clk` will not be +freed even if any error happens. + +How it is fixed: For every failed path, an extra goto label is added to +ensure `dmc1_clk` will be freed regardlessly. + +Signed-off-by: Shuhao Fu +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c +index 76c888ed8d160..d2fa42beae9c2 100644 +--- a/drivers/cpufreq/s5pv210-cpufreq.c ++++ b/drivers/cpufreq/s5pv210-cpufreq.c +@@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + + if (policy->cpu != 0) { + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* +@@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { + pr_err("CPUFreq doesn't support this memory type\n"); + ret = -EINVAL; +- goto out_dmc1; ++ goto out; + } + + /* Find current refresh counter and frequency each DMC */ +@@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) + cpufreq_generic_init(policy, s5pv210_freq_table, 40000); + return 0; + ++out: ++ clk_put(dmc1_clk); + out_dmc1: + clk_put(dmc0_clk); + out_dmc0: +-- +2.51.0 + diff --git a/queue-6.6/cpuidle-menu-use-residency-threshold-in-polling-stat.patch b/queue-6.6/cpuidle-menu-use-residency-threshold-in-polling-stat.patch new file mode 100644 index 0000000000..03895e89e7 --- /dev/null +++ b/queue-6.6/cpuidle-menu-use-residency-threshold-in-polling-stat.patch @@ -0,0 +1,99 @@ +From 1a1f162da886f68cb985381532370b22938c16be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 07:09:54 +0530 +Subject: cpuidle: menu: Use residency threshold in polling state override + decisions + +From: Aboorva Devarajan + +[ Upstream commit 07d815701274d156ad8c7c088a52e01642156fb8 ] + +On virtualized PowerPC (pseries) systems, where only one polling state +(Snooze) and one deep state (CEDE) are available, selecting CEDE when +the predicted idle duration is less than the target residency of CEDE +state can hurt performance. In such cases, the entry/exit overhead of +CEDE outweighs the power savings, leading to unnecessary state +transitions and higher latency. + +Menu governor currently contains a special-case rule that prioritizes +the first non-polling state over polling, even when its target residency +is much longer than the predicted idle duration. On PowerPC/pseries, +where the gap between the polling state (Snooze) and the first non-polling +state (CEDE) is large, this behavior causes performance regressions. + +Refine that special case by adding an extra requirement: the first +non-polling state can only be chosen if its target residency is below +the defined RESIDENCY_THRESHOLD_NS. If this condition is not satisfied, +polling is allowed instead, avoiding suboptimal non-polling state +entries. + +This change is limited to the single special-case rule for the first +non-polling state. The general non-polling state selection logic in the +menu governor remains unchanged. + +Performance improvement observed with pgbench on PowerPC (pseries) +system: ++---------------------------+------------+------------+------------+ +| Metric | Baseline | Patched | Change (%) | ++---------------------------+------------+------------+------------+ +| Transactions/sec (TPS) | 495,210 | 536,982 | +8.45% | +| Avg latency (ms) | 0.163 | 0.150 | -7.98% | ++---------------------------+------------+------------+------------+ + +CPUIdle state usage: ++--------------+--------------+-------------+ +| Metric | Baseline | Patched | ++--------------+--------------+-------------+ +| Total usage | 12,735,820 | 13,918,442 | +| Above usage | 11,401,520 | 1,598,210 | +| Below usage | 20,145 | 702,395 | ++--------------+--------------+-------------+ + +Above/Total and Below/Total usage percentages: ++------------------------+-----------+---------+ +| Metric | Baseline | Patched | ++------------------------+-----------+---------+ +| Above % (Above/Total) | 89.56% | 11.49% | +| Below % (Below/Total) | 0.16% | 5.05% | +| Total cpuidle miss (%) | 89.72% | 16.54% | ++------------------------+-----------+---------+ + +The results indicate that restricting CEDE selection to cases where +its residency matches the predicted idle time reduces mispredictions, +lowers unnecessary state transitions, and improves overall throughput. + +Reviewed-by: Christian Loehle +Signed-off-by: Aboorva Devarajan +[ rjw: Changelog edits, rebase ] +Link: https://patch.msgid.link/20251006013954.17972-1-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/governors/menu.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index 8c591dde61023..27010eee6d1bc 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -354,12 +354,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + } + + /* +- * Use a physical idle state, not busy polling, unless a timer +- * is going to trigger soon enough or the exit latency of the +- * idle state in question is greater than the predicted idle +- * duration. ++ * Use a physical idle state instead of busy polling so long as ++ * its target residency is below the residency threshold, its ++ * exit latency is not greater than the predicted idle duration, ++ * and the next timer doesn't expire soon. + */ + if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && ++ s->target_residency_ns < RESIDENCY_THRESHOLD_NS && + s->target_residency_ns <= data->next_timer_ns && + s->exit_latency_ns <= predicted_ns) { + predicted_ns = s->target_residency_ns; +-- +2.51.0 + diff --git a/queue-6.6/fs-ntfs3-support-timestamps-prior-to-epoch.patch b/queue-6.6/fs-ntfs3-support-timestamps-prior-to-epoch.patch new file mode 100644 index 0000000000..223558bba8 --- /dev/null +++ b/queue-6.6/fs-ntfs3-support-timestamps-prior-to-epoch.patch @@ -0,0 +1,43 @@ +From b3363f6f729a7d42fb41958d69388b775d70e695 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Sep 2025 11:48:48 +0300 +Subject: fs/ntfs3: Support timestamps prior to epoch + +From: Konstantin Komarov + +[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ] + +Before it used an unsigned 64-bit type, which prevented proper handling +of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to +support pre-epoch timestamps. The issue was caught by xfstests. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/ntfs_fs.h | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index 72810d8f62ee9..31f57ee9a1a9b 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -990,11 +990,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts) + */ + static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) + { +- u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; ++ s32 t32; ++ /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ ++ s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; + +- // WARNING: do_div changes its first argument(!) +- ts->tv_nsec = do_div(t, _100ns2seconds) * 100; +- ts->tv_sec = t; ++ ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); ++ ts->tv_nsec = t32 * 100; + } + + static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb) +-- +2.51.0 + diff --git a/queue-6.6/gfs2-fix-remote-evict-for-read-only-filesystems.patch b/queue-6.6/gfs2-fix-remote-evict-for-read-only-filesystems.patch new file mode 100644 index 0000000000..b0df288b10 --- /dev/null +++ b/queue-6.6/gfs2-fix-remote-evict-for-read-only-filesystems.patch @@ -0,0 +1,41 @@ +From d01842ab518ad98e1d5dcdff02dcb08b3922cb2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 12:14:24 +0000 +Subject: gfs2: fix remote evict for read-only filesystems + +From: Andreas Gruenbacher + +[ Upstream commit 64c10ed9274bc46416f502afea48b4ae11279669 ] + +When a node tries to delete an inode, it first requests exclusive access +to the iopen glock. This triggers demote requests on all remote nodes +currently holding the iopen glock. To satisfy those requests, the +remote nodes evict the inode in question, or they poke the corresponding +inode glock to signal that the inode is still in active use. + +This behavior doesn't depend on whether or not a filesystem is +read-only, so remove the incorrect read-only check. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/glops.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c +index 1c854d4e2d491..4a169c60bce65 100644 +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -640,8 +640,7 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote) + struct gfs2_inode *ip = gl->gl_object; + struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; + +- if (!remote || sb_rdonly(sdp->sd_vfs) || +- test_bit(SDF_KILL, &sdp->sd_flags)) ++ if (!remote || test_bit(SDF_KILL, &sdp->sd_flags)) + return; + + if (gl->gl_demote_state == LM_ST_UNLOCKED && +-- +2.51.0 + diff --git a/queue-6.6/gfs2-fix-use-of-bio_chain.patch b/queue-6.6/gfs2-fix-use-of-bio_chain.patch new file mode 100644 index 0000000000..00d9246464 --- /dev/null +++ b/queue-6.6/gfs2-fix-use-of-bio_chain.patch @@ -0,0 +1,37 @@ +From 021773c453c94eb63a92f031558b5145dc6947c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 21:19:52 +0000 +Subject: gfs2: Fix use of bio_chain + +From: Andreas Gruenbacher + +[ Upstream commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941 ] + +In gfs2_chain_bio(), the call to bio_chain() has its arguments swapped. +The result is leaked bios and incorrect synchronization (only the last +bio will actually be waited for). This code is only used during mount +and filesystem thaw, so the bug normally won't be noticeable. + +Reported-by: Stephen Zhang +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/lops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c +index 483f698070622..b25b741e3c96a 100644 +--- a/fs/gfs2/lops.c ++++ b/fs/gfs2/lops.c +@@ -492,7 +492,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) + new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); + bio_clone_blkg_association(new, prev); + new->bi_iter.bi_sector = bio_end_sector(prev); +- bio_chain(new, prev); ++ bio_chain(prev, new); + submit_bio(prev); + return new; + } +-- +2.51.0 + diff --git a/queue-6.6/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch b/queue-6.6/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch new file mode 100644 index 0000000000..09d4cdb861 --- /dev/null +++ b/queue-6.6/hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch @@ -0,0 +1,91 @@ +From e6f2756e58eb65c69f42e1009a58344dfd2bfa77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 17:39:12 +0800 +Subject: hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create + +From: Yang Chenzhi + +[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ] + +When sync() and link() are called concurrently, both threads may +enter hfs_bnode_find() without finding the node in the hash table +and proceed to create it. + +Thread A: + hfsplus_write_inode() + -> hfsplus_write_system_inode() + -> hfs_btree_write() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +Thread B: + hfsplus_create_cat() + -> hfs_brec_insert() + -> hfs_bnode_split() + -> hfs_bmap_alloc() + -> hfs_bnode_find(tree, 0) + -> __hfs_bnode_create(tree, 0) + +In this case, thread A creates the bnode, sets refcnt=1, and hashes it. +Thread B also tries to create the same bnode, notices it has already +been inserted, drops its own instance, and uses the hashed one without +getting the node. + +``` + + node2 = hfs_bnode_findhash(tree, cnid); + if (!node2) { <- Thread A + hash = hfs_bnode_hash(cnid); + node->next_hash = tree->node_hash[hash]; + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { <- Thread B + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, + !test_bit(HFS_BNODE_NEW, &node2->flags)); + return node2; + } +``` + +However, hfs_bnode_find() requires each call to take a reference. +Here both threads end up setting refcnt=1. When they later put the node, +this triggers: + +BUG_ON(!atomic_read(&node->refcnt)) + +In this scenario, Thread B in fact finds the node in the hash table +rather than creating a new one, and thus must take a reference. + +Fix this by calling hfs_bnode_get() when reusing a bnode newly created by +another thread to ensure the refcount is updated correctly. + +A similar bug was fixed in HFS long ago in commit +a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") +but the same issue remained in HFS+ until now. + +Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com +Signed-off-by: Yang Chenzhi +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index aa095e6fb20e8..c0089849be50e 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -481,6 +481,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) + tree->node_hash[hash] = node; + tree->node_hash_cnt++; + } else { ++ hfs_bnode_get(node2); + spin_unlock(&tree->hash_lock); + kfree(node); + wait_event(node2->lock_wq, +-- +2.51.0 + diff --git a/queue-6.6/hfsplus-fix-volume-corruption-issue-for-generic-070.patch b/queue-6.6/hfsplus-fix-volume-corruption-issue-for-generic-070.patch new file mode 100644 index 0000000000..30757f30df --- /dev/null +++ b/queue-6.6/hfsplus-fix-volume-corruption-issue-for-generic-070.patch @@ -0,0 +1,122 @@ +From 9b28085faf03b2c3dda66a0041a4393cbbdc80e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:12:30 -0700 +Subject: hfsplus: fix volume corruption issue for generic/070 + +From: Viacheslav Dubeyko + +[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ] + +The xfstests' test-case generic/070 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent +(see xfstests-dev/results//generic/070.full for details) + +Ran: generic/070 +Failures: generic/070 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop50 +** /dev/loop50 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +Unused node is not erased (node = 1) +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 +CBTStat = 0x0000 CatStat = 0x00000000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is test +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume test was repaired successfully. + +It is possible to see that fsck.hfsplus detected not +erased and unused node for the case of extents overflow file. +The HFS+ logic has special method that defines if the node +should be erased: + +bool hfs_bnode_need_zeroout(struct hfs_btree *tree) +{ + struct super_block *sb = tree->inode->i_sb; + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + + return tree->cnid == HFSPLUS_CAT_CNID && + volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; +} + +However, it is possible to see that this method works +only for the case of catalog file. But debugging of the issue +has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been +requested for the extents overflow file too: + +catalog file +kernel: hfsplus: node 4, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800 + +extents overflow file +kernel: hfsplus: node 1, num_recs 0, flags 0x10 +kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800 + +This patch modifies the hfs_bnode_need_zeroout() by checking +only volume_attr but not the b-tree ID because node zeroing +can be requested for all HFS+ b-tree types. + +sudo ./check generic/070 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/070 33s ... 34s +Ran: generic/070 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/bnode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c +index 407d5152eb411..aa095e6fb20e8 100644 +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -704,6 +704,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); + +- return tree->cnid == HFSPLUS_CAT_CNID && +- volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; ++ return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + } +-- +2.51.0 + diff --git a/queue-6.6/hfsplus-fix-volume-corruption-issue-for-generic-073.patch b/queue-6.6/hfsplus-fix-volume-corruption-issue-for-generic-073.patch new file mode 100644 index 0000000000..2cade055e5 --- /dev/null +++ b/queue-6.6/hfsplus-fix-volume-corruption-issue-for-generic-073.patch @@ -0,0 +1,125 @@ +From eca56149d5f13580303c2685f6381581571b91f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:25:23 -0800 +Subject: hfsplus: fix volume corruption issue for generic/073 + +From: Viacheslav Dubeyko + +[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ] + +The xfstests' test-case generic/073 leaves HFS+ volume +in corrupted state: + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent +(see XFSTESTS-2/xfstests-dev/results//generic/073.full for details) + +Ran: generic/073 +Failures: generic/073 +Failed 1 of 1 tests + +sudo fsck.hfsplus -d /dev/loop51 +** /dev/loop51 +Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. +Executing fsck_hfs (version 540.1-Linux). +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +Invalid directory item count +(It should be 1 instead of 0) +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 +CBTStat = 0x0000 CatStat = 0x00004000 +** Repairing volume. +** Rechecking volume. +** Checking non-journaled HFS Plus Volume. +The volume name is untitled +** Checking extents overflow file. +** Checking catalog file. +** Checking multi-linked files. +** Checking catalog hierarchy. +** Checking extended attributes file. +** Checking volume bitmap. +** Checking volume information. +** The volume untitled was repaired successfully. + +The test is doing these steps on final phase: + +mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 +$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo + +So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ +logic decrements the number of entries in testdir_1 and increments number of +entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not +for testdir_2. As a result, this is the reason why fsck.hfsplus detects the +volume corruption afterwards. + +This patch fixes the issue by means of adding the +hfsplus_cat_write_inode() call for old_dir and new_dir in +hfsplus_rename() after the successful ending of +hfsplus_rename_cat(). This method makes modification of in-core +inode objects for old_dir and new_dir but it doesn't save these +modifications in Catalog File's entries. It was expected that +hfsplus_write_inode() will save these modifications afterwards. +However, because generic/073 does fsync only for testdir_1 and foo +then testdir_2 modification hasn't beed saved into Catalog File's +entry and it was flushed without this modification. And it was +detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog +File all modified entries and correct state of Catalog File will +be flushed during hfsplus_file_fsync() call. Finally, it makes +fsck.hfsplus happy. + +sudo ./check generic/073 +FSTYP -- hfsplus +PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 +MKFS_OPTIONS -- /dev/loop51 +MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch + +generic/073 32s ... 32s +Ran: generic/073 +Passed all 1 tests + +Signed-off-by: Viacheslav Dubeyko +cc: John Paul Adrian Glaubitz +cc: Yangtao Li +cc: linux-fsdevel@vger.kernel.org +Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/dir.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c +index f5c4b3e31a1c2..33154c720a4e9 100644 +--- a/fs/hfsplus/dir.c ++++ b/fs/hfsplus/dir.c +@@ -552,8 +552,13 @@ static int hfsplus_rename(struct mnt_idmap *idmap, + res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, + old_dir, &old_dentry->d_name, + new_dir, &new_dentry->d_name); +- if (!res) ++ if (!res) { + new_dentry->d_fsdata = old_dentry->d_fsdata; ++ ++ res = hfsplus_cat_write_inode(old_dir); ++ if (!res) ++ res = hfsplus_cat_write_inode(new_dir); ++ } + return res; + } + +-- +2.51.0 + diff --git a/queue-6.6/hfsplus-verify-inode-mode-when-loading-from-disk.patch b/queue-6.6/hfsplus-verify-inode-mode-when-loading-from-disk.patch new file mode 100644 index 0000000000..ad5a856381 --- /dev/null +++ b/queue-6.6/hfsplus-verify-inode-mode-when-loading-from-disk.patch @@ -0,0 +1,105 @@ +From 42e3c79b7472acee502e33b1ce987156721fced4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 18:18:54 +0900 +Subject: hfsplus: Verify inode mode when loading from disk + +From: Tetsuo Handa + +[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ] + +syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when +the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted. + +According to [1], the permissions field was treated as reserved in Mac OS +8 and 9. According to [2], the reserved field was explicitly initialized +with 0, and that field must remain 0 as long as reserved. Therefore, when +the "mode" field is not 0 (i.e. no longer reserved), the file must be +S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ +S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlusPermissions [1] +Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#ReservedAndPadFields [2] +Signed-off-by: Tetsuo Handa +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA.ne.jp +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index 73ff191ff2adc..2619e5371ec9c 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -183,13 +183,29 @@ const struct dentry_operations hfsplus_dentry_operations = { + .d_compare = hfsplus_compare_dentry, + }; + +-static void hfsplus_get_perms(struct inode *inode, +- struct hfsplus_perm *perms, int dir) ++static int hfsplus_get_perms(struct inode *inode, ++ struct hfsplus_perm *perms, int dir) + { + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + u16 mode; + + mode = be16_to_cpu(perms->mode); ++ if (dir) { ++ if (mode && !S_ISDIR(mode)) ++ goto bad_type; ++ } else if (mode) { ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ case S_IFLNK: ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: ++ break; ++ default: ++ goto bad_type; ++ } ++ } + + i_uid_write(inode, be32_to_cpu(perms->owner)); + if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) +@@ -215,6 +231,10 @@ static void hfsplus_get_perms(struct inode *inode, + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; ++ return 0; ++bad_type: ++ pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); ++ return -EIO; + } + + static int hfsplus_file_open(struct inode *inode, struct file *file) +@@ -519,7 +539,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); +- hfsplus_get_perms(inode, &folder->permissions, 1); ++ res = hfsplus_get_perms(inode, &folder->permissions, 1); ++ if (res) ++ goto out; + set_nlink(inode, 1); + inode->i_size = 2 + be32_to_cpu(folder->valence); + inode->i_atime = hfsp_mt2ut(folder->access_date); +@@ -547,7 +569,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + + hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? + &file->rsrc_fork : &file->data_fork); +- hfsplus_get_perms(inode, &file->permissions, 0); ++ res = hfsplus_get_perms(inode, &file->permissions, 0); ++ if (res) ++ goto out; + set_nlink(inode, 1); + if (S_ISREG(inode->i_mode)) { + if (file->permissions.dev) +-- +2.51.0 + diff --git a/queue-6.6/iomap-account-for-unaligned-end-offsets-when-truncat.patch b/queue-6.6/iomap-account-for-unaligned-end-offsets-when-truncat.patch new file mode 100644 index 0000000000..c30eb1170a --- /dev/null +++ b/queue-6.6/iomap-account-for-unaligned-end-offsets-when-truncat.patch @@ -0,0 +1,74 @@ +From 023d1b945c0dd86ca8eda7c79568b75be336d45c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 11:36:51 -0800 +Subject: iomap: account for unaligned end offsets when truncating read range + +From: Joanne Koong + +[ Upstream commit 9d875e0eef8ec15b6b1da0cb9a0f8ed13efee89e ] + +The end position to start truncating from may be at an offset into a +block, which under the current logic would result in overtruncation. + +Adjust the calculation to account for unaligned end offsets. + +Signed-off-by: Joanne Koong +Link: https://patch.msgid.link/20251111193658.3495942-3-joannelkoong@gmail.com +Reviewed-by: Christoph Hellwig +Reviewed-by: Darrick J. Wong +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 13a5f4422c797..7e9480150d61e 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -188,6 +188,22 @@ static void ifs_free(struct folio *folio) + kfree(ifs); + } + ++/* ++ * Calculate how many bytes to truncate based off the number of blocks to ++ * truncate and the end position to start truncating from. ++ */ ++static size_t iomap_bytes_to_truncate(loff_t end_pos, unsigned block_bits, ++ unsigned blocks_truncated) ++{ ++ unsigned block_size = 1 << block_bits; ++ unsigned block_offset = end_pos & (block_size - 1); ++ ++ if (!block_offset) ++ return blocks_truncated << block_bits; ++ ++ return ((blocks_truncated - 1) << block_bits) + block_offset; ++} ++ + /* + * Calculate the range inside the folio that we actually need to read. + */ +@@ -233,7 +249,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + /* truncate len if we find any trailing uptodate block(s) */ + while (++i <= last) { + if (ifs_block_is_uptodate(ifs, i)) { +- plen -= (last - i + 1) * block_size; ++ plen -= iomap_bytes_to_truncate(*pos + plen, ++ block_bits, last - i + 1); + last = i - 1; + break; + } +@@ -249,7 +266,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + unsigned end = offset_in_folio(folio, isize - 1) >> block_bits; + + if (first <= end && last > end) +- plen -= (last - end) * block_size; ++ plen -= iomap_bytes_to_truncate(*pos + plen, block_bits, ++ last - end); + } + + *offp = poff; +-- +2.51.0 + diff --git a/queue-6.6/iomap-adjust-read-range-correctly-for-non-block-alig.patch b/queue-6.6/iomap-adjust-read-range-correctly-for-non-block-alig.patch new file mode 100644 index 0000000000..23e54c6c21 --- /dev/null +++ b/queue-6.6/iomap-adjust-read-range-correctly-for-non-block-alig.patch @@ -0,0 +1,67 @@ +From 0418ed84d791136d3634d004ccfe0a9c78228f43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 11:00:42 -0700 +Subject: iomap: adjust read range correctly for non-block-aligned positions + +From: Joanne Koong + +[ Upstream commit 7aa6bc3e8766990824f66ca76c19596ce10daf3e ] + +iomap_adjust_read_range() assumes that the position and length passed in +are block-aligned. This is not always the case however, as shown in the +syzbot generated case for erofs. This causes too many bytes to be +skipped for uptodate blocks, which results in returning the incorrect +position and length to read in. If all the blocks are uptodate, this +underflows length and returns a position beyond the folio. + +Fix the calculation to also take into account the block offset when +calculating how many bytes can be skipped for uptodate blocks. + +Signed-off-by: Joanne Koong +Tested-by: syzbot@syzkaller.appspotmail.com +Reviewed-by: Brian Foster +Reviewed-by: Christoph Hellwig +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 7ffdf0d037fae..13a5f4422c797 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -211,17 +211,24 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, + * to avoid reading in already uptodate ranges. + */ + if (ifs) { +- unsigned int i; ++ unsigned int i, blocks_skipped; + + /* move forward for each leading block marked uptodate */ +- for (i = first; i <= last; i++) { ++ for (i = first; i <= last; i++) + if (!ifs_block_is_uptodate(ifs, i)) + break; +- *pos += block_size; +- poff += block_size; +- plen -= block_size; +- first++; ++ ++ blocks_skipped = i - first; ++ if (blocks_skipped) { ++ unsigned long block_offset = *pos & (block_size - 1); ++ unsigned bytes_skipped = ++ (blocks_skipped << block_bits) - block_offset; ++ ++ *pos += bytes_skipped; ++ poff += bytes_skipped; ++ plen -= bytes_skipped; + } ++ first = i; + + /* truncate len if we find any trailing uptodate block(s) */ + while (++i <= last) { +-- +2.51.0 + diff --git a/queue-6.6/kbuild-use-objtree-for-module-signing-key-path.patch b/queue-6.6/kbuild-use-objtree-for-module-signing-key-path.patch new file mode 100644 index 0000000000..39ac016cc8 --- /dev/null +++ b/queue-6.6/kbuild-use-objtree-for-module-signing-key-path.patch @@ -0,0 +1,58 @@ +From 837bc46e1ab2842bc5c687bb39913ba84cd45682 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 16:34:52 +0000 +Subject: kbuild: Use objtree for module signing key path + +From: Mikhail Malyshev + +[ Upstream commit af61da281f52aba0c5b090bafb3a31c5739850ff ] + +When building out-of-tree modules with CONFIG_MODULE_SIG_FORCE=y, +module signing fails because the private key path uses $(srctree) +while the public key path uses $(objtree). Since signing keys are +generated in the build directory during kernel compilation, both +paths should use $(objtree) for consistency. + +This causes SSL errors like: + SSL error:02001002:system library:fopen:No such file or directory + sign-file: /kernel-src/certs/signing_key.pem + +The issue occurs because: +- sig-key uses: $(srctree)/certs/signing_key.pem (source tree) +- cmd_sign uses: $(objtree)/certs/signing_key.x509 (build tree) + +But both keys are generated in $(objtree) during the build. + +This complements commit 25ff08aa43e37 ("kbuild: Fix signing issue for +external modules") which fixed the scripts path and public key path, +but missed the private key path inconsistency. + +Fixes out-of-tree module signing for configurations with separate +source and build directories (e.g., O=/kernel-out). + +Signed-off-by: Mikhail Malyshev +Reviewed-by: Nathan Chancellor +Tested-by: Nicolas Schier +Link: https://patch.msgid.link/20251015163452.3754286-1-mike.malyshev@gmail.com +Signed-off-by: Nicolas Schier +Signed-off-by: Sasha Levin +--- + scripts/Makefile.modinst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst +index 0afd75472679f..3e8b069a04ff0 100644 +--- a/scripts/Makefile.modinst ++++ b/scripts/Makefile.modinst +@@ -96,7 +96,7 @@ endif + # Don't stop modules_install even if we can't sign external modules. + # + ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) +-sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) ++sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) + else + sig-key := $(CONFIG_MODULE_SIG_KEY) + endif +-- +2.51.0 + diff --git a/queue-6.6/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch b/queue-6.6/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch new file mode 100644 index 0000000000..a25d0847ea --- /dev/null +++ b/queue-6.6/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch @@ -0,0 +1,106 @@ +From a33dc53afee103862e527fc49af076c13fcf47d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 09:05:46 +0900 +Subject: ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency + +From: Namjae Jeon + +[ Upstream commit b39a1833cc4a2755b02603eec3a71a85e9dff926 ] + +Under high concurrency, A tree-connection object (tcon) is freed on +a disconnect path while another path still holds a reference and later +executes *_put()/write on it. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/mgmt/tree_connect.c | 18 ++++-------------- + fs/smb/server/mgmt/tree_connect.h | 1 - + fs/smb/server/smb2pdu.c | 3 --- + 3 files changed, 4 insertions(+), 18 deletions(-) + +diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c +index 94a52a75014a4..9bde1b58f9c46 100644 +--- a/fs/smb/server/mgmt/tree_connect.c ++++ b/fs/smb/server/mgmt/tree_connect.c +@@ -77,7 +77,6 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + tree_conn->t_state = TREE_NEW; + status.tree_conn = tree_conn; + atomic_set(&tree_conn->refcount, 1); +- init_waitqueue_head(&tree_conn->refcount_q); + + ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, + GFP_KERNEL)); +@@ -99,14 +98,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) + + void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) + { +- /* +- * Checking waitqueue to releasing tree connect on +- * tree disconnect. waitqueue_active is safe because it +- * uses atomic operation for condition. +- */ +- if (!atomic_dec_return(&tcon->refcount) && +- waitqueue_active(&tcon->refcount_q)) +- wake_up(&tcon->refcount_q); ++ if (atomic_dec_and_test(&tcon->refcount)) ++ kfree(tcon); + } + + int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, +@@ -118,14 +111,11 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, + xa_erase(&sess->tree_conns, tree_conn->id); + write_unlock(&sess->tree_conns_lock); + +- if (!atomic_dec_and_test(&tree_conn->refcount)) +- wait_event(tree_conn->refcount_q, +- atomic_read(&tree_conn->refcount) == 0); +- + ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); + ksmbd_release_tree_conn_id(sess, tree_conn->id); + ksmbd_share_config_put(tree_conn->share_conf); +- kfree(tree_conn); ++ if (atomic_dec_and_test(&tree_conn->refcount)) ++ kfree(tree_conn); + return ret; + } + +diff --git a/fs/smb/server/mgmt/tree_connect.h b/fs/smb/server/mgmt/tree_connect.h +index a42cdd0510411..f0023d86716f2 100644 +--- a/fs/smb/server/mgmt/tree_connect.h ++++ b/fs/smb/server/mgmt/tree_connect.h +@@ -33,7 +33,6 @@ struct ksmbd_tree_connect { + int maximal_access; + bool posix_extensions; + atomic_t refcount; +- wait_queue_head_t refcount_q; + unsigned int t_state; + }; + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index 8fa68c3b24f3f..77b06fd984be6 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -2183,7 +2183,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); + tcon->t_state = TREE_DISCONNECTED; + write_unlock(&sess->tree_conns_lock); + +@@ -2193,8 +2192,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + goto err_out; + } + +- work->tcon = NULL; +- + rsp->StructureSize = cpu_to_le16(4); + err = ksmbd_iov_pin_rsp(work, rsp, + sizeof(struct smb2_tree_disconnect_rsp)); +-- +2.51.0 + diff --git a/queue-6.6/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch b/queue-6.6/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch new file mode 100644 index 0000000000..c6edd4d7cb --- /dev/null +++ b/queue-6.6/ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch @@ -0,0 +1,190 @@ +From 888d1c5151cefe5b8d4843fb726263118c1b8e0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:05:09 +0900 +Subject: ksmbd: vfs: fix race on m_flags in vfs_cache + +From: Qianchang Zhao + +[ Upstream commit 991f8a79db99b14c48d20d2052c82d65b9186cad ] + +ksmbd maintains delete-on-close and pending-delete state in +ksmbd_inode->m_flags. In vfs_cache.c this field is accessed under +inconsistent locking: some paths read and modify m_flags under +ci->m_lock while others do so without taking the lock at all. + +Examples: + + - ksmbd_query_inode_status() and __ksmbd_inode_close() use + ci->m_lock when checking or updating m_flags. + - ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), + ksmbd_clear_inode_pending_delete() and ksmbd_fd_set_delete_on_close() + used to read and modify m_flags without ci->m_lock. + +This creates a potential data race on m_flags when multiple threads +open, close and delete the same file concurrently. In the worst case +delete-on-close and pending-delete bits can be lost or observed in an +inconsistent state, leading to confusing delete semantics (files that +stay on disk after delete-on-close, or files that disappear while still +in use). + +Fix it by: + + - Making ksmbd_query_inode_status() look at m_flags under ci->m_lock + after dropping inode_hash_lock. + - Adding ci->m_lock protection to all helpers that read or modify + m_flags (ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), + ksmbd_clear_inode_pending_delete(), ksmbd_fd_set_delete_on_close()). + - Keeping the existing ci->m_lock protection in __ksmbd_inode_close(), + and moving the actual unlink/xattr removal outside the lock. + +This unifies the locking around m_flags and removes the data race while +preserving the existing delete-on-close behaviour. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Qianchang Zhao +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/vfs_cache.c | 88 +++++++++++++++++++++++++++------------ + 1 file changed, 62 insertions(+), 26 deletions(-) + +diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c +index 002f0864abee6..2fcb7ca33a63c 100644 +--- a/fs/smb/server/vfs_cache.c ++++ b/fs/smb/server/vfs_cache.c +@@ -105,40 +105,62 @@ int ksmbd_query_inode_status(struct dentry *dentry) + + read_lock(&inode_hash_lock); + ci = __ksmbd_inode_lookup(dentry); +- if (ci) { +- ret = KSMBD_INODE_STATUS_OK; +- if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) +- ret = KSMBD_INODE_STATUS_PENDING_DELETE; +- atomic_dec(&ci->m_count); +- } + read_unlock(&inode_hash_lock); ++ if (!ci) ++ return ret; ++ ++ down_read(&ci->m_lock); ++ if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) ++ ret = KSMBD_INODE_STATUS_PENDING_DELETE; ++ else ++ ret = KSMBD_INODE_STATUS_OK; ++ up_read(&ci->m_lock); ++ ++ atomic_dec(&ci->m_count); + return ret; + } + + bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) + { +- return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); ++ struct ksmbd_inode *ci = fp->f_ci; ++ int ret; ++ ++ down_read(&ci->m_lock); ++ ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); ++ up_read(&ci->m_lock); ++ ++ return ret; + } + + void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) + { +- fp->f_ci->m_flags |= S_DEL_PENDING; ++ struct ksmbd_inode *ci = fp->f_ci; ++ ++ down_write(&ci->m_lock); ++ ci->m_flags |= S_DEL_PENDING; ++ up_write(&ci->m_lock); + } + + void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp) + { +- fp->f_ci->m_flags &= ~S_DEL_PENDING; ++ struct ksmbd_inode *ci = fp->f_ci; ++ ++ down_write(&ci->m_lock); ++ ci->m_flags &= ~S_DEL_PENDING; ++ up_write(&ci->m_lock); + } + + void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, + int file_info) + { +- if (ksmbd_stream_fd(fp)) { +- fp->f_ci->m_flags |= S_DEL_ON_CLS_STREAM; +- return; +- } ++ struct ksmbd_inode *ci = fp->f_ci; + +- fp->f_ci->m_flags |= S_DEL_ON_CLS; ++ down_write(&ci->m_lock); ++ if (ksmbd_stream_fd(fp)) ++ ci->m_flags |= S_DEL_ON_CLS_STREAM; ++ else ++ ci->m_flags |= S_DEL_ON_CLS; ++ up_write(&ci->m_lock); + } + + static void ksmbd_inode_hash(struct ksmbd_inode *ci) +@@ -250,27 +272,41 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) + struct file *filp; + + filp = fp->filp; +- if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { +- ci->m_flags &= ~S_DEL_ON_CLS_STREAM; +- err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), +- &filp->f_path, +- fp->stream.name, +- true); +- if (err) +- pr_err("remove xattr failed : %s\n", +- fp->stream.name); ++ ++ if (ksmbd_stream_fd(fp)) { ++ bool remove_stream_xattr = false; ++ ++ down_write(&ci->m_lock); ++ if (ci->m_flags & S_DEL_ON_CLS_STREAM) { ++ ci->m_flags &= ~S_DEL_ON_CLS_STREAM; ++ remove_stream_xattr = true; ++ } ++ up_write(&ci->m_lock); ++ ++ if (remove_stream_xattr) { ++ err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), ++ &filp->f_path, ++ fp->stream.name, ++ true); ++ if (err) ++ pr_err("remove xattr failed : %s\n", ++ fp->stream.name); ++ } + } + + if (atomic_dec_and_test(&ci->m_count)) { ++ bool do_unlink = false; ++ + down_write(&ci->m_lock); + if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { + ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); +- up_write(&ci->m_lock); +- ksmbd_vfs_unlink(filp); +- down_write(&ci->m_lock); ++ do_unlink = true; + } + up_write(&ci->m_lock); + ++ if (do_unlink) ++ ksmbd_vfs_unlink(filp); ++ + ksmbd_inode_free(ci); + } + } +-- +2.51.0 + diff --git a/queue-6.6/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch b/queue-6.6/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch new file mode 100644 index 0000000000..4540482356 --- /dev/null +++ b/queue-6.6/livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch @@ -0,0 +1,88 @@ +From 4f935af765f081c2b8c2ac5b2039bba418d6c4c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 10:30:19 -0700 +Subject: livepatch: Match old_sympos 0 and 1 in klp_find_func() + +From: Song Liu + +[ Upstream commit 139560e8b973402140cafeb68c656c1374bd4c20 ] + +When there is only one function of the same name, old_sympos of 0 and 1 +are logically identical. Match them in klp_find_func(). + +This is to avoid a corner case with different toolchain behavior. + +In this specific issue, two versions of kpatch-build were used to +build livepatch for the same kernel. One assigns old_sympos == 0 for +unique local functions, the other assigns old_sympos == 1 for unique +local functions. Both versions work fine by themselves. (PS: This +behavior change was introduced in a downstream version of kpatch-build. +This change does not exist in upstream kpatch-build.) + +However, during livepatch upgrade (with the replace flag set) from a +patch built with one version of kpatch-build to the same fix built with +the other version of kpatch-build, livepatching fails with errors like: + +[ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' +... +[ 14.219466] Call Trace: +[ 14.219468] +[ 14.219469] dump_stack_lvl+0x47/0x60 +[ 14.219474] sysfs_warn_dup.cold+0x17/0x27 +[ 14.219476] sysfs_create_dir_ns+0x95/0xb0 +[ 14.219479] kobject_add_internal+0x9e/0x260 +[ 14.219483] kobject_add+0x68/0x80 +[ 14.219485] ? kstrdup+0x3c/0xa0 +[ 14.219486] klp_enable_patch+0x320/0x830 +[ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] +[ 14.219491] ? 0xffffffffa05eb000 +[ 14.219492] do_one_initcall+0x2e/0x190 +[ 14.219494] do_init_module+0x67/0x270 +[ 14.219496] init_module_from_file+0x75/0xa0 +[ 14.219499] idempotent_init_module+0x15a/0x240 +[ 14.219501] __x64_sys_finit_module+0x61/0xc0 +[ 14.219503] do_syscall_64+0x5b/0x160 +[ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 +[ 14.219507] RIP: 0033:0x7f545a4bd96d +... +[ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with + -EEXIST, don't try to register things with the same name ... + +This happens because klp_find_func() thinks somefunc with old_sympos==0 +is not the same as somefunc with old_sympos==1, and klp_add_object_nops +adds another xxx/func,1 to the list of functions to patch. + +Signed-off-by: Song Liu +Acked-by: Josh Poimboeuf +[pmladek@suse.com: Fixed some typos.] +Reviewed-by: Petr Mladek +Tested-by: Petr Mladek +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + kernel/livepatch/core.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c +index ecbc9b6aba3a1..81fd438697446 100644 +--- a/kernel/livepatch/core.c ++++ b/kernel/livepatch/core.c +@@ -90,8 +90,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj, + struct klp_func *func; + + klp_for_each_func(obj, func) { ++ /* ++ * Besides identical old_sympos, also consider old_sympos ++ * of 0 and 1 are identical. ++ */ + if ((strcmp(old_func->old_name, func->old_name) == 0) && +- (old_func->old_sympos == func->old_sympos)) { ++ ((old_func->old_sympos == func->old_sympos) || ++ (old_func->old_sympos == 0 && func->old_sympos == 1) || ++ (old_func->old_sympos == 1 && func->old_sympos == 0))) { + return func; + } + } +-- +2.51.0 + diff --git a/queue-6.6/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch b/queue-6.6/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch new file mode 100644 index 0000000000..86c285c852 --- /dev/null +++ b/queue-6.6/ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch @@ -0,0 +1,60 @@ +From ad52fe9f8bdf35742910e7a7c80d44ca8df91aa8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:38:50 -0300 +Subject: ntfs: set dummy blocksize to read boot_block when mounting + +From: Pedro Demarchi Gomes + +[ Upstream commit d1693a7d5a38acf6424235a6070bcf5b186a360d ] + +When mounting, sb->s_blocksize is used to read the boot_block without +being defined or validated. Set a dummy blocksize before attempting to +read the boot_block. + +The issue can be triggered with the following syz reproducer: + + mkdirat(0xffffffffffffff9c, &(0x7f0000000080)='./file1\x00', 0x0) + r4 = openat$nullb(0xffffffffffffff9c, &(0x7f0000000040), 0x121403, 0x0) + ioctl$FS_IOC_SETFLAGS(r4, 0x40081271, &(0x7f0000000980)=0x4000) + mount(&(0x7f0000000140)=@nullb, &(0x7f0000000040)='./cgroup\x00', + &(0x7f0000000000)='ntfs3\x00', 0x2208004, 0x0) + syz_clone(0x88200200, 0x0, 0x0, 0x0, 0x0, 0x0) + +Here, the ioctl sets the bdev block size to 16384. During mount, +get_tree_bdev_flags() calls sb_set_blocksize(sb, block_size(bdev)), +but since block_size(bdev) > PAGE_SIZE, sb_set_blocksize() leaves +sb->s_blocksize at zero. + +Later, ntfs_init_from_boot() attempts to read the boot_block while +sb->s_blocksize is still zero, which triggers the bug. + +Reported-by: syzbot+f4f84b57a01d6b8364ad@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=f4f84b57a01d6b8364ad +Signed-off-by: Pedro Demarchi Gomes +[almaz.alexandrovich@paragon-software.com: changed comment style, added +return value handling] +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/super.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index c14b55cdea85c..0b96d0f995c61 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -885,6 +885,11 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size, + + sbi->volume.blocks = dev_size >> PAGE_SHIFT; + ++ /* Set dummy blocksize to read boot_block. */ ++ if (!sb_min_blocksize(sb, PAGE_SIZE)) { ++ return -EINVAL; ++ } ++ + read_boot: + bh = ntfs_bread(sb, boot_block); + if (!bh) +-- +2.51.0 + diff --git a/queue-6.6/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch b/queue-6.6/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch new file mode 100644 index 0000000000..3c5a758325 --- /dev/null +++ b/queue-6.6/perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch @@ -0,0 +1,83 @@ +From 55623803371bcebae1425923772d18d4f788e8d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 08:00:53 -0500 +Subject: perf/x86/amd: Check event before enable to avoid GPF + +From: George Kennedy + +[ Upstream commit 866cf36bfee4fba6a492d2dcc5133f857e3446b0 ] + +On AMD machines cpuc->events[idx] can become NULL in a subtle race +condition with NMI->throttle->x86_pmu_stop(). + +Check event for NULL in amd_pmu_enable_all() before enable to avoid a GPF. +This appears to be an AMD only issue. + +Syzkaller reported a GPF in amd_pmu_enable_all. + +INFO: NMI handler (perf_event_nmi_handler) took too long to run: 13.143 + msecs +Oops: general protection fault, probably for non-canonical address + 0xdffffc0000000034: 0000 PREEMPT SMP KASAN NOPTI +KASAN: null-ptr-deref in range [0x00000000000001a0-0x00000000000001a7] +CPU: 0 UID: 0 PID: 328415 Comm: repro_36674776 Not tainted 6.12.0-rc1-syzk +RIP: 0010:x86_pmu_enable_event (arch/x86/events/perf_event.h:1195 + arch/x86/events/core.c:1430) +RSP: 0018:ffff888118009d60 EFLAGS: 00010012 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: 0000000000000034 RSI: 0000000000000000 RDI: 00000000000001a0 +RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002 +R13: ffff88811802a440 R14: ffff88811802a240 R15: ffff8881132d8601 +FS: 00007f097dfaa700(0000) GS:ffff888118000000(0000) GS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000200001c0 CR3: 0000000103d56000 CR4: 00000000000006f0 +Call Trace: + +amd_pmu_enable_all (arch/x86/events/amd/core.c:760 (discriminator 2)) +x86_pmu_enable (arch/x86/events/core.c:1360) +event_sched_out (kernel/events/core.c:1191 kernel/events/core.c:1186 + kernel/events/core.c:2346) +__perf_remove_from_context (kernel/events/core.c:2435) +event_function (kernel/events/core.c:259) +remote_function (kernel/events/core.c:92 (discriminator 1) + kernel/events/core.c:72 (discriminator 1)) +__flush_smp_call_function_queue (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 ./include/trace/events/csd.h:64 + kernel/smp.c:135 kernel/smp.c:540) +__sysvec_call_function_single (./arch/x86/include/asm/jump_label.h:27 + ./include/linux/jump_label.h:207 + ./arch/x86/include/asm/trace/irq_vectors.h:99 arch/x86/kernel/smp.c:272) +sysvec_call_function_single (arch/x86/kernel/smp.c:266 (discriminator 47) + arch/x86/kernel/smp.c:266 (discriminator 47)) + + +Reported-by: syzkaller +Signed-off-by: George Kennedy +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + arch/x86/events/amd/core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c +index aa8fc2cf1bde7..211f429750f5f 100644 +--- a/arch/x86/events/amd/core.c ++++ b/arch/x86/events/amd/core.c +@@ -745,7 +745,12 @@ static void amd_pmu_enable_all(int added) + if (!test_bit(idx, cpuc->active_mask)) + continue; + +- amd_pmu_enable_event(cpuc->events[idx]); ++ /* ++ * FIXME: cpuc->events[idx] can become NULL in a subtle race ++ * condition with NMI->throttle->x86_pmu_stop(). ++ */ ++ if (cpuc->events[idx]) ++ amd_pmu_enable_event(cpuc->events[idx]); + } + } + +-- +2.51.0 + diff --git a/queue-6.6/sched-deadline-only-set-free_cpus-for-online-runqueu.patch b/queue-6.6/sched-deadline-only-set-free_cpus-for-online-runqueu.patch new file mode 100644 index 0000000000..63b34ac942 --- /dev/null +++ b/queue-6.6/sched-deadline-only-set-free_cpus-for-online-runqueu.patch @@ -0,0 +1,189 @@ +From 9e3e8a7e12cd3d768078fa3226b2b8b024d8c01d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 18:22:36 -0700 +Subject: sched/deadline: only set free_cpus for online runqueues + +From: Doug Berger + +[ Upstream commit 382748c05e58a9f1935f5a653c352422375566ea ] + +Commit 16b269436b72 ("sched/deadline: Modify cpudl::free_cpus +to reflect rd->online") introduced the cpudl_set/clear_freecpu +functions to allow the cpu_dl::free_cpus mask to be manipulated +by the deadline scheduler class rq_on/offline callbacks so the +mask would also reflect this state. + +Commit 9659e1eeee28 ("sched/deadline: Remove cpu_active_mask +from cpudl_find()") removed the check of the cpu_active_mask to +save some processing on the premise that the cpudl::free_cpus +mask already reflected the runqueue online state. + +Unfortunately, there are cases where it is possible for the +cpudl_clear function to set the free_cpus bit for a CPU when the +deadline runqueue is offline. When this occurs while a CPU is +connected to the default root domain the flag may retain the bad +state after the CPU has been unplugged. Later, a different CPU +that is transitioning through the default root domain may push a +deadline task to the powered down CPU when cpudl_find sees its +free_cpus bit is set. If this happens the task will not have the +opportunity to run. + +One example is outlined here: +https://lore.kernel.org/lkml/20250110233010.2339521-1-opendmb@gmail.com + +Another occurs when the last deadline task is migrated from a +CPU that has an offlined runqueue. The dequeue_task member of +the deadline scheduler class will eventually call cpudl_clear +and set the free_cpus bit for the CPU. + +This commit modifies the cpudl_clear function to be aware of the +online state of the deadline runqueue so that the free_cpus mask +can be updated appropriately. + +It is no longer necessary to manage the mask outside of the +cpudl_set/clear functions so the cpudl_set/clear_freecpu +functions are removed. In addition, since the free_cpus mask is +now only updated under the cpudl lock the code was changed to +use the non-atomic __cpumask functions. + +Signed-off-by: Doug Berger +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + kernel/sched/cpudeadline.c | 34 +++++++++------------------------- + kernel/sched/cpudeadline.h | 4 +--- + kernel/sched/deadline.c | 8 ++++---- + 3 files changed, 14 insertions(+), 32 deletions(-) + +diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c +index 95baa12a10293..59d7b4f48c086 100644 +--- a/kernel/sched/cpudeadline.c ++++ b/kernel/sched/cpudeadline.c +@@ -165,12 +165,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, + * cpudl_clear - remove a CPU from the cpudl max-heap + * @cp: the cpudl max-heap context + * @cpu: the target CPU ++ * @online: the online state of the deadline runqueue + * + * Notes: assumes cpu_rq(cpu)->lock is locked + * + * Returns: (void) + */ +-void cpudl_clear(struct cpudl *cp, int cpu) ++void cpudl_clear(struct cpudl *cp, int cpu, bool online) + { + int old_idx, new_cpu; + unsigned long flags; +@@ -183,7 +184,7 @@ void cpudl_clear(struct cpudl *cp, int cpu) + if (old_idx == IDX_INVALID) { + /* + * Nothing to remove if old_idx was invalid. +- * This could happen if a rq_offline_dl is ++ * This could happen if rq_online_dl or rq_offline_dl is + * called for a CPU without -dl tasks running. + */ + } else { +@@ -194,9 +195,12 @@ void cpudl_clear(struct cpudl *cp, int cpu) + cp->elements[new_cpu].idx = old_idx; + cp->elements[cpu].idx = IDX_INVALID; + cpudl_heapify(cp, old_idx); +- +- cpumask_set_cpu(cpu, cp->free_cpus); + } ++ if (likely(online)) ++ __cpumask_set_cpu(cpu, cp->free_cpus); ++ else ++ __cpumask_clear_cpu(cpu, cp->free_cpus); ++ + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +@@ -227,7 +231,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + cp->elements[new_idx].cpu = cpu; + cp->elements[cpu].idx = new_idx; + cpudl_heapify_up(cp, new_idx); +- cpumask_clear_cpu(cpu, cp->free_cpus); ++ __cpumask_clear_cpu(cpu, cp->free_cpus); + } else { + cp->elements[old_idx].dl = dl; + cpudl_heapify(cp, old_idx); +@@ -236,26 +240,6 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) + raw_spin_unlock_irqrestore(&cp->lock, flags); + } + +-/* +- * cpudl_set_freecpu - Set the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_set_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_set_cpu(cpu, cp->free_cpus); +-} +- +-/* +- * cpudl_clear_freecpu - Clear the cpudl.free_cpus +- * @cp: the cpudl max-heap context +- * @cpu: rd attached CPU +- */ +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu) +-{ +- cpumask_clear_cpu(cpu, cp->free_cpus); +-} +- + /* + * cpudl_init - initialize the cpudl structure + * @cp: the cpudl max-heap context +diff --git a/kernel/sched/cpudeadline.h b/kernel/sched/cpudeadline.h +index 0adeda93b5fb5..ecff718d94aea 100644 +--- a/kernel/sched/cpudeadline.h ++++ b/kernel/sched/cpudeadline.h +@@ -18,9 +18,7 @@ struct cpudl { + #ifdef CONFIG_SMP + int cpudl_find(struct cpudl *cp, struct task_struct *p, struct cpumask *later_mask); + void cpudl_set(struct cpudl *cp, int cpu, u64 dl); +-void cpudl_clear(struct cpudl *cp, int cpu); ++void cpudl_clear(struct cpudl *cp, int cpu, bool online); + int cpudl_init(struct cpudl *cp); +-void cpudl_set_freecpu(struct cpudl *cp, int cpu); +-void cpudl_clear_freecpu(struct cpudl *cp, int cpu); + void cpudl_cleanup(struct cpudl *cp); + #endif /* CONFIG_SMP */ +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index 5bb9735e19d2f..91459b664014d 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -1469,7 +1469,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline) + if (!dl_rq->dl_nr_running) { + dl_rq->earliest_dl.curr = 0; + dl_rq->earliest_dl.next = 0; +- cpudl_clear(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, rq->online); + cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr); + } else { + struct rb_node *leftmost = rb_first_cached(&dl_rq->root); +@@ -2550,9 +2550,10 @@ static void rq_online_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_set_overload(rq); + +- cpudl_set_freecpu(&rq->rd->cpudl, rq->cpu); + if (rq->dl.dl_nr_running > 0) + cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr); ++ else ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, true); + } + + /* Assumes rq->lock is held */ +@@ -2561,8 +2562,7 @@ static void rq_offline_dl(struct rq *rq) + if (rq->dl.overloaded) + dl_clear_overload(rq); + +- cpudl_clear(&rq->rd->cpudl, rq->cpu); +- cpudl_clear_freecpu(&rq->rd->cpudl, rq->cpu); ++ cpudl_clear(&rq->rd->cpudl, rq->cpu, false); + } + + void __init init_sched_dl_class(void) +-- +2.51.0 + diff --git a/queue-6.6/sched-fair-revert-max_newidle_lb_cost-bump.patch b/queue-6.6/sched-fair-revert-max_newidle_lb_cost-bump.patch new file mode 100644 index 0000000000..162a3af6e3 --- /dev/null +++ b/queue-6.6/sched-fair-revert-max_newidle_lb_cost-bump.patch @@ -0,0 +1,77 @@ +From 7fdd22e3c0a79b7ffd0586c69c4d570753ed7364 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 17:01:20 +0100 +Subject: sched/fair: Revert max_newidle_lb_cost bump + +From: Peter Zijlstra + +[ Upstream commit d206fbad9328ddb68ebabd7cf7413392acd38081 ] + +Many people reported regressions on their database workloads due to: + + 155213a2aed4 ("sched/fair: Bump sd->max_newidle_lb_cost when newidle balance fails") + +For instance Adam Li reported a 6% regression on SpecJBB. + +Conversely this will regress schbench again; on my machine from 2.22 +Mrps/s down to 2.04 Mrps/s. + +Reported-by: Joseph Salisbury +Reported-by: Adam Li +Reported-by: Dietmar Eggemann +Reported-by: Hazem Mohamed Abuelfotoh +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dietmar Eggemann +Tested-by: Dietmar Eggemann +Tested-by: Chris Mason +Link: https://lkml.kernel.org/r/20250626144017.1510594-2-clm@fb.com +Link: https://lkml.kernel.org/r/006c9df2-b691-47f1-82e6-e233c3f91faf@oracle.com +Link: https://patch.msgid.link/20251107161739.406147760@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 19 +++---------------- + 1 file changed, 3 insertions(+), 16 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index cf3a51f323e32..38cc72d203c07 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -11722,14 +11722,8 @@ static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) + /* + * Track max cost of a domain to make sure to not delay the + * next wakeup on the CPU. +- * +- * sched_balance_newidle() bumps the cost whenever newidle +- * balance fails, and we don't want things to grow out of +- * control. Use the sysctl_sched_migration_cost as the upper +- * limit, plus a litle extra to avoid off by ones. + */ +- sd->max_newidle_lb_cost = +- min(cost, sysctl_sched_migration_cost + 200); ++ sd->max_newidle_lb_cost = cost; + sd->last_decay_max_lb_cost = jiffies; + } else if (time_after(jiffies, sd->last_decay_max_lb_cost + HZ)) { + /* +@@ -12415,17 +12409,10 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) + + t1 = sched_clock_cpu(this_cpu); + domain_cost = t1 - t0; ++ update_newidle_cost(sd, domain_cost); ++ + curr_cost += domain_cost; + t0 = t1; +- +- /* +- * Failing newidle means it is not effective; +- * bump the cost so we end up doing less of it. +- */ +- if (!pulled_task) +- domain_cost = (3 * sd->max_newidle_lb_cost) / 2; +- +- update_newidle_cost(sd, domain_cost); + } + + /* +-- +2.51.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 9a5eeff634..6e3e53dce9 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -296,3 +296,35 @@ usb-phy-initialize-struct-usb_phy-list_head.patch alsa-dice-fix-buffer-overflow-in-detect_stream_formats.patch ipv6-avoid-possible-null-deref-in-modify_prefix_route.patch ipv6-add-exception-routes-to-gc-list-in-rt6_insert_exception.patch +btrfs-do-not-skip-logging-new-dentries-when-logging-.patch +btrfs-fix-a-potential-path-leak-in-print_data_reloc_.patch +bpf-arm64-do-not-audit-capability-check-in-do_jit.patch +btrfs-fix-memory-leak-of-fs_devices-in-degraded-seed.patch +iomap-adjust-read-range-correctly-for-non-block-alig.patch +iomap-account-for-unaligned-end-offsets-when-truncat.patch +perf-x86-amd-check-event-before-enable-to-avoid-gpf.patch +sched-deadline-only-set-free_cpus-for-online-runqueu.patch +sched-fair-revert-max_newidle_lb_cost-bump.patch +x86-ptrace-always-inline-trivial-accessors.patch +acpica-avoid-walking-the-namespace-if-start_node-is-.patch +acpi-property-use-acpi-functions-in-acpi_graph_get_n.patch +cpufreq-dt-platdev-add-jh7110s-soc-to-the-allowlist.patch +cpufreq-s5pv210-fix-refcount-leak.patch +cpuidle-menu-use-residency-threshold-in-polling-stat.patch +livepatch-match-old_sympos-0-and-1-in-klp_find_func.patch +fs-ntfs3-support-timestamps-prior-to-epoch.patch +kbuild-use-objtree-for-module-signing-key-path.patch +ntfs-set-dummy-blocksize-to-read-boot_block-when-mou.patch +hfsplus-fix-volume-corruption-issue-for-generic-070.patch +hfsplus-fix-missing-hfs_bnode_get-in-__hfs_bnode_cre.patch +hfsplus-verify-inode-mode-when-loading-from-disk.patch +hfsplus-fix-volume-corruption-issue-for-generic-073.patch +wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch +btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch +gfs2-fix-remote-evict-for-read-only-filesystems.patch +smb-server-fix-return-value-of-smb2_ioctl.patch +ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch +ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch +bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch +bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch +gfs2-fix-use-of-bio_chain.patch diff --git a/queue-6.6/smb-server-fix-return-value-of-smb2_ioctl.patch b/queue-6.6/smb-server-fix-return-value-of-smb2_ioctl.patch new file mode 100644 index 0000000000..48ba1b7173 --- /dev/null +++ b/queue-6.6/smb-server-fix-return-value-of-smb2_ioctl.patch @@ -0,0 +1,61 @@ +From 17a5bf4e664b0aec3632ce2ac4432110b6f58306 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:46:10 +0800 +Subject: smb/server: fix return value of smb2_ioctl() + +From: ChenXiaoSong + +[ Upstream commit 269df046c1e15ab34fa26fd90db9381f022a0963 ] + +__process_request() will not print error messages if smb2_ioctl() +always returns 0. + +Fix this by returning the correct value at the end of function. + +Signed-off-by: ChenXiaoSong +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/smb2pdu.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index a819f198c3337..8fa68c3b24f3f 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -8094,7 +8094,7 @@ int smb2_ioctl(struct ksmbd_work *work) + id = req->VolatileFileId; + + if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) { +- rsp->hdr.Status = STATUS_NOT_SUPPORTED; ++ ret = -EOPNOTSUPP; + goto out; + } + +@@ -8114,8 +8114,9 @@ int smb2_ioctl(struct ksmbd_work *work) + case FSCTL_DFS_GET_REFERRALS: + case FSCTL_DFS_GET_REFERRALS_EX: + /* Not support DFS yet */ ++ ret = -EOPNOTSUPP; + rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED; +- goto out; ++ goto out2; + case FSCTL_CREATE_OR_GET_OBJECT_ID: + { + struct file_object_buf_type1_ioctl_rsp *obj_buf; +@@ -8405,8 +8406,10 @@ int smb2_ioctl(struct ksmbd_work *work) + rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL; + else if (ret < 0 || rsp->hdr.Status == 0) + rsp->hdr.Status = STATUS_INVALID_PARAMETER; ++ ++out2: + smb2_set_err_rsp(work); +- return 0; ++ return ret; + } + + /** +-- +2.51.0 + diff --git a/queue-6.6/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch b/queue-6.6/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch new file mode 100644 index 0000000000..1fbf9068a2 --- /dev/null +++ b/queue-6.6/wifi-brcmfmac-add-dmi-nvram-filename-quirk-for-acer-.patch @@ -0,0 +1,61 @@ +From 064c57847c669e11547853a38abd2d9fe1e68e68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 11:03:14 +0100 +Subject: wifi: brcmfmac: Add DMI nvram filename quirk for Acer A1 840 tablet + +From: Hans de Goede + +[ Upstream commit a8e5a110c0c38e08e5dd66356cd1156e91cf88e1 ] + +The Acer A1 840 tablet contains quite generic names in the sys_vendor and +product_name DMI strings, without this patch brcmfmac will try to load: +brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file which is a bit +too generic. + +Add a DMI quirk so that a unique and clearly identifiable nvram file name +is used on the Acer A1 840 tablet. + +Acked-by: Arend van Spriel +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20251103100314.353826-1-hansg@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +index c3a602197662b..abe7f6501e5ed 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +@@ -24,6 +24,10 @@ static const struct brcmf_dmi_data acepc_t8_data = { + BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" + }; + ++static const struct brcmf_dmi_data acer_a1_840_data = { ++ BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" ++}; ++ + /* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus + * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. + */ +@@ -91,6 +95,16 @@ static const struct dmi_system_id dmi_platform_data[] = { + }, + .driver_data = (void *)&acepc_t8_data, + }, ++ { ++ /* Acer Iconia One 8 A1-840 (non FHD version) */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), ++ /* Above strings are too generic also match BIOS date */ ++ DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), ++ }, ++ .driver_data = (void *)&acer_a1_840_data, ++ }, + { + /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ + .matches = { +-- +2.51.0 + diff --git a/queue-6.6/x86-ptrace-always-inline-trivial-accessors.patch b/queue-6.6/x86-ptrace-always-inline-trivial-accessors.patch new file mode 100644 index 0000000000..872a6d7edc --- /dev/null +++ b/queue-6.6/x86-ptrace-always-inline-trivial-accessors.patch @@ -0,0 +1,89 @@ +From dbb30e5107226cdc7553d9de416835597d5123a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 12:04:24 +0100 +Subject: x86/ptrace: Always inline trivial accessors + +From: Peter Zijlstra + +[ Upstream commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa ] + +A KASAN build bloats these single load/store helpers such that +it fails to inline them: + + vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled + +Make sure the compiler isn't allowed to do stupid. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Link: https://patch.msgid.link/20251031105435.GU4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index 5a83fbd9bc0b4..eb5b1e2aa7000 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -187,12 +187,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); + extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); + + +-static inline unsigned long regs_return_value(struct pt_regs *regs) ++static __always_inline unsigned long regs_return_value(struct pt_regs *regs) + { + return regs->ax; + } + +-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) ++static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) + { + regs->ax = rc; + } +@@ -277,34 +277,34 @@ static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) + } + #endif + +-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline unsigned long instruction_pointer(struct pt_regs *regs) ++static __always_inline unsigned long instruction_pointer(struct pt_regs *regs) + { + return regs->ip; + } + +-static inline void instruction_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void instruction_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->ip = val; + } + +-static inline unsigned long frame_pointer(struct pt_regs *regs) ++static __always_inline unsigned long frame_pointer(struct pt_regs *regs) + { + return regs->bp; + } + +-static inline unsigned long user_stack_pointer(struct pt_regs *regs) ++static __always_inline unsigned long user_stack_pointer(struct pt_regs *regs) + { + return regs->sp; + } + +-static inline void user_stack_pointer_set(struct pt_regs *regs, +- unsigned long val) ++static __always_inline ++void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) + { + regs->sp = val; + } +-- +2.51.0 +