release 6.16.4
This commit is contained in:
4
debian/bin/gencontrol.py
vendored
4
debian/bin/gencontrol.py
vendored
@@ -62,7 +62,7 @@ class Gencontrol(Base):
|
||||
super().do_main_setup(config, vars, makeflags)
|
||||
makeflags.update({
|
||||
'VERSION': self.version.linux_version,
|
||||
'UPSTREAMVERSION': self.version.linux_upstream,
|
||||
'UPSTREAMVERSION': self.version.linux_upstream_full,
|
||||
'ABINAME': self.abiname,
|
||||
'SOURCEVERSION': self.version.complete,
|
||||
})
|
||||
@@ -353,7 +353,7 @@ class Gencontrol(Base):
|
||||
self.abiname = f'{version.linux_upstream_full}'
|
||||
|
||||
self.vars = {
|
||||
'upstreamversion': self.version.linux_upstream,
|
||||
'upstreamversion': self.version.linux_upstream_full,
|
||||
'version': self.version.linux_version,
|
||||
'version_complete': self.version.complete,
|
||||
'source_basename': re.sub(r'-[\d.]+$', '',
|
||||
|
7
debian/changelog
vendored
7
debian/changelog
vendored
@@ -1,3 +1,10 @@
|
||||
linux (6.16.4-1) sid; urgency=medium
|
||||
|
||||
* New upstream stable update:
|
||||
https://www.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.16.4
|
||||
|
||||
-- Konstantin Demin <rockdrilla@gmail.com> Thu, 28 Aug 2025 22:38:27 +0300
|
||||
|
||||
linux (6.16.3-1) sid; urgency=medium
|
||||
|
||||
* New upstream stable update:
|
||||
|
8
debian/lib/python/debian_linux/debian.py
vendored
8
debian/lib/python/debian_linux/debian.py
vendored
@@ -175,12 +175,6 @@ class VersionLinux(Version):
|
||||
.+?
|
||||
)
|
||||
)?
|
||||
(?:
|
||||
\.dfsg\.
|
||||
(?P<dfsg>
|
||||
\d+
|
||||
)
|
||||
)?
|
||||
$
|
||||
""", re.X)
|
||||
|
||||
@@ -192,7 +186,6 @@ $
|
||||
if up_match is None or rev_match is None:
|
||||
raise RuntimeError(u"Invalid debian linux version")
|
||||
d = up_match.groupdict()
|
||||
self.linux_modifier = d['modifier']
|
||||
self.linux_version = d['version']
|
||||
if d['modifier'] is not None:
|
||||
assert not d['update']
|
||||
@@ -200,7 +193,6 @@ $
|
||||
else:
|
||||
self.linux_upstream = d['version']
|
||||
self.linux_upstream_full = self.linux_upstream + d['update']
|
||||
self.linux_dfsg = d['dfsg']
|
||||
|
||||
|
||||
class PackageArchitecture(set[str]):
|
||||
|
@@ -1,45 +0,0 @@
|
||||
From: Theodore Ts'o <tytso@mit.edu>
|
||||
Date: Thu, 7 Aug 2025 09:35:20 -0400
|
||||
Subject: ext4: don't try to clear the orphan_present feature block device is
|
||||
r/o
|
||||
Origin: https://git.kernel.org/linus/c5e104a91e7b6fa12c1dc2d8bf84abb7ef9b89ad
|
||||
Bug-Debian: https://bugs.debian.org/1108271
|
||||
|
||||
When the file system is frozen in preparation for taking an LVM
|
||||
snapshot, the journal is checkpointed and if the orphan_file feature
|
||||
is enabled, and the orphan file is empty, we clear the orphan_present
|
||||
feature flag. But if there are pending inodes that need to be removed
|
||||
the orphan_present feature flag can't be cleared.
|
||||
|
||||
The problem comes if the block device is read-only. In that case, we
|
||||
can't process the orphan inode list, so it is skipped in
|
||||
ext4_orphan_cleanup(). But then in ext4_mark_recovery_complete(),
|
||||
this results in the ext4 error "Orphan file not empty on read-only fs"
|
||||
firing and the file system mount is aborted.
|
||||
|
||||
Fix this by clearing the needs_recovery flag in the block device is
|
||||
read-only. We do this after the call to ext4_load_and_init-journal()
|
||||
since there are some error checks need to be done in case the journal
|
||||
needs to be replayed and the block device is read-only, or if the
|
||||
block device containing the externa journal is read-only, etc.
|
||||
|
||||
Cc: stable@kernel.org
|
||||
Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1108271
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 02f310fcf47f ("ext4: Speedup ext4 orphan inode handling")
|
||||
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
|
||||
---
|
||||
fs/ext4/super.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/fs/ext4/super.c
|
||||
+++ b/fs/ext4/super.c
|
||||
@@ -5414,6 +5414,8 @@ static int __ext4_fill_super(struct fs_c
|
||||
err = ext4_load_and_init_journal(sb, es, ctx);
|
||||
if (err)
|
||||
goto failed_mount3a;
|
||||
+ if (bdev_read_only(sb->s_bdev))
|
||||
+ needs_recovery = 0;
|
||||
} else if (test_opt(sb, NOLOAD) && !sb_rdonly(sb) &&
|
||||
ext4_has_feature_journal_needs_recovery(sb)) {
|
||||
ext4_msg(sb, KERN_ERR, "required journal recovery "
|
@@ -18,7 +18,7 @@ Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
|
||||
--- a/fs/btrfs/super.c
|
||||
+++ b/fs/btrfs/super.c
|
||||
@@ -2622,7 +2622,7 @@ module_exit(exit_btrfs_fs)
|
||||
@@ -2625,7 +2625,7 @@ module_exit(exit_btrfs_fs)
|
||||
|
||||
MODULE_DESCRIPTION("B-Tree File System (BTRFS)");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
44
debian/patches/bugfix/all/net-ipv4-fix-regression-in-local-broadcast-routes.patch
vendored
Normal file
44
debian/patches/bugfix/all/net-ipv4-fix-regression-in-local-broadcast-routes.patch
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
From: Oscar Maes <oscmaes92@gmail.com>
|
||||
Date: Tue, 26 Aug 2025 14:17:49 +0200
|
||||
Subject: net: ipv4: fix regression in local-broadcast routes
|
||||
Origin: https://lore.kernel.org/regressions/20250826121750.8451-1-oscmaes92@gmail.com/
|
||||
|
||||
Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
|
||||
introduced a regression where local-broadcast packets would have their
|
||||
gateway set in __mkroute_output, which was caused by fi = NULL being
|
||||
removed.
|
||||
|
||||
Fix this by resetting the fib_info for local-broadcast packets. This
|
||||
preserves the intended changes for directed-broadcast packets.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
|
||||
Reported-by: Brett A C Sheffield <bacs@librecast.net>
|
||||
Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
|
||||
Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
|
||||
---
|
||||
net/ipv4/route.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/net/ipv4/route.c
|
||||
+++ b/net/ipv4/route.c
|
||||
@@ -2573,12 +2573,16 @@ static struct rtable *__mkroute_output(c
|
||||
!netif_is_l3_master(dev_out))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
- if (ipv4_is_lbcast(fl4->daddr))
|
||||
+ if (ipv4_is_lbcast(fl4->daddr)) {
|
||||
type = RTN_BROADCAST;
|
||||
- else if (ipv4_is_multicast(fl4->daddr))
|
||||
+
|
||||
+ /* reset fi to prevent gateway resolution */
|
||||
+ fi = NULL;
|
||||
+ } else if (ipv4_is_multicast(fl4->daddr)) {
|
||||
type = RTN_MULTICAST;
|
||||
- else if (ipv4_is_zeronet(fl4->daddr))
|
||||
+ } else if (ipv4_is_zeronet(fl4->daddr)) {
|
||||
return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
|
||||
if (dev_out->flags & IFF_LOOPBACK)
|
||||
flags |= RTCF_LOCAL;
|
@@ -1,7 +1,7 @@
|
||||
From f556624b84006d199f4e32314589fc3d1800e730 Mon Sep 17 00:00:00 2001
|
||||
From: wangzijie <wangzijie1@honor.com>
|
||||
Date: Mon, 18 Aug 2025 20:31:02 +0800
|
||||
Subject: proc: fix missing pde_set_flags() for net proc files
|
||||
Date: Thu, 21 Aug 2025 18:58:06 +0800
|
||||
Origin: https://lore.kernel.org/stable/20250821105806.1453833-1-wangzijie1@honor.com/
|
||||
|
||||
To avoid potential UAF issues during module removal races, we use pde_set_flags()
|
||||
to save proc_ops flags in PDE itself before proc_register(), and then use
|
||||
@@ -16,42 +16,43 @@ NULL check for proc_ops in pde_set_flags().
|
||||
|
||||
[1]: https://lore.kernel.org/all/20250815195616.64497967@chagall.paradoxon.rec/
|
||||
|
||||
Fixes: ff7ec8dc1b64 ("proc: use the same treatment to check proc_lseek as ones for proc_read_iter et.al)
|
||||
Fixes: ff7ec8dc1b64 ("proc: use the same treatment to check proc_lseek as ones for proc_read_iter et.al")
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Lars Wendler <polynomial-c@gmx.de>
|
||||
Signed-off-by: wangzijie <wangzijie1@honor.com>
|
||||
Cherry-picked-for: https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/151
|
||||
---
|
||||
fs/proc/generic.c | 36 +++++++++++++++++++-----------------
|
||||
1 file changed, 19 insertions(+), 17 deletions(-)
|
||||
fs/proc/generic.c | 38 +++++++++++++++++++++-----------------
|
||||
1 file changed, 21 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/fs/proc/generic.c
|
||||
+++ b/fs/proc/generic.c
|
||||
@@ -364,6 +364,23 @@ static const struct inode_operations pro
|
||||
@@ -364,6 +364,25 @@ static const struct inode_operations pro
|
||||
.setattr = proc_notify_change,
|
||||
};
|
||||
|
||||
+static void pde_set_flags(struct proc_dir_entry *pde)
|
||||
+{
|
||||
+ if (!pde->proc_ops)
|
||||
+ const struct proc_ops *proc_ops = pde->proc_ops;
|
||||
+
|
||||
+ if (!proc_ops)
|
||||
+ return;
|
||||
+
|
||||
+ if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
|
||||
+ if (proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
|
||||
+ pde->flags |= PROC_ENTRY_PERMANENT;
|
||||
+ if (pde->proc_ops->proc_read_iter)
|
||||
+ if (proc_ops->proc_read_iter)
|
||||
+ pde->flags |= PROC_ENTRY_proc_read_iter;
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ if (pde->proc_ops->proc_compat_ioctl)
|
||||
+ if (proc_ops->proc_compat_ioctl)
|
||||
+ pde->flags |= PROC_ENTRY_proc_compat_ioctl;
|
||||
+#endif
|
||||
+ if (pde->proc_ops->proc_lseek)
|
||||
+ if (proc_ops->proc_lseek)
|
||||
+ pde->flags |= PROC_ENTRY_proc_lseek;
|
||||
+}
|
||||
+
|
||||
/* returns the registered entry, or frees dp and returns NULL on failure */
|
||||
struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
|
||||
struct proc_dir_entry *dp)
|
||||
@@ -371,6 +388,8 @@ struct proc_dir_entry *proc_register(str
|
||||
@@ -371,6 +390,8 @@ struct proc_dir_entry *proc_register(str
|
||||
if (proc_alloc_inum(&dp->low_ino))
|
||||
goto out_free_entry;
|
||||
|
||||
@@ -60,7 +61,7 @@ Cherry-picked-for: https://gitlab.archlinux.org/archlinux/packaging/packages/lin
|
||||
write_lock(&proc_subdir_lock);
|
||||
dp->parent = dir;
|
||||
if (pde_subdir_insert(dir, dp) == false) {
|
||||
@@ -559,20 +578,6 @@ struct proc_dir_entry *proc_create_reg(c
|
||||
@@ -559,20 +580,6 @@ struct proc_dir_entry *proc_create_reg(c
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ Cherry-picked-for: https://gitlab.archlinux.org/archlinux/packaging/packages/lin
|
||||
struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
|
||||
struct proc_dir_entry *parent,
|
||||
const struct proc_ops *proc_ops, void *data)
|
||||
@@ -583,7 +588,6 @@ struct proc_dir_entry *proc_create_data(
|
||||
@@ -583,7 +590,6 @@ struct proc_dir_entry *proc_create_data(
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->proc_ops = proc_ops;
|
||||
@@ -89,7 +90,7 @@ Cherry-picked-for: https://gitlab.archlinux.org/archlinux/packaging/packages/lin
|
||||
return proc_register(parent, p);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_create_data);
|
||||
@@ -634,7 +638,6 @@ struct proc_dir_entry *proc_create_seq_p
|
||||
@@ -634,7 +640,6 @@ struct proc_dir_entry *proc_create_seq_p
|
||||
p->proc_ops = &proc_seq_ops;
|
||||
p->seq_ops = ops;
|
||||
p->state_size = state_size;
|
||||
@@ -97,7 +98,7 @@ Cherry-picked-for: https://gitlab.archlinux.org/archlinux/packaging/packages/lin
|
||||
return proc_register(parent, p);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_create_seq_private);
|
||||
@@ -665,7 +668,6 @@ struct proc_dir_entry *proc_create_singl
|
||||
@@ -665,7 +670,6 @@ struct proc_dir_entry *proc_create_singl
|
||||
return NULL;
|
||||
p->proc_ops = &proc_single_ops;
|
||||
p->single_show = show;
|
@@ -36,7 +36,7 @@ Signed-off-by: Christian Loehle <christian.loehle@arm.com>
|
||||
depends on KVM_GUEST
|
||||
--- a/drivers/cpuidle/governors/menu.c
|
||||
+++ b/drivers/cpuidle/governors/menu.c
|
||||
@@ -526,7 +526,7 @@ static int menu_enable_device(struct cpu
|
||||
@@ -521,7 +521,7 @@ static int menu_enable_device(struct cpu
|
||||
|
||||
static struct cpuidle_governor menu_governor = {
|
||||
.name = "menu",
|
||||
|
@@ -1,91 +0,0 @@
|
||||
From e9efb8c2e0d662c1d28a95732f0a085e81c365ab Mon Sep 17 00:00:00 2001
|
||||
From: Jiwei Sun <sunjw10@lenovo.com>
|
||||
Date: Thu, 23 Jan 2025 13:51:54 +0800
|
||||
Subject: PCI: Fix link speed calculation on retrain failure
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When pcie_failed_link_retrain() fails to retrain, it tries to revert to the
|
||||
previous link speed. However it calculates that speed from the Link
|
||||
Control 2 register without masking out non-speed bits first.
|
||||
|
||||
PCIE_LNKCTL2_TLS2SPEED() converts such incorrect values to
|
||||
PCI_SPEED_UNKNOWN (0xff), which in turn causes a WARN splat in
|
||||
pcie_set_target_speed():
|
||||
|
||||
pci 0000:00:01.1: [1022:14ed] type 01 class 0x060400 PCIe Root Port
|
||||
pci 0000:00:01.1: broken device, retraining non-functional downstream link at 2.5GT/s
|
||||
pci 0000:00:01.1: retraining failed
|
||||
WARNING: CPU: 1 PID: 1 at drivers/pci/pcie/bwctrl.c:168 pcie_set_target_speed
|
||||
RDX: 0000000000000001 RSI: 00000000000000ff RDI: ffff9acd82efa000
|
||||
pcie_failed_link_retrain
|
||||
pci_device_add
|
||||
pci_scan_single_device
|
||||
|
||||
Mask out the non-speed bits in PCIE_LNKCTL2_TLS2SPEED() and
|
||||
PCIE_LNKCAP_SLS2SPEED() so they don't incorrectly return PCI_SPEED_UNKNOWN.
|
||||
|
||||
Fixes: de9a6c8d5dbf ("PCI/bwctrl: Add pcie_set_target_speed() to set PCIe Link Speed")
|
||||
Reported-by: Andrew <andreasx0@protonmail.com>
|
||||
Closes: https://lore.kernel.org/r/7iNzXbCGpf8yUMJZBQjLdbjPcXrEJqBxy5-bHfppz0ek-h4_-G93b1KUrm106r2VNF2FV_sSq0nENv4RsRIUGnlYZMlQr2ZD2NyB5sdj5aU=@protonmail.com/
|
||||
Suggested-by: Maciej W. Rozycki <macro@orcam.me.uk>
|
||||
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
Signed-off-by: Jiwei Sun <sunjw10@lenovo.com>
|
||||
[bhelgaas: commit log, add details from https://lore.kernel.org/r/1c92ef6bcb314ee6977839b46b393282e4f52e74.1750684771.git.lukas@wunner.de]
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
Cc: stable@vger.kernel.org # v6.13+
|
||||
Link: https://patch.msgid.link/20250123055155.22648-2-sjiwei@163.com
|
||||
---
|
||||
drivers/pci/pci.h | 32 +++++++++++++++++++-------------
|
||||
1 file changed, 19 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/pci/pci.h
|
||||
+++ b/drivers/pci/pci.h
|
||||
@@ -391,12 +391,14 @@ void pci_bus_put(struct pci_bus *bus);
|
||||
|
||||
#define PCIE_LNKCAP_SLS2SPEED(lnkcap) \
|
||||
({ \
|
||||
- ((lnkcap) == PCI_EXP_LNKCAP_SLS_64_0GB ? PCIE_SPEED_64_0GT : \
|
||||
- (lnkcap) == PCI_EXP_LNKCAP_SLS_32_0GB ? PCIE_SPEED_32_0GT : \
|
||||
- (lnkcap) == PCI_EXP_LNKCAP_SLS_16_0GB ? PCIE_SPEED_16_0GT : \
|
||||
- (lnkcap) == PCI_EXP_LNKCAP_SLS_8_0GB ? PCIE_SPEED_8_0GT : \
|
||||
- (lnkcap) == PCI_EXP_LNKCAP_SLS_5_0GB ? PCIE_SPEED_5_0GT : \
|
||||
- (lnkcap) == PCI_EXP_LNKCAP_SLS_2_5GB ? PCIE_SPEED_2_5GT : \
|
||||
+ u32 lnkcap_sls = (lnkcap) & PCI_EXP_LNKCAP_SLS; \
|
||||
+ \
|
||||
+ (lnkcap_sls == PCI_EXP_LNKCAP_SLS_64_0GB ? PCIE_SPEED_64_0GT : \
|
||||
+ lnkcap_sls == PCI_EXP_LNKCAP_SLS_32_0GB ? PCIE_SPEED_32_0GT : \
|
||||
+ lnkcap_sls == PCI_EXP_LNKCAP_SLS_16_0GB ? PCIE_SPEED_16_0GT : \
|
||||
+ lnkcap_sls == PCI_EXP_LNKCAP_SLS_8_0GB ? PCIE_SPEED_8_0GT : \
|
||||
+ lnkcap_sls == PCI_EXP_LNKCAP_SLS_5_0GB ? PCIE_SPEED_5_0GT : \
|
||||
+ lnkcap_sls == PCI_EXP_LNKCAP_SLS_2_5GB ? PCIE_SPEED_2_5GT : \
|
||||
PCI_SPEED_UNKNOWN); \
|
||||
})
|
||||
|
||||
@@ -411,13 +413,17 @@ void pci_bus_put(struct pci_bus *bus);
|
||||
PCI_SPEED_UNKNOWN)
|
||||
|
||||
#define PCIE_LNKCTL2_TLS2SPEED(lnkctl2) \
|
||||
- ((lnkctl2) == PCI_EXP_LNKCTL2_TLS_64_0GT ? PCIE_SPEED_64_0GT : \
|
||||
- (lnkctl2) == PCI_EXP_LNKCTL2_TLS_32_0GT ? PCIE_SPEED_32_0GT : \
|
||||
- (lnkctl2) == PCI_EXP_LNKCTL2_TLS_16_0GT ? PCIE_SPEED_16_0GT : \
|
||||
- (lnkctl2) == PCI_EXP_LNKCTL2_TLS_8_0GT ? PCIE_SPEED_8_0GT : \
|
||||
- (lnkctl2) == PCI_EXP_LNKCTL2_TLS_5_0GT ? PCIE_SPEED_5_0GT : \
|
||||
- (lnkctl2) == PCI_EXP_LNKCTL2_TLS_2_5GT ? PCIE_SPEED_2_5GT : \
|
||||
- PCI_SPEED_UNKNOWN)
|
||||
+({ \
|
||||
+ u16 lnkctl2_tls = (lnkctl2) & PCI_EXP_LNKCTL2_TLS; \
|
||||
+ \
|
||||
+ (lnkctl2_tls == PCI_EXP_LNKCTL2_TLS_64_0GT ? PCIE_SPEED_64_0GT : \
|
||||
+ lnkctl2_tls == PCI_EXP_LNKCTL2_TLS_32_0GT ? PCIE_SPEED_32_0GT : \
|
||||
+ lnkctl2_tls == PCI_EXP_LNKCTL2_TLS_16_0GT ? PCIE_SPEED_16_0GT : \
|
||||
+ lnkctl2_tls == PCI_EXP_LNKCTL2_TLS_8_0GT ? PCIE_SPEED_8_0GT : \
|
||||
+ lnkctl2_tls == PCI_EXP_LNKCTL2_TLS_5_0GT ? PCIE_SPEED_5_0GT : \
|
||||
+ lnkctl2_tls == PCI_EXP_LNKCTL2_TLS_2_5GT ? PCIE_SPEED_2_5GT : \
|
||||
+ PCI_SPEED_UNKNOWN); \
|
||||
+})
|
||||
|
||||
/* PCIe speed to Mb/s reduced by encoding overhead */
|
||||
#define PCIE_SPEED2MBS_ENC(speed) \
|
@@ -1,57 +0,0 @@
|
||||
From ab8a3c32946686d57d720dc4a1b23635fb4a39bd Mon Sep 17 00:00:00 2001
|
||||
From: Damien Le Moal <dlemoal@kernel.org>
|
||||
Date: Tue, 24 Jun 2025 20:45:43 +0900
|
||||
Subject: PCI: endpoint: Fix configfs group list head handling
|
||||
|
||||
Doing a list_del() on the epf_group field of struct pci_epf_driver in
|
||||
pci_epf_remove_cfs() is not correct as this field is a list head, not
|
||||
a list entry. This list_del() call triggers a KASAN warning when an
|
||||
endpoint function driver which has a configfs attribute group is torn
|
||||
down:
|
||||
|
||||
==================================================================
|
||||
BUG: KASAN: slab-use-after-free in pci_epf_remove_cfs+0x17c/0x198
|
||||
Write of size 8 at addr ffff00010f4a0d80 by task rmmod/319
|
||||
|
||||
CPU: 3 UID: 0 PID: 319 Comm: rmmod Not tainted 6.16.0-rc2 #1 NONE
|
||||
Hardware name: Radxa ROCK 5B (DT)
|
||||
Call trace:
|
||||
show_stack+0x2c/0x84 (C)
|
||||
dump_stack_lvl+0x70/0x98
|
||||
print_report+0x17c/0x538
|
||||
kasan_report+0xb8/0x190
|
||||
__asan_report_store8_noabort+0x20/0x2c
|
||||
pci_epf_remove_cfs+0x17c/0x198
|
||||
pci_epf_unregister_driver+0x18/0x30
|
||||
nvmet_pci_epf_cleanup_module+0x24/0x30 [nvmet_pci_epf]
|
||||
__arm64_sys_delete_module+0x264/0x424
|
||||
invoke_syscall+0x70/0x260
|
||||
el0_svc_common.constprop.0+0xac/0x230
|
||||
do_el0_svc+0x40/0x58
|
||||
el0_svc+0x48/0xdc
|
||||
el0t_64_sync_handler+0x10c/0x138
|
||||
el0t_64_sync+0x198/0x19c
|
||||
...
|
||||
|
||||
Remove this incorrect list_del() call from pci_epf_remove_cfs().
|
||||
|
||||
Fixes: ef1433f717a2 ("PCI: endpoint: Create configfs entry for each pci_epf_device_id table entry")
|
||||
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
|
||||
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
|
||||
Reviewed-by: Niklas Cassel <cassel@kernel.org>
|
||||
Cc: stable@vger.kernel.org
|
||||
Link: https://patch.msgid.link/20250624114544.342159-2-dlemoal@kernel.org
|
||||
---
|
||||
drivers/pci/endpoint/pci-epf-core.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/pci/endpoint/pci-epf-core.c
|
||||
+++ b/drivers/pci/endpoint/pci-epf-core.c
|
||||
@@ -338,7 +338,6 @@ static void pci_epf_remove_cfs(struct pc
|
||||
mutex_lock(&pci_epf_mutex);
|
||||
list_for_each_entry_safe(group, tmp, &driver->epf_group, group_entry)
|
||||
pci_ep_cfs_remove_epf_group(group);
|
||||
- list_del(&driver->epf_group);
|
||||
mutex_unlock(&pci_epf_mutex);
|
||||
}
|
||||
|
@@ -1,48 +0,0 @@
|
||||
From ac49c252132396b1910ea5aad0541f550c55679c Mon Sep 17 00:00:00 2001
|
||||
From: Damien Le Moal <dlemoal@kernel.org>
|
||||
Date: Tue, 24 Jun 2025 20:45:44 +0900
|
||||
Subject: PCI: endpoint: Fix configfs group removal on driver teardown
|
||||
|
||||
An endpoint driver configfs attributes group is added to the
|
||||
epf_group list of struct pci_epf_driver by pci_epf_add_cfs() but an
|
||||
added group is not removed from this list when the attribute group is
|
||||
unregistered with pci_ep_cfs_remove_epf_group().
|
||||
|
||||
Add the missing list_del() call in pci_ep_cfs_remove_epf_group()
|
||||
to correctly remove the attribute group from the driver list.
|
||||
|
||||
With this change, once the loop over all attribute groups in
|
||||
pci_epf_remove_cfs() completes, the driver epf_group list should be
|
||||
empty. Add a WARN_ON() to make sure of that.
|
||||
|
||||
Fixes: ef1433f717a2 ("PCI: endpoint: Create configfs entry for each pci_epf_device_id table entry")
|
||||
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
|
||||
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
|
||||
Reviewed-by: Niklas Cassel <cassel@kernel.org>
|
||||
Cc: stable@vger.kernel.org
|
||||
Link: https://patch.msgid.link/20250624114544.342159-3-dlemoal@kernel.org
|
||||
---
|
||||
drivers/pci/endpoint/pci-ep-cfs.c | 1 +
|
||||
drivers/pci/endpoint/pci-epf-core.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/pci/endpoint/pci-ep-cfs.c
|
||||
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
|
||||
@@ -691,6 +691,7 @@ void pci_ep_cfs_remove_epf_group(struct
|
||||
if (IS_ERR_OR_NULL(group))
|
||||
return;
|
||||
|
||||
+ list_del(&group->group_entry);
|
||||
configfs_unregister_default_group(group);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
|
||||
--- a/drivers/pci/endpoint/pci-epf-core.c
|
||||
+++ b/drivers/pci/endpoint/pci-epf-core.c
|
||||
@@ -338,6 +338,7 @@ static void pci_epf_remove_cfs(struct pc
|
||||
mutex_lock(&pci_epf_mutex);
|
||||
list_for_each_entry_safe(group, tmp, &driver->epf_group, group_entry)
|
||||
pci_ep_cfs_remove_epf_group(group);
|
||||
+ WARN_ON(!list_empty(&driver->epf_group));
|
||||
mutex_unlock(&pci_epf_mutex);
|
||||
}
|
||||
|
@@ -1,40 +0,0 @@
|
||||
From bb8fada608c868a04288371c76dd387bb9ce5101 Mon Sep 17 00:00:00 2001
|
||||
From: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
Date: Thu, 8 May 2025 18:55:38 +0300
|
||||
Subject: media: v4l2-ctrls: Don't reset handler's error in
|
||||
v4l2_ctrl_handler_free()
|
||||
|
||||
It's a common pattern in drivers to free the control handler's resources
|
||||
and then return the handler's error code on drivers' error handling paths.
|
||||
Alas, the v4l2_ctrl_handler_free() function also zeroes the error field,
|
||||
effectively indicating successful return to the caller.
|
||||
|
||||
There's no apparent need to touch the error field while releasing the
|
||||
control handler's resources and cleaning up stale pointers. Not touching
|
||||
the handler's error field is a more certain way to address this problem
|
||||
than changing all the users, in which case the pattern would be likely to
|
||||
re-emerge in new drivers.
|
||||
|
||||
Do just that, don't touch the control handler's error field in
|
||||
v4l2_ctrl_handler_free().
|
||||
|
||||
Fixes: 0996517cf8ea ("V4L/DVB: v4l2: Add new control handling framework")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
---
|
||||
drivers/media/v4l2-core/v4l2-ctrls-core.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
|
||||
@@ -1661,7 +1661,6 @@ void v4l2_ctrl_handler_free(struct v4l2_
|
||||
kvfree(hdl->buckets);
|
||||
hdl->buckets = NULL;
|
||||
hdl->cached = NULL;
|
||||
- hdl->error = 0;
|
||||
mutex_unlock(hdl->lock);
|
||||
mutex_destroy(&hdl->_lock);
|
||||
}
|
@@ -1,145 +0,0 @@
|
||||
From e90295abea9dd31f84e7784e19e988be0dfcfb83 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Le Moal <dlemoal@kernel.org>
|
||||
Date: Wed, 25 Jun 2025 18:33:26 +0900
|
||||
Subject: dm: dm-crypt: Do not partially accept write BIOs with zoned targets
|
||||
|
||||
Read and write operations issued to a dm-crypt target may be split
|
||||
according to the dm-crypt internal limits defined by the max_read_size
|
||||
and max_write_size module parameters (default is 128 KB). The intent is
|
||||
to improve processing time of large BIOs by splitting them into smaller
|
||||
operations that can be parallelized on different CPUs.
|
||||
|
||||
For zoned dm-crypt targets, this BIO splitting is still done but without
|
||||
the parallel execution to ensure that the issuing order of write
|
||||
operations to the underlying devices remains sequential. However, the
|
||||
splitting itself causes other problems:
|
||||
|
||||
1) Since dm-crypt relies on the block layer zone write plugging to
|
||||
handle zone append emulation using regular write operations, the
|
||||
reminder of a split write BIO will always be plugged into the target
|
||||
zone write plugged. Once the on-going write BIO finishes, this
|
||||
reminder BIO is unplugged and issued from the zone write plug work.
|
||||
If this reminder BIO itself needs to be split, the reminder will be
|
||||
re-issued and plugged again, but that causes a call to a
|
||||
blk_queue_enter(), which may block if a queue freeze operation was
|
||||
initiated. This results in a deadlock as DM submission still holds
|
||||
BIOs that the queue freeze side is waiting for.
|
||||
|
||||
2) dm-crypt relies on the emulation done by the block layer using
|
||||
regular write operations for processing zone append operations. This
|
||||
still requires to properly return the written sector as the BIO
|
||||
sector of the original BIO. However, this can be done correctly only
|
||||
and only if there is a single clone BIO used for processing the
|
||||
original zone append operation issued by the user. If the size of a
|
||||
zone append operation is larger than dm-crypt max_write_size, then
|
||||
the orginal BIO will be split and processed as a chain of regular
|
||||
write operations. Such chaining result in an incorrect written sector
|
||||
being returned to the zone append issuer using the original BIO
|
||||
sector. This in turn results in file system data corruptions using
|
||||
xfs or btrfs.
|
||||
|
||||
Fix this by modifying get_max_request_size() to always return the size
|
||||
of the BIO to avoid it being split with dm_accpet_partial_bio() in
|
||||
crypt_map(). get_max_request_size() is renamed to
|
||||
get_max_request_sectors() to clarify the unit of the value returned
|
||||
and its interface is changed to take a struct dm_target pointer and a
|
||||
pointer to the struct bio being processed. In addition to this change,
|
||||
to ensure that crypt_alloc_buffer() works correctly, set the dm-crypt
|
||||
device max_hw_sectors limit to be at most
|
||||
BIO_MAX_VECS << PAGE_SECTORS_SHIFT (1 MB with a 4KB page architecture).
|
||||
This forces DM core to split write BIOs before passing them to
|
||||
crypt_map(), and thus guaranteeing that dm-crypt can always accept an
|
||||
entire write BIO without needing to split it.
|
||||
|
||||
This change does not have any effect on the read path of dm-crypt. Read
|
||||
operations can still be split and the BIO fragments processed in
|
||||
parallel. There is also no impact on the performance of the write path
|
||||
given that all zone write BIOs were already processed inline instead of
|
||||
in parallel.
|
||||
|
||||
This change also does not affect in any way regular dm-crypt block
|
||||
devices.
|
||||
|
||||
Fixes: f211268ed1f9 ("dm: Use the block layer zone append emulation")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
|
||||
Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20250625093327.548866-5-dlemoal@kernel.org
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
---
|
||||
drivers/md/dm-crypt.c | 49 ++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 39 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/md/dm-crypt.c
|
||||
+++ b/drivers/md/dm-crypt.c
|
||||
@@ -253,17 +253,35 @@ MODULE_PARM_DESC(max_read_size, "Maximum
|
||||
static unsigned int max_write_size = 0;
|
||||
module_param(max_write_size, uint, 0644);
|
||||
MODULE_PARM_DESC(max_write_size, "Maximum size of a write request");
|
||||
-static unsigned get_max_request_size(struct crypt_config *cc, bool wrt)
|
||||
+
|
||||
+static unsigned get_max_request_sectors(struct dm_target *ti, struct bio *bio)
|
||||
{
|
||||
+ struct crypt_config *cc = ti->private;
|
||||
unsigned val, sector_align;
|
||||
- val = !wrt ? READ_ONCE(max_read_size) : READ_ONCE(max_write_size);
|
||||
- if (likely(!val))
|
||||
- val = !wrt ? DM_CRYPT_DEFAULT_MAX_READ_SIZE : DM_CRYPT_DEFAULT_MAX_WRITE_SIZE;
|
||||
- if (wrt || cc->used_tag_size) {
|
||||
- if (unlikely(val > BIO_MAX_VECS << PAGE_SHIFT))
|
||||
- val = BIO_MAX_VECS << PAGE_SHIFT;
|
||||
+ bool wrt = op_is_write(bio_op(bio));
|
||||
+
|
||||
+ if (wrt) {
|
||||
+ /*
|
||||
+ * For zoned devices, splitting write operations creates the
|
||||
+ * risk of deadlocking queue freeze operations with zone write
|
||||
+ * plugging BIO work when the reminder of a split BIO is
|
||||
+ * issued. So always allow the entire BIO to proceed.
|
||||
+ */
|
||||
+ if (ti->emulate_zone_append)
|
||||
+ return bio_sectors(bio);
|
||||
+
|
||||
+ val = min_not_zero(READ_ONCE(max_write_size),
|
||||
+ DM_CRYPT_DEFAULT_MAX_WRITE_SIZE);
|
||||
+ } else {
|
||||
+ val = min_not_zero(READ_ONCE(max_read_size),
|
||||
+ DM_CRYPT_DEFAULT_MAX_READ_SIZE);
|
||||
}
|
||||
- sector_align = max(bdev_logical_block_size(cc->dev->bdev), (unsigned)cc->sector_size);
|
||||
+
|
||||
+ if (wrt || cc->used_tag_size)
|
||||
+ val = min(val, BIO_MAX_VECS << PAGE_SHIFT);
|
||||
+
|
||||
+ sector_align = max(bdev_logical_block_size(cc->dev->bdev),
|
||||
+ (unsigned)cc->sector_size);
|
||||
val = round_down(val, sector_align);
|
||||
if (unlikely(!val))
|
||||
val = sector_align;
|
||||
@@ -3496,7 +3514,7 @@ static int crypt_map(struct dm_target *t
|
||||
/*
|
||||
* Check if bio is too large, split as needed.
|
||||
*/
|
||||
- max_sectors = get_max_request_size(cc, bio_data_dir(bio) == WRITE);
|
||||
+ max_sectors = get_max_request_sectors(ti, bio);
|
||||
if (unlikely(bio_sectors(bio) > max_sectors))
|
||||
dm_accept_partial_bio(bio, max_sectors);
|
||||
|
||||
@@ -3733,6 +3751,17 @@ static void crypt_io_hints(struct dm_tar
|
||||
max_t(unsigned int, limits->physical_block_size, cc->sector_size);
|
||||
limits->io_min = max_t(unsigned int, limits->io_min, cc->sector_size);
|
||||
limits->dma_alignment = limits->logical_block_size - 1;
|
||||
+
|
||||
+ /*
|
||||
+ * For zoned dm-crypt targets, there will be no internal splitting of
|
||||
+ * write BIOs to avoid exceeding BIO_MAX_VECS vectors per BIO. But
|
||||
+ * without respecting this limit, crypt_alloc_buffer() will trigger a
|
||||
+ * BUG(). Avoid this by forcing DM core to split write BIOs to this
|
||||
+ * limit.
|
||||
+ */
|
||||
+ if (ti->emulate_zone_append)
|
||||
+ limits->max_hw_sectors = min(limits->max_hw_sectors,
|
||||
+ BIO_MAX_VECS << PAGE_SECTORS_SHIFT);
|
||||
}
|
||||
|
||||
static struct target_type crypt_target = {
|
@@ -1,62 +0,0 @@
|
||||
From 32eefb128e8ca539632595379da05e5662b72161 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Le Moal <dlemoal@kernel.org>
|
||||
Date: Wed, 25 Jun 2025 18:33:27 +0900
|
||||
Subject: dm: Check for forbidden splitting of zone write operations
|
||||
|
||||
DM targets must not split zone append and write operations using
|
||||
dm_accept_partial_bio() as doing so is forbidden for zone append BIOs,
|
||||
breaks zone append emulation using regular write BIOs and potentially
|
||||
creates deadlock situations with queue freeze operations.
|
||||
|
||||
Modify dm_accept_partial_bio() to add missing BUG_ON() checks for all
|
||||
these cases, that is, check that the BIO is a write or write zeroes
|
||||
operation. This change packs all the zone related checks together under
|
||||
a static_branch_unlikely(&zoned_enabled) and done only if the target is
|
||||
a zoned device.
|
||||
|
||||
Fixes: f211268ed1f9 ("dm: Use the block layer zone append emulation")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
|
||||
Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20250625093327.548866-6-dlemoal@kernel.org
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
---
|
||||
drivers/md/dm.c | 17 +++++++++++++----
|
||||
1 file changed, 13 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/md/dm.c
|
||||
+++ b/drivers/md/dm.c
|
||||
@@ -1293,8 +1293,9 @@ out:
|
||||
/*
|
||||
* A target may call dm_accept_partial_bio only from the map routine. It is
|
||||
* allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_* zone management
|
||||
- * operations, REQ_OP_ZONE_APPEND (zone append writes) and any bio serviced by
|
||||
- * __send_duplicate_bios().
|
||||
+ * operations, zone append writes (native with REQ_OP_ZONE_APPEND or emulated
|
||||
+ * with write BIOs flagged with BIO_EMULATES_ZONE_APPEND) and any bio serviced
|
||||
+ * by __send_duplicate_bios().
|
||||
*
|
||||
* dm_accept_partial_bio informs the dm that the target only wants to process
|
||||
* additional n_sectors sectors of the bio and the rest of the data should be
|
||||
@@ -1327,11 +1328,19 @@ void dm_accept_partial_bio(struct bio *b
|
||||
unsigned int bio_sectors = bio_sectors(bio);
|
||||
|
||||
BUG_ON(dm_tio_flagged(tio, DM_TIO_IS_DUPLICATE_BIO));
|
||||
- BUG_ON(op_is_zone_mgmt(bio_op(bio)));
|
||||
- BUG_ON(bio_op(bio) == REQ_OP_ZONE_APPEND);
|
||||
BUG_ON(bio_sectors > *tio->len_ptr);
|
||||
BUG_ON(n_sectors > bio_sectors);
|
||||
|
||||
+ if (static_branch_unlikely(&zoned_enabled) &&
|
||||
+ unlikely(bdev_is_zoned(bio->bi_bdev))) {
|
||||
+ enum req_op op = bio_op(bio);
|
||||
+
|
||||
+ BUG_ON(op_is_zone_mgmt(op));
|
||||
+ BUG_ON(op == REQ_OP_WRITE);
|
||||
+ BUG_ON(op == REQ_OP_WRITE_ZEROES);
|
||||
+ BUG_ON(op == REQ_OP_ZONE_APPEND);
|
||||
+ }
|
||||
+
|
||||
*tio->len_ptr -= bio_sectors - n_sectors;
|
||||
bio->bi_iter.bi_size = n_sectors << SECTOR_SHIFT;
|
||||
|
@@ -1,110 +0,0 @@
|
||||
From 457eadbe8b4399d1c64d99536f5a2029f5e793d6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <mwalle@kernel.org>
|
||||
Date: Tue, 1 Jul 2025 16:04:26 +0200
|
||||
Subject: mtd: spi-nor: Fix spi_nor_try_unlock_all()
|
||||
|
||||
Commit ff67592cbdfc ("mtd: spi-nor: Introduce spi_nor_set_mtd_info()")
|
||||
moved all initialization of the mtd fields at the end of spi_nor_scan().
|
||||
Normally, the mtd info is only needed for the mtd ops on the device,
|
||||
with one exception: spi_nor_try_unlock_all(), which will also make use
|
||||
of the mtd->size parameter. With that commit, the size will always be
|
||||
zero because it is not initialized. Fix that by not using the size of
|
||||
the mtd_info struct, but use the size from struct spi_nor_flash_parameter.
|
||||
|
||||
Fixes: ff67592cbdfc ("mtd: spi-nor: Introduce spi_nor_set_mtd_info()")
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Jean-Marc Ranger <jmranger@hotmail.com>
|
||||
Closes: https://lore.kernel.org/all/DM6PR06MB561177323DC5207E34AF2A06C547A@DM6PR06MB5611.namprd06.prod.outlook.com/
|
||||
Tested-by: Jean-Marc Ranger <jmranger@hotmail.com>
|
||||
Signed-off-by: Michael Walle <mwalle@kernel.org>
|
||||
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
|
||||
Signed-off-by: Pratyush Yadav <pratyush@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250701140426.2355182-1-mwalle@kernel.org
|
||||
---
|
||||
drivers/mtd/spi-nor/swp.c | 19 ++++++++-----------
|
||||
1 file changed, 8 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/swp.c
|
||||
+++ b/drivers/mtd/spi-nor/swp.c
|
||||
@@ -56,7 +56,6 @@ static u64 spi_nor_get_min_prot_length_s
|
||||
static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
|
||||
u64 *len)
|
||||
{
|
||||
- struct mtd_info *mtd = &nor->mtd;
|
||||
u64 min_prot_len;
|
||||
u8 mask = spi_nor_get_sr_bp_mask(nor);
|
||||
u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
|
||||
@@ -77,13 +76,13 @@ static void spi_nor_get_locked_range_sr(
|
||||
min_prot_len = spi_nor_get_min_prot_length_sr(nor);
|
||||
*len = min_prot_len << (bp - 1);
|
||||
|
||||
- if (*len > mtd->size)
|
||||
- *len = mtd->size;
|
||||
+ if (*len > nor->params->size)
|
||||
+ *len = nor->params->size;
|
||||
|
||||
if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask)
|
||||
*ofs = 0;
|
||||
else
|
||||
- *ofs = mtd->size - *len;
|
||||
+ *ofs = nor->params->size - *len;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,7 +157,6 @@ static bool spi_nor_is_unlocked_sr(struc
|
||||
*/
|
||||
static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
|
||||
{
|
||||
- struct mtd_info *mtd = &nor->mtd;
|
||||
u64 min_prot_len;
|
||||
int ret, status_old, status_new;
|
||||
u8 mask = spi_nor_get_sr_bp_mask(nor);
|
||||
@@ -183,7 +181,7 @@ static int spi_nor_sr_lock(struct spi_no
|
||||
can_be_bottom = false;
|
||||
|
||||
/* If anything above us is unlocked, we can't use 'top' protection */
|
||||
- if (!spi_nor_is_locked_sr(nor, ofs + len, mtd->size - (ofs + len),
|
||||
+ if (!spi_nor_is_locked_sr(nor, ofs + len, nor->params->size - (ofs + len),
|
||||
status_old))
|
||||
can_be_top = false;
|
||||
|
||||
@@ -195,11 +193,11 @@ static int spi_nor_sr_lock(struct spi_no
|
||||
|
||||
/* lock_len: length of region that should end up locked */
|
||||
if (use_top)
|
||||
- lock_len = mtd->size - ofs;
|
||||
+ lock_len = nor->params->size - ofs;
|
||||
else
|
||||
lock_len = ofs + len;
|
||||
|
||||
- if (lock_len == mtd->size) {
|
||||
+ if (lock_len == nor->params->size) {
|
||||
val = mask;
|
||||
} else {
|
||||
min_prot_len = spi_nor_get_min_prot_length_sr(nor);
|
||||
@@ -248,7 +246,6 @@ static int spi_nor_sr_lock(struct spi_no
|
||||
*/
|
||||
static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
|
||||
{
|
||||
- struct mtd_info *mtd = &nor->mtd;
|
||||
u64 min_prot_len;
|
||||
int ret, status_old, status_new;
|
||||
u8 mask = spi_nor_get_sr_bp_mask(nor);
|
||||
@@ -273,7 +270,7 @@ static int spi_nor_sr_unlock(struct spi_
|
||||
can_be_top = false;
|
||||
|
||||
/* If anything above us is locked, we can't use 'bottom' protection */
|
||||
- if (!spi_nor_is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len),
|
||||
+ if (!spi_nor_is_unlocked_sr(nor, ofs + len, nor->params->size - (ofs + len),
|
||||
status_old))
|
||||
can_be_bottom = false;
|
||||
|
||||
@@ -285,7 +282,7 @@ static int spi_nor_sr_unlock(struct spi_
|
||||
|
||||
/* lock_len: length of region that should remain locked */
|
||||
if (use_top)
|
||||
- lock_len = mtd->size - (ofs + len);
|
||||
+ lock_len = nor->params->size - (ofs + len);
|
||||
else
|
||||
lock_len = ofs;
|
||||
|
@@ -1,40 +0,0 @@
|
||||
From dd30d1837412d22457fc47562da3e4ae9c7d70ae Mon Sep 17 00:00:00 2001
|
||||
From: Chi Zhiling <chizhiling@kylinos.cn>
|
||||
Date: Thu, 5 Jun 2025 13:49:35 +0800
|
||||
Subject: readahead: fix return value of page_cache_next_miss() when no hole is
|
||||
found
|
||||
|
||||
max_scan in page_cache_next_miss always decreases to zero when no hole is
|
||||
found, causing the return value to be index + 0.
|
||||
|
||||
Fix this by preserving the max_scan value throughout the loop.
|
||||
|
||||
Jan said "From what I know and have seen in the past, wrong responses
|
||||
from page_cache_next_miss() can lead to readahead window reduction and
|
||||
thus reduced read speeds."
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250605054935.2323451-1-chizhiling@163.com
|
||||
Fixes: 901a269ff3d5 ("filemap: fix page_cache_next_miss() when no hole found")
|
||||
Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
|
||||
Reviewed-by: Jan Kara <jack@suse.cz>
|
||||
Cc: Josef Bacik <josef@toxicpanda.com>
|
||||
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/filemap.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/mm/filemap.c
|
||||
+++ b/mm/filemap.c
|
||||
@@ -1778,8 +1778,9 @@ pgoff_t page_cache_next_miss(struct addr
|
||||
pgoff_t index, unsigned long max_scan)
|
||||
{
|
||||
XA_STATE(xas, &mapping->i_pages, index);
|
||||
+ unsigned long nr = max_scan;
|
||||
|
||||
- while (max_scan--) {
|
||||
+ while (nr--) {
|
||||
void *entry = xas_next(&xas);
|
||||
if (!entry || xa_is_value(entry))
|
||||
return xas.xa_index;
|
@@ -0,0 +1,74 @@
|
||||
From 7a6182b5469b0c09373c8c02517c75305a899291 Mon Sep 17 00:00:00 2001
|
||||
From: Nikolay Kuratov <kniv@yandex-team.ru>
|
||||
Date: Tue, 5 Aug 2025 16:09:17 +0300
|
||||
Subject: vhost/net: Protect ubufs with rcu read lock in vhost_net_ubuf_put()
|
||||
|
||||
When operating on struct vhost_net_ubuf_ref, the following execution
|
||||
sequence is theoretically possible:
|
||||
CPU0 is finalizing DMA operation CPU1 is doing VHOST_NET_SET_BACKEND
|
||||
// ubufs->refcount == 2
|
||||
vhost_net_ubuf_put() vhost_net_ubuf_put_wait_and_free(oldubufs)
|
||||
vhost_net_ubuf_put_and_wait()
|
||||
vhost_net_ubuf_put()
|
||||
int r = atomic_sub_return(1, &ubufs->refcount);
|
||||
// r = 1
|
||||
int r = atomic_sub_return(1, &ubufs->refcount);
|
||||
// r = 0
|
||||
wait_event(ubufs->wait, !atomic_read(&ubufs->refcount));
|
||||
// no wait occurs here because condition is already true
|
||||
kfree(ubufs);
|
||||
if (unlikely(!r))
|
||||
wake_up(&ubufs->wait); // use-after-free
|
||||
|
||||
This leads to use-after-free on ubufs access. This happens because CPU1
|
||||
skips waiting for wake_up() when refcount is already zero.
|
||||
|
||||
To prevent that use a read-side RCU critical section in vhost_net_ubuf_put(),
|
||||
as suggested by Hillf Danton. For this lock to take effect, free ubufs with
|
||||
kfree_rcu().
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 0ad8b480d6ee9 ("vhost: fix ref cnt checking deadlock")
|
||||
Reported-by: Andrey Ryabinin <arbn@yandex-team.com>
|
||||
Suggested-by: Hillf Danton <hdanton@sina.com>
|
||||
Signed-off-by: Nikolay Kuratov <kniv@yandex-team.ru>
|
||||
Message-Id: <20250805130917.727332-1-kniv@yandex-team.ru>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
drivers/vhost/net.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/vhost/net.c
|
||||
+++ b/drivers/vhost/net.c
|
||||
@@ -96,6 +96,7 @@ struct vhost_net_ubuf_ref {
|
||||
atomic_t refcount;
|
||||
wait_queue_head_t wait;
|
||||
struct vhost_virtqueue *vq;
|
||||
+ struct rcu_head rcu;
|
||||
};
|
||||
|
||||
#define VHOST_NET_BATCH 64
|
||||
@@ -247,9 +248,13 @@ vhost_net_ubuf_alloc(struct vhost_virtqu
|
||||
|
||||
static int vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs)
|
||||
{
|
||||
- int r = atomic_sub_return(1, &ubufs->refcount);
|
||||
+ int r;
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ r = atomic_sub_return(1, &ubufs->refcount);
|
||||
if (unlikely(!r))
|
||||
wake_up(&ubufs->wait);
|
||||
+ rcu_read_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -262,7 +267,7 @@ static void vhost_net_ubuf_put_and_wait(
|
||||
static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs)
|
||||
{
|
||||
vhost_net_ubuf_put_and_wait(ubufs);
|
||||
- kfree(ubufs);
|
||||
+ kfree_rcu(ubufs, rcu);
|
||||
}
|
||||
|
||||
static void vhost_net_clear_ubuf_info(struct vhost_net *n)
|
@@ -1,77 +0,0 @@
|
||||
From 143c76ac94eddb9c2cb5ff4f57d78f60e22d9e20 Mon Sep 17 00:00:00 2001
|
||||
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
|
||||
Date: Wed, 9 Jul 2025 12:41:45 +0200
|
||||
Subject: PM: runtime: Take active children into account in
|
||||
pm_runtime_get_if_in_use()
|
||||
|
||||
For all practical purposes, there is no difference between the situation
|
||||
in which a given device is not ignoring children and its active child
|
||||
count is nonzero and the situation in which its runtime PM usage counter
|
||||
is nonzero. However, pm_runtime_get_if_in_use() will only increment the
|
||||
device's usage counter and return 1 in the latter case.
|
||||
|
||||
For consistency, make it do so in the former case either by adjusting
|
||||
pm_runtime_get_conditional() and update the related kerneldoc comments
|
||||
accordingly.
|
||||
|
||||
Fixes: c111566bea7c ("PM: runtime: Add pm_runtime_get_if_active()")
|
||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
Cc: 5.10+ <stable@vger.kernel.org> # 5.10+: c0ef3df8dbae: PM: runtime: Simplify pm_runtime_get_if_active() usage
|
||||
Cc: 5.10+ <stable@vger.kernel.org> # 5.10+
|
||||
Link: https://patch.msgid.link/12700973.O9o76ZdvQC@rjwysocki.net
|
||||
---
|
||||
drivers/base/power/runtime.c | 27 ++++++++++++++++++---------
|
||||
1 file changed, 18 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/base/power/runtime.c
|
||||
+++ b/drivers/base/power/runtime.c
|
||||
@@ -1191,10 +1191,12 @@ EXPORT_SYMBOL_GPL(__pm_runtime_resume);
|
||||
*
|
||||
* Return -EINVAL if runtime PM is disabled for @dev.
|
||||
*
|
||||
- * Otherwise, if the runtime PM status of @dev is %RPM_ACTIVE and either
|
||||
- * @ign_usage_count is %true or the runtime PM usage counter of @dev is not
|
||||
- * zero, increment the usage counter of @dev and return 1. Otherwise, return 0
|
||||
- * without changing the usage counter.
|
||||
+ * Otherwise, if its runtime PM status is %RPM_ACTIVE and (1) @ign_usage_count
|
||||
+ * is set, or (2) @dev is not ignoring children and its active child count is
|
||||
+ * nonero, or (3) the runtime PM usage counter of @dev is not zero, increment
|
||||
+ * the usage counter of @dev and return 1.
|
||||
+ *
|
||||
+ * Otherwise, return 0 without changing the usage counter.
|
||||
*
|
||||
* If @ign_usage_count is %true, this function can be used to prevent suspending
|
||||
* the device when its runtime PM status is %RPM_ACTIVE.
|
||||
@@ -1216,7 +1218,8 @@ static int pm_runtime_get_conditional(st
|
||||
retval = -EINVAL;
|
||||
} else if (dev->power.runtime_status != RPM_ACTIVE) {
|
||||
retval = 0;
|
||||
- } else if (ign_usage_count) {
|
||||
+ } else if (ign_usage_count || (!dev->power.ignore_children &&
|
||||
+ atomic_read(&dev->power.child_count) > 0)) {
|
||||
retval = 1;
|
||||
atomic_inc(&dev->power.usage_count);
|
||||
} else {
|
||||
@@ -1249,10 +1252,16 @@ EXPORT_SYMBOL_GPL(pm_runtime_get_if_acti
|
||||
* @dev: Target device.
|
||||
*
|
||||
* Increment the runtime PM usage counter of @dev if its runtime PM status is
|
||||
- * %RPM_ACTIVE and its runtime PM usage counter is greater than 0, in which case
|
||||
- * it returns 1. If the device is in a different state or its usage_count is 0,
|
||||
- * 0 is returned. -EINVAL is returned if runtime PM is disabled for the device,
|
||||
- * in which case also the usage_count will remain unmodified.
|
||||
+ * %RPM_ACTIVE and its runtime PM usage counter is greater than 0 or it is not
|
||||
+ * ignoring children and its active child count is nonzero. 1 is returned in
|
||||
+ * this case.
|
||||
+ *
|
||||
+ * If @dev is in a different state or it is not in use (that is, its usage
|
||||
+ * counter is 0, or it is ignoring children, or its active child count is 0),
|
||||
+ * 0 is returned.
|
||||
+ *
|
||||
+ * -EINVAL is returned if runtime PM is disabled for the device, in which case
|
||||
+ * also the usage counter of @dev is not updated.
|
||||
*/
|
||||
int pm_runtime_get_if_in_use(struct device *dev)
|
||||
{
|
@@ -1,57 +0,0 @@
|
||||
From 127ab7f801b3ec9cf94d2436ef1f579a1fc09dd6 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@kernel.org>
|
||||
Date: Tue, 8 Jul 2025 12:38:28 -0700
|
||||
Subject: crypto: x86/aegis - Fix sleeping when disallowed on PREEMPT_RT
|
||||
|
||||
skcipher_walk_done() can call kfree(), which takes a spinlock, which
|
||||
makes it incorrect to call while preemption is disabled on PREEMPT_RT.
|
||||
Therefore, end the kernel-mode FPU section before calling
|
||||
skcipher_walk_done(), and restart it afterwards.
|
||||
|
||||
Moreover, pass atomic=false to skcipher_walk_aead_encrypt() instead of
|
||||
atomic=true. The point of atomic=true was to make skcipher_walk_done()
|
||||
safe to call while in a kernel-mode FPU section, but that does not
|
||||
actually work. So just use the usual atomic=false.
|
||||
|
||||
Fixes: 1d373d4e8e15 ("crypto: x86 - Add optimized AEGIS implementations")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
arch/x86/crypto/aegis128-aesni-glue.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/x86/crypto/aegis128-aesni-glue.c
|
||||
+++ b/arch/x86/crypto/aegis128-aesni-glue.c
|
||||
@@ -119,7 +119,9 @@ crypto_aegis128_aesni_process_crypt(stru
|
||||
walk->dst.virt.addr,
|
||||
round_down(walk->nbytes,
|
||||
AEGIS128_BLOCK_SIZE));
|
||||
+ kernel_fpu_end();
|
||||
skcipher_walk_done(walk, walk->nbytes % AEGIS128_BLOCK_SIZE);
|
||||
+ kernel_fpu_begin();
|
||||
}
|
||||
|
||||
if (walk->nbytes) {
|
||||
@@ -131,7 +133,9 @@ crypto_aegis128_aesni_process_crypt(stru
|
||||
aegis128_aesni_dec_tail(state, walk->src.virt.addr,
|
||||
walk->dst.virt.addr,
|
||||
walk->nbytes);
|
||||
+ kernel_fpu_end();
|
||||
skcipher_walk_done(walk, 0);
|
||||
+ kernel_fpu_begin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,9 +180,9 @@ crypto_aegis128_aesni_crypt(struct aead_
|
||||
struct aegis_state state;
|
||||
|
||||
if (enc)
|
||||
- skcipher_walk_aead_encrypt(&walk, req, true);
|
||||
+ skcipher_walk_aead_encrypt(&walk, req, false);
|
||||
else
|
||||
- skcipher_walk_aead_decrypt(&walk, req, true);
|
||||
+ skcipher_walk_aead_decrypt(&walk, req, false);
|
||||
|
||||
kernel_fpu_begin();
|
||||
|
@@ -1,122 +0,0 @@
|
||||
From 3bc9bc41e634767f001b7b37b6f1f89fc0214b8a Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@kernel.org>
|
||||
Date: Tue, 8 Jul 2025 12:38:29 -0700
|
||||
Subject: crypto: x86/aegis - Add missing error checks
|
||||
|
||||
The skcipher_walk functions can allocate memory and can fail, so
|
||||
checking for errors is necessary.
|
||||
|
||||
Fixes: 1d373d4e8e15 ("crypto: x86 - Add optimized AEGIS implementations")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
arch/x86/crypto/aegis128-aesni-glue.c | 36 +++++++++++++++++++--------
|
||||
1 file changed, 25 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/arch/x86/crypto/aegis128-aesni-glue.c
|
||||
+++ b/arch/x86/crypto/aegis128-aesni-glue.c
|
||||
@@ -104,10 +104,12 @@ static void crypto_aegis128_aesni_proces
|
||||
}
|
||||
}
|
||||
|
||||
-static __always_inline void
|
||||
+static __always_inline int
|
||||
crypto_aegis128_aesni_process_crypt(struct aegis_state *state,
|
||||
struct skcipher_walk *walk, bool enc)
|
||||
{
|
||||
+ int err = 0;
|
||||
+
|
||||
while (walk->nbytes >= AEGIS128_BLOCK_SIZE) {
|
||||
if (enc)
|
||||
aegis128_aesni_enc(state, walk->src.virt.addr,
|
||||
@@ -120,7 +122,8 @@ crypto_aegis128_aesni_process_crypt(stru
|
||||
round_down(walk->nbytes,
|
||||
AEGIS128_BLOCK_SIZE));
|
||||
kernel_fpu_end();
|
||||
- skcipher_walk_done(walk, walk->nbytes % AEGIS128_BLOCK_SIZE);
|
||||
+ err = skcipher_walk_done(walk,
|
||||
+ walk->nbytes % AEGIS128_BLOCK_SIZE);
|
||||
kernel_fpu_begin();
|
||||
}
|
||||
|
||||
@@ -134,9 +137,10 @@ crypto_aegis128_aesni_process_crypt(stru
|
||||
walk->dst.virt.addr,
|
||||
walk->nbytes);
|
||||
kernel_fpu_end();
|
||||
- skcipher_walk_done(walk, 0);
|
||||
+ err = skcipher_walk_done(walk, 0);
|
||||
kernel_fpu_begin();
|
||||
}
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static struct aegis_ctx *crypto_aegis128_aesni_ctx(struct crypto_aead *aead)
|
||||
@@ -169,7 +173,7 @@ static int crypto_aegis128_aesni_setauth
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static __always_inline void
|
||||
+static __always_inline int
|
||||
crypto_aegis128_aesni_crypt(struct aead_request *req,
|
||||
struct aegis_block *tag_xor,
|
||||
unsigned int cryptlen, bool enc)
|
||||
@@ -178,20 +182,24 @@ crypto_aegis128_aesni_crypt(struct aead_
|
||||
struct aegis_ctx *ctx = crypto_aegis128_aesni_ctx(tfm);
|
||||
struct skcipher_walk walk;
|
||||
struct aegis_state state;
|
||||
+ int err;
|
||||
|
||||
if (enc)
|
||||
- skcipher_walk_aead_encrypt(&walk, req, false);
|
||||
+ err = skcipher_walk_aead_encrypt(&walk, req, false);
|
||||
else
|
||||
- skcipher_walk_aead_decrypt(&walk, req, false);
|
||||
+ err = skcipher_walk_aead_decrypt(&walk, req, false);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
kernel_fpu_begin();
|
||||
|
||||
aegis128_aesni_init(&state, &ctx->key, req->iv);
|
||||
crypto_aegis128_aesni_process_ad(&state, req->src, req->assoclen);
|
||||
- crypto_aegis128_aesni_process_crypt(&state, &walk, enc);
|
||||
- aegis128_aesni_final(&state, tag_xor, req->assoclen, cryptlen);
|
||||
-
|
||||
+ err = crypto_aegis128_aesni_process_crypt(&state, &walk, enc);
|
||||
+ if (err == 0)
|
||||
+ aegis128_aesni_final(&state, tag_xor, req->assoclen, cryptlen);
|
||||
kernel_fpu_end();
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int crypto_aegis128_aesni_encrypt(struct aead_request *req)
|
||||
@@ -200,8 +208,11 @@ static int crypto_aegis128_aesni_encrypt
|
||||
struct aegis_block tag = {};
|
||||
unsigned int authsize = crypto_aead_authsize(tfm);
|
||||
unsigned int cryptlen = req->cryptlen;
|
||||
+ int err;
|
||||
|
||||
- crypto_aegis128_aesni_crypt(req, &tag, cryptlen, true);
|
||||
+ err = crypto_aegis128_aesni_crypt(req, &tag, cryptlen, true);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
scatterwalk_map_and_copy(tag.bytes, req->dst,
|
||||
req->assoclen + cryptlen, authsize, 1);
|
||||
@@ -216,11 +227,14 @@ static int crypto_aegis128_aesni_decrypt
|
||||
struct aegis_block tag;
|
||||
unsigned int authsize = crypto_aead_authsize(tfm);
|
||||
unsigned int cryptlen = req->cryptlen - authsize;
|
||||
+ int err;
|
||||
|
||||
scatterwalk_map_and_copy(tag.bytes, req->src,
|
||||
req->assoclen + cryptlen, authsize, 0);
|
||||
|
||||
- crypto_aegis128_aesni_crypt(req, &tag, cryptlen, false);
|
||||
+ err = crypto_aegis128_aesni_crypt(req, &tag, cryptlen, false);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
return crypto_memneq(tag.bytes, zeros.bytes, authsize) ? -EBADMSG : 0;
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
From 8b4284861b77422d25c46fe00402754ab1a156cc Mon Sep 17 00:00:00 2001
|
||||
From: Tim Harvey <tharvey@gateworks.com>
|
||||
Date: Fri, 18 Jul 2025 13:02:59 -0700
|
||||
Subject: hwmon: (gsc-hwmon) fix fan pwm setpoint show functions
|
||||
|
||||
The Linux hwmon sysfs API values for pwmX_auto_pointY_pwm represent an
|
||||
integer value between 0 (0%) to 255 (100%) and the pwmX_auto_pointY_temp
|
||||
represent millidegrees Celcius.
|
||||
|
||||
Commit a6d80df47ee2 ("hwmon: (gsc-hwmon) fix fan pwm temperature
|
||||
scaling") properly addressed the incorrect scaling in the
|
||||
pwm_auto_point_temp_store implementation but erroneously scaled
|
||||
the pwm_auto_point_pwm_show (pwm value) instead of the
|
||||
pwm_auto_point_temp_show (temp value) resulting in:
|
||||
# cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_pwm
|
||||
25500
|
||||
# cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_temp
|
||||
4500
|
||||
|
||||
Fix the scaling of these attributes:
|
||||
# cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_pwm
|
||||
255
|
||||
# cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_temp
|
||||
45000
|
||||
|
||||
Fixes: a6d80df47ee2 ("hwmon: (gsc-hwmon) fix fan pwm temperature scaling")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
|
||||
Link: https://lore.kernel.org/r/20250718200259.1840792-1-tharvey@gateworks.com
|
||||
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||
---
|
||||
drivers/hwmon/gsc-hwmon.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/hwmon/gsc-hwmon.c
|
||||
+++ b/drivers/hwmon/gsc-hwmon.c
|
||||
@@ -64,7 +64,7 @@ static ssize_t pwm_auto_point_temp_show(
|
||||
return ret;
|
||||
|
||||
ret = regs[0] | regs[1] << 8;
|
||||
- return sprintf(buf, "%d\n", ret * 10);
|
||||
+ return sprintf(buf, "%d\n", ret * 100);
|
||||
}
|
||||
|
||||
static ssize_t pwm_auto_point_temp_store(struct device *dev,
|
||||
@@ -99,7 +99,7 @@ static ssize_t pwm_auto_point_pwm_show(s
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
|
||||
|
||||
- return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)));
|
||||
+ return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100);
|
||||
}
|
||||
|
||||
static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
|
@@ -1,31 +0,0 @@
|
||||
From 3f91f07c241bea4ec294315cb41df81f123fa0bb Mon Sep 17 00:00:00 2001
|
||||
From: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
|
||||
Date: Wed, 2 Jul 2025 21:17:57 +0700
|
||||
Subject: vt: keyboard: Don't process Unicode characters in K_OFF mode
|
||||
|
||||
We don't process Unicode characters if the virtual terminal is in raw
|
||||
mode, so there's no reason why we shouldn't do the same for K_OFF
|
||||
(especially since people would expect K_OFF to actually turn off all VT
|
||||
key processing).
|
||||
|
||||
Fixes: 9fc3de9c8356 ("vt: Add virtual console keyboard mode OFF")
|
||||
Signed-off-by: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
|
||||
Cc: stable <stable@kernel.org>
|
||||
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250702-vt-misc-unicode-fixes-v1-1-c27e143cc2eb@qtmlabs.xyz
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/tty/vt/keyboard.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/tty/vt/keyboard.c
|
||||
+++ b/drivers/tty/vt/keyboard.c
|
||||
@@ -1487,7 +1487,7 @@ static void kbd_keycode(unsigned int key
|
||||
rc = atomic_notifier_call_chain(&keyboard_notifier_list,
|
||||
KBD_UNICODE, ¶m);
|
||||
if (rc != NOTIFY_STOP)
|
||||
- if (down && !raw_mode)
|
||||
+ if (down && !(raw_mode || kbd->kbdmode == VC_OFF))
|
||||
k_unicode(vc, keysym, !down);
|
||||
return;
|
||||
}
|
@@ -1,190 +0,0 @@
|
||||
From f575281d91029d2dbfa0fa628cdc72e80fcd626f Mon Sep 17 00:00:00 2001
|
||||
From: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
|
||||
Date: Wed, 2 Jul 2025 21:17:58 +0700
|
||||
Subject: vt: defkeymap: Map keycodes above 127 to K_HOLE
|
||||
|
||||
The maximum number of keycodes got bumped to 256 a very long time ago,
|
||||
but the default keymaps were never adjusted to match. This is causing
|
||||
the kernel to interpret keycodes above 127 as U+0000 if the shipped
|
||||
generated keymap is used.
|
||||
|
||||
Fix this by mapping all keycodes above 127 to K_HOLE so the kernel
|
||||
ignores them.
|
||||
|
||||
The contents of this patche were generated by rerunning `loadkeys
|
||||
--mktable --unicode` and only including the changes to map keycodes
|
||||
above 127 to K_HOLE.
|
||||
|
||||
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
|
||||
Signed-off-by: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
|
||||
Cc: stable <stable@kernel.org>
|
||||
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250702-vt-misc-unicode-fixes-v1-2-c27e143cc2eb@qtmlabs.xyz
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/tty/vt/defkeymap.c_shipped | 112 +++++++++++++++++++++++++++++
|
||||
1 file changed, 112 insertions(+)
|
||||
|
||||
--- a/drivers/tty/vt/defkeymap.c_shipped
|
||||
+++ b/drivers/tty/vt/defkeymap.c_shipped
|
||||
@@ -23,6 +23,22 @@ unsigned short plain_map[NR_KEYS] = {
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
static unsigned short shift_map[NR_KEYS] = {
|
||||
@@ -42,6 +58,22 @@ static unsigned short shift_map[NR_KEYS]
|
||||
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
static unsigned short altgr_map[NR_KEYS] = {
|
||||
@@ -61,6 +93,22 @@ static unsigned short altgr_map[NR_KEYS]
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
static unsigned short ctrl_map[NR_KEYS] = {
|
||||
@@ -80,6 +128,22 @@ static unsigned short ctrl_map[NR_KEYS]
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
static unsigned short shift_ctrl_map[NR_KEYS] = {
|
||||
@@ -99,6 +163,22 @@ static unsigned short shift_ctrl_map[NR_
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
static unsigned short alt_map[NR_KEYS] = {
|
||||
@@ -118,6 +198,22 @@ static unsigned short alt_map[NR_KEYS] =
|
||||
0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
static unsigned short ctrl_alt_map[NR_KEYS] = {
|
||||
@@ -137,6 +233,22 @@ static unsigned short ctrl_alt_map[NR_KE
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
unsigned short *key_maps[MAX_NR_KEYMAPS] = {
|
@@ -1,55 +0,0 @@
|
||||
From c0bcd8c710c48ab93f0b72c1a3611c39a68c3a74 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <cuiyunhui@bytedance.com>
|
||||
Date: Wed, 23 Jul 2025 10:33:22 +0800
|
||||
Subject: serial: 8250: fix panic due to PSLVERR
|
||||
|
||||
When the PSLVERR_RESP_EN parameter is set to 1, the device generates
|
||||
an error response if an attempt is made to read an empty RBR (Receive
|
||||
Buffer Register) while the FIFO is enabled.
|
||||
|
||||
In serial8250_do_startup(), calling serial_port_out(port, UART_LCR,
|
||||
UART_LCR_WLEN8) triggers dw8250_check_lcr(), which invokes
|
||||
dw8250_force_idle() and serial8250_clear_and_reinit_fifos(). The latter
|
||||
function enables the FIFO via serial_out(p, UART_FCR, p->fcr).
|
||||
Execution proceeds to the serial_port_in(port, UART_RX).
|
||||
This satisfies the PSLVERR trigger condition.
|
||||
|
||||
When another CPU (e.g., using printk()) is accessing the UART (UART
|
||||
is busy), the current CPU fails the check (value & ~UART_LCR_SPAR) ==
|
||||
(lcr & ~UART_LCR_SPAR) in dw8250_check_lcr(), causing it to enter
|
||||
dw8250_force_idle().
|
||||
|
||||
Put serial_port_out(port, UART_LCR, UART_LCR_WLEN8) under the port->lock
|
||||
to fix this issue.
|
||||
|
||||
Panic backtrace:
|
||||
[ 0.442336] Oops - unknown exception [#1]
|
||||
[ 0.442343] epc : dw8250_serial_in32+0x1e/0x4a
|
||||
[ 0.442351] ra : serial8250_do_startup+0x2c8/0x88e
|
||||
...
|
||||
[ 0.442416] console_on_rootfs+0x26/0x70
|
||||
|
||||
Fixes: c49436b657d0 ("serial: 8250_dw: Improve unwritable LCR workaround")
|
||||
Link: https://lore.kernel.org/all/84cydt5peu.fsf@jogness.linutronix.de/T/
|
||||
Signed-off-by: Yunhui Cui <cuiyunhui@bytedance.com>
|
||||
Reviewed-by: John Ogness <john.ogness@linutronix.de>
|
||||
Cc: stable <stable@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250723023322.464-2-cuiyunhui@bytedance.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/tty/serial/8250/8250_port.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/tty/serial/8250/8250_port.c
|
||||
+++ b/drivers/tty/serial/8250/8250_port.c
|
||||
@@ -2376,9 +2376,9 @@ int serial8250_do_startup(struct uart_po
|
||||
/*
|
||||
* Now, initialize the UART
|
||||
*/
|
||||
+ uart_port_lock_irqsave(port, &flags);
|
||||
serial_port_out(port, UART_LCR, UART_LCR_WLEN8);
|
||||
|
||||
- uart_port_lock_irqsave(port, &flags);
|
||||
if (up->port.flags & UPF_FOURPORT) {
|
||||
if (!up->port.irq)
|
||||
up->port.mctrl |= TIOCM_OUT1;
|
@@ -1,74 +0,0 @@
|
||||
From 2ee6decb1435c8331404d590f7a5a2d6a5711760 Mon Sep 17 00:00:00 2001
|
||||
From: SeongJae Park <sj@kernel.org>
|
||||
Date: Mon, 16 Jun 2025 10:23:44 -0700
|
||||
Subject: mm/damon/paddr: use alloc_migartion_target() with no migration
|
||||
fallback nodemask
|
||||
|
||||
Patch series "mm/damon: use alloc_migrate_target() for
|
||||
DAMOS_MIGRATE_{HOT,COLD}".
|
||||
|
||||
DAMOS_MIGRATE_{HOT,COLD} implementation resembles that for demotion, and
|
||||
hence the behavior is also similar to that. But, since those are not only
|
||||
for demotion but general migrations, it would be better to match with that
|
||||
for move_pages() system call. Make the implementation and the behavior
|
||||
more similar to move_pages() by not setting migration fallback nodes, and
|
||||
using alloc_migration_target() instead of alloc_migrate_folio().
|
||||
|
||||
alloc_migrate_folio() was renamed from alloc_demote_folio() and been
|
||||
non-static function, to let DAMOS_MIGRATE_{HOT,COLD} call it. As
|
||||
alloc_migration_target() is called instead, the renaming and de-static
|
||||
changes are no more required but could only make future code readers be
|
||||
confused. Revert the changes, too.
|
||||
|
||||
|
||||
This patch (of 3):
|
||||
|
||||
DAMOS_MIGRATE_{HOT,COLD} implementation resembles that for
|
||||
demote_folio_list(). Because those are not only for demotion but general
|
||||
folio migrations, it makes more sense to behave similarly to move_pages()
|
||||
system call. Make the behavior more similar to move_pages(), by using
|
||||
alloc_migration_target() instead of alloc_migrate_folio(), without
|
||||
fallback nodemask.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250616172346.67659-2-sj@kernel.org
|
||||
Signed-off-by: SeongJae Park <sj@kernel.org>
|
||||
Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>
|
||||
Cc: David Hildenbrand <david@redhat.com>
|
||||
Cc: Honggyu Kim <honggyu.kim@sk.com>
|
||||
Cc: Johannes Weiner <hannes@cmpxchg.org>
|
||||
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
Cc: Michal Hocko <mhocko@kernel.org>
|
||||
Cc: Qi Zheng <zhengqi.arch@bytedance.com>
|
||||
Cc: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/damon/paddr.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
--- a/mm/damon/paddr.c
|
||||
+++ b/mm/damon/paddr.c
|
||||
@@ -386,7 +386,6 @@ static unsigned int __damon_pa_migrate_f
|
||||
int target_nid)
|
||||
{
|
||||
unsigned int nr_succeeded = 0;
|
||||
- nodemask_t allowed_mask = NODE_MASK_NONE;
|
||||
struct migration_target_control mtc = {
|
||||
/*
|
||||
* Allocate from 'node', or fail quickly and quietly.
|
||||
@@ -396,7 +395,6 @@ static unsigned int __damon_pa_migrate_f
|
||||
.gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
|
||||
__GFP_NOWARN | __GFP_NOMEMALLOC | GFP_NOWAIT,
|
||||
.nid = target_nid,
|
||||
- .nmask = &allowed_mask
|
||||
};
|
||||
|
||||
if (pgdat->node_id == target_nid || target_nid == NUMA_NO_NODE)
|
||||
@@ -406,7 +404,7 @@ static unsigned int __damon_pa_migrate_f
|
||||
return 0;
|
||||
|
||||
/* Migration ignores all cpuset and mempolicy settings */
|
||||
- migrate_pages(migrate_folios, alloc_migrate_folio, NULL,
|
||||
+ migrate_pages(migrate_folios, alloc_migration_target, NULL,
|
||||
(unsigned long)&mtc, MIGRATE_ASYNC, MR_DAMON,
|
||||
&nr_succeeded);
|
||||
|
@@ -1,318 +0,0 @@
|
||||
From 9292d9753eeab6dd9492ec28b79045ab4890652a Mon Sep 17 00:00:00 2001
|
||||
From: Bijan Tabatabai <bijantabatab@micron.com>
|
||||
Date: Tue, 8 Jul 2025 19:59:38 -0500
|
||||
Subject: mm/damon: move migration helpers from paddr to ops-common
|
||||
|
||||
This patch moves the damon_pa_migrate_pages function along with its
|
||||
corresponding helper functions from paddr to ops-common. The function
|
||||
prefix of "damon_pa_" was also changed to just "damon_" accordingly.
|
||||
|
||||
This patch will allow page migration to be available to vaddr schemes as
|
||||
well as paddr schemes.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250709005952.17776-9-bijan311@gmail.com
|
||||
Co-developed-by: Ravi Shankar Jonnalagadda <ravis.opensrc@micron.com>
|
||||
Signed-off-by: Ravi Shankar Jonnalagadda <ravis.opensrc@micron.com>
|
||||
Signed-off-by: Bijan Tabatabai <bijantabatab@micron.com>
|
||||
Reviewed-by: SeongJae Park <sj@kernel.org>
|
||||
Cc: Jonathan Corbet <corbet@lwn.net>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/damon/ops-common.c | 120 +++++++++++++++++++++++++++++++++++++++++
|
||||
mm/damon/ops-common.h | 2 +
|
||||
mm/damon/paddr.c | 122 +-----------------------------------------
|
||||
3 files changed, 123 insertions(+), 121 deletions(-)
|
||||
|
||||
--- a/mm/damon/ops-common.c
|
||||
+++ b/mm/damon/ops-common.c
|
||||
@@ -5,6 +5,7 @@
|
||||
* Author: SeongJae Park <sj@kernel.org>
|
||||
*/
|
||||
|
||||
+#include <linux/migrate.h>
|
||||
#include <linux/mmu_notifier.h>
|
||||
#include <linux/page_idle.h>
|
||||
#include <linux/pagemap.h>
|
||||
@@ -12,6 +13,7 @@
|
||||
#include <linux/swap.h>
|
||||
#include <linux/swapops.h>
|
||||
|
||||
+#include "../internal.h"
|
||||
#include "ops-common.h"
|
||||
|
||||
/*
|
||||
@@ -138,3 +140,121 @@ int damon_cold_score(struct damon_ctx *c
|
||||
/* Return coldness of the region */
|
||||
return DAMOS_MAX_SCORE - hotness;
|
||||
}
|
||||
+
|
||||
+static unsigned int __damon_migrate_folio_list(
|
||||
+ struct list_head *migrate_folios, struct pglist_data *pgdat,
|
||||
+ int target_nid)
|
||||
+{
|
||||
+ unsigned int nr_succeeded = 0;
|
||||
+ struct migration_target_control mtc = {
|
||||
+ /*
|
||||
+ * Allocate from 'node', or fail quickly and quietly.
|
||||
+ * When this happens, 'page' will likely just be discarded
|
||||
+ * instead of migrated.
|
||||
+ */
|
||||
+ .gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
|
||||
+ __GFP_NOWARN | __GFP_NOMEMALLOC | GFP_NOWAIT,
|
||||
+ .nid = target_nid,
|
||||
+ };
|
||||
+
|
||||
+ if (pgdat->node_id == target_nid || target_nid == NUMA_NO_NODE)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (list_empty(migrate_folios))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Migration ignores all cpuset and mempolicy settings */
|
||||
+ migrate_pages(migrate_folios, alloc_migration_target, NULL,
|
||||
+ (unsigned long)&mtc, MIGRATE_ASYNC, MR_DAMON,
|
||||
+ &nr_succeeded);
|
||||
+
|
||||
+ return nr_succeeded;
|
||||
+}
|
||||
+
|
||||
+static unsigned int damon_migrate_folio_list(struct list_head *folio_list,
|
||||
+ struct pglist_data *pgdat,
|
||||
+ int target_nid)
|
||||
+{
|
||||
+ unsigned int nr_migrated = 0;
|
||||
+ struct folio *folio;
|
||||
+ LIST_HEAD(ret_folios);
|
||||
+ LIST_HEAD(migrate_folios);
|
||||
+
|
||||
+ while (!list_empty(folio_list)) {
|
||||
+ struct folio *folio;
|
||||
+
|
||||
+ cond_resched();
|
||||
+
|
||||
+ folio = lru_to_folio(folio_list);
|
||||
+ list_del(&folio->lru);
|
||||
+
|
||||
+ if (!folio_trylock(folio))
|
||||
+ goto keep;
|
||||
+
|
||||
+ /* Relocate its contents to another node. */
|
||||
+ list_add(&folio->lru, &migrate_folios);
|
||||
+ folio_unlock(folio);
|
||||
+ continue;
|
||||
+keep:
|
||||
+ list_add(&folio->lru, &ret_folios);
|
||||
+ }
|
||||
+ /* 'folio_list' is always empty here */
|
||||
+
|
||||
+ /* Migrate folios selected for migration */
|
||||
+ nr_migrated += __damon_migrate_folio_list(
|
||||
+ &migrate_folios, pgdat, target_nid);
|
||||
+ /*
|
||||
+ * Folios that could not be migrated are still in @migrate_folios. Add
|
||||
+ * those back on @folio_list
|
||||
+ */
|
||||
+ if (!list_empty(&migrate_folios))
|
||||
+ list_splice_init(&migrate_folios, folio_list);
|
||||
+
|
||||
+ try_to_unmap_flush();
|
||||
+
|
||||
+ list_splice(&ret_folios, folio_list);
|
||||
+
|
||||
+ while (!list_empty(folio_list)) {
|
||||
+ folio = lru_to_folio(folio_list);
|
||||
+ list_del(&folio->lru);
|
||||
+ folio_putback_lru(folio);
|
||||
+ }
|
||||
+
|
||||
+ return nr_migrated;
|
||||
+}
|
||||
+
|
||||
+unsigned long damon_migrate_pages(struct list_head *folio_list, int target_nid)
|
||||
+{
|
||||
+ int nid;
|
||||
+ unsigned long nr_migrated = 0;
|
||||
+ LIST_HEAD(node_folio_list);
|
||||
+ unsigned int noreclaim_flag;
|
||||
+
|
||||
+ if (list_empty(folio_list))
|
||||
+ return nr_migrated;
|
||||
+
|
||||
+ noreclaim_flag = memalloc_noreclaim_save();
|
||||
+
|
||||
+ nid = folio_nid(lru_to_folio(folio_list));
|
||||
+ do {
|
||||
+ struct folio *folio = lru_to_folio(folio_list);
|
||||
+
|
||||
+ if (nid == folio_nid(folio)) {
|
||||
+ list_move(&folio->lru, &node_folio_list);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ nr_migrated += damon_migrate_folio_list(&node_folio_list,
|
||||
+ NODE_DATA(nid),
|
||||
+ target_nid);
|
||||
+ nid = folio_nid(lru_to_folio(folio_list));
|
||||
+ } while (!list_empty(folio_list));
|
||||
+
|
||||
+ nr_migrated += damon_migrate_folio_list(&node_folio_list,
|
||||
+ NODE_DATA(nid),
|
||||
+ target_nid);
|
||||
+
|
||||
+ memalloc_noreclaim_restore(noreclaim_flag);
|
||||
+
|
||||
+ return nr_migrated;
|
||||
+}
|
||||
--- a/mm/damon/ops-common.h
|
||||
+++ b/mm/damon/ops-common.h
|
||||
@@ -16,3 +16,5 @@ int damon_cold_score(struct damon_ctx *c
|
||||
struct damos *s);
|
||||
int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
|
||||
struct damos *s);
|
||||
+
|
||||
+unsigned long damon_migrate_pages(struct list_head *folio_list, int target_nid);
|
||||
--- a/mm/damon/paddr.c
|
||||
+++ b/mm/damon/paddr.c
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <linux/rmap.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/memory-tiers.h>
|
||||
-#include <linux/migrate.h>
|
||||
#include <linux/mm_inline.h>
|
||||
|
||||
#include "../internal.h"
|
||||
@@ -381,125 +380,6 @@ static unsigned long damon_pa_deactivate
|
||||
sz_filter_passed);
|
||||
}
|
||||
|
||||
-static unsigned int __damon_pa_migrate_folio_list(
|
||||
- struct list_head *migrate_folios, struct pglist_data *pgdat,
|
||||
- int target_nid)
|
||||
-{
|
||||
- unsigned int nr_succeeded = 0;
|
||||
- struct migration_target_control mtc = {
|
||||
- /*
|
||||
- * Allocate from 'node', or fail quickly and quietly.
|
||||
- * When this happens, 'page' will likely just be discarded
|
||||
- * instead of migrated.
|
||||
- */
|
||||
- .gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
|
||||
- __GFP_NOWARN | __GFP_NOMEMALLOC | GFP_NOWAIT,
|
||||
- .nid = target_nid,
|
||||
- };
|
||||
-
|
||||
- if (pgdat->node_id == target_nid || target_nid == NUMA_NO_NODE)
|
||||
- return 0;
|
||||
-
|
||||
- if (list_empty(migrate_folios))
|
||||
- return 0;
|
||||
-
|
||||
- /* Migration ignores all cpuset and mempolicy settings */
|
||||
- migrate_pages(migrate_folios, alloc_migration_target, NULL,
|
||||
- (unsigned long)&mtc, MIGRATE_ASYNC, MR_DAMON,
|
||||
- &nr_succeeded);
|
||||
-
|
||||
- return nr_succeeded;
|
||||
-}
|
||||
-
|
||||
-static unsigned int damon_pa_migrate_folio_list(struct list_head *folio_list,
|
||||
- struct pglist_data *pgdat,
|
||||
- int target_nid)
|
||||
-{
|
||||
- unsigned int nr_migrated = 0;
|
||||
- struct folio *folio;
|
||||
- LIST_HEAD(ret_folios);
|
||||
- LIST_HEAD(migrate_folios);
|
||||
-
|
||||
- while (!list_empty(folio_list)) {
|
||||
- struct folio *folio;
|
||||
-
|
||||
- cond_resched();
|
||||
-
|
||||
- folio = lru_to_folio(folio_list);
|
||||
- list_del(&folio->lru);
|
||||
-
|
||||
- if (!folio_trylock(folio))
|
||||
- goto keep;
|
||||
-
|
||||
- /* Relocate its contents to another node. */
|
||||
- list_add(&folio->lru, &migrate_folios);
|
||||
- folio_unlock(folio);
|
||||
- continue;
|
||||
-keep:
|
||||
- list_add(&folio->lru, &ret_folios);
|
||||
- }
|
||||
- /* 'folio_list' is always empty here */
|
||||
-
|
||||
- /* Migrate folios selected for migration */
|
||||
- nr_migrated += __damon_pa_migrate_folio_list(
|
||||
- &migrate_folios, pgdat, target_nid);
|
||||
- /*
|
||||
- * Folios that could not be migrated are still in @migrate_folios. Add
|
||||
- * those back on @folio_list
|
||||
- */
|
||||
- if (!list_empty(&migrate_folios))
|
||||
- list_splice_init(&migrate_folios, folio_list);
|
||||
-
|
||||
- try_to_unmap_flush();
|
||||
-
|
||||
- list_splice(&ret_folios, folio_list);
|
||||
-
|
||||
- while (!list_empty(folio_list)) {
|
||||
- folio = lru_to_folio(folio_list);
|
||||
- list_del(&folio->lru);
|
||||
- folio_putback_lru(folio);
|
||||
- }
|
||||
-
|
||||
- return nr_migrated;
|
||||
-}
|
||||
-
|
||||
-static unsigned long damon_pa_migrate_pages(struct list_head *folio_list,
|
||||
- int target_nid)
|
||||
-{
|
||||
- int nid;
|
||||
- unsigned long nr_migrated = 0;
|
||||
- LIST_HEAD(node_folio_list);
|
||||
- unsigned int noreclaim_flag;
|
||||
-
|
||||
- if (list_empty(folio_list))
|
||||
- return nr_migrated;
|
||||
-
|
||||
- noreclaim_flag = memalloc_noreclaim_save();
|
||||
-
|
||||
- nid = folio_nid(lru_to_folio(folio_list));
|
||||
- do {
|
||||
- struct folio *folio = lru_to_folio(folio_list);
|
||||
-
|
||||
- if (nid == folio_nid(folio)) {
|
||||
- list_move(&folio->lru, &node_folio_list);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- nr_migrated += damon_pa_migrate_folio_list(&node_folio_list,
|
||||
- NODE_DATA(nid),
|
||||
- target_nid);
|
||||
- nid = folio_nid(lru_to_folio(folio_list));
|
||||
- } while (!list_empty(folio_list));
|
||||
-
|
||||
- nr_migrated += damon_pa_migrate_folio_list(&node_folio_list,
|
||||
- NODE_DATA(nid),
|
||||
- target_nid);
|
||||
-
|
||||
- memalloc_noreclaim_restore(noreclaim_flag);
|
||||
-
|
||||
- return nr_migrated;
|
||||
-}
|
||||
-
|
||||
static unsigned long damon_pa_migrate(struct damon_region *r, struct damos *s,
|
||||
unsigned long *sz_filter_passed)
|
||||
{
|
||||
@@ -527,7 +407,7 @@ put_folio:
|
||||
addr += folio_size(folio);
|
||||
folio_put(folio);
|
||||
}
|
||||
- applied = damon_pa_migrate_pages(&folio_list, s->target_nid);
|
||||
+ applied = damon_migrate_pages(&folio_list, s->target_nid);
|
||||
cond_resched();
|
||||
s->last_applied = folio;
|
||||
return applied * PAGE_SIZE;
|
@@ -1,381 +0,0 @@
|
||||
From 98fbe2f62c4263248a325867c439f9d7222a3c64 Mon Sep 17 00:00:00 2001
|
||||
From: Bijan Tabatabai <bijantabatab@micron.com>
|
||||
Date: Tue, 8 Jul 2025 19:59:42 -0500
|
||||
Subject: mm/damon: move folio filtering from paddr to ops-common
|
||||
|
||||
This patch moves damos_pa_filter_match and the functions it calls to
|
||||
ops-common, renaming it to damos_folio_filter_match. Doing so allows us
|
||||
to share the filtering logic for the vaddr version of the
|
||||
migrate_{hot,cold} schemes.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250709005952.17776-13-bijan311@gmail.com
|
||||
Co-developed-by: Ravi Shankar Jonnalagadda <ravis.opensrc@micron.com>
|
||||
Signed-off-by: Ravi Shankar Jonnalagadda <ravis.opensrc@micron.com>
|
||||
Signed-off-by: Bijan Tabatabai <bijantabatab@micron.com>
|
||||
Reviewed-by: SeongJae Park <sj@kernel.org>
|
||||
Cc: Jonathan Corbet <corbet@lwn.net>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/damon/ops-common.c | 150 +++++++++++++++++++++++++++++++++++++++++
|
||||
mm/damon/ops-common.h | 3 +
|
||||
mm/damon/paddr.c | 153 +-----------------------------------------
|
||||
3 files changed, 154 insertions(+), 152 deletions(-)
|
||||
|
||||
--- a/mm/damon/ops-common.c
|
||||
+++ b/mm/damon/ops-common.c
|
||||
@@ -141,6 +141,156 @@ int damon_cold_score(struct damon_ctx *c
|
||||
return DAMOS_MAX_SCORE - hotness;
|
||||
}
|
||||
|
||||
+static bool damon_folio_mkold_one(struct folio *folio,
|
||||
+ struct vm_area_struct *vma, unsigned long addr, void *arg)
|
||||
+{
|
||||
+ DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, addr, 0);
|
||||
+
|
||||
+ while (page_vma_mapped_walk(&pvmw)) {
|
||||
+ addr = pvmw.address;
|
||||
+ if (pvmw.pte)
|
||||
+ damon_ptep_mkold(pvmw.pte, vma, addr);
|
||||
+ else
|
||||
+ damon_pmdp_mkold(pvmw.pmd, vma, addr);
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+void damon_folio_mkold(struct folio *folio)
|
||||
+{
|
||||
+ struct rmap_walk_control rwc = {
|
||||
+ .rmap_one = damon_folio_mkold_one,
|
||||
+ .anon_lock = folio_lock_anon_vma_read,
|
||||
+ };
|
||||
+ bool need_lock;
|
||||
+
|
||||
+ if (!folio_mapped(folio) || !folio_raw_mapping(folio)) {
|
||||
+ folio_set_idle(folio);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ need_lock = !folio_test_anon(folio) || folio_test_ksm(folio);
|
||||
+ if (need_lock && !folio_trylock(folio))
|
||||
+ return;
|
||||
+
|
||||
+ rmap_walk(folio, &rwc);
|
||||
+
|
||||
+ if (need_lock)
|
||||
+ folio_unlock(folio);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static bool damon_folio_young_one(struct folio *folio,
|
||||
+ struct vm_area_struct *vma, unsigned long addr, void *arg)
|
||||
+{
|
||||
+ bool *accessed = arg;
|
||||
+ DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, addr, 0);
|
||||
+ pte_t pte;
|
||||
+
|
||||
+ *accessed = false;
|
||||
+ while (page_vma_mapped_walk(&pvmw)) {
|
||||
+ addr = pvmw.address;
|
||||
+ if (pvmw.pte) {
|
||||
+ pte = ptep_get(pvmw.pte);
|
||||
+
|
||||
+ /*
|
||||
+ * PFN swap PTEs, such as device-exclusive ones, that
|
||||
+ * actually map pages are "old" from a CPU perspective.
|
||||
+ * The MMU notifier takes care of any device aspects.
|
||||
+ */
|
||||
+ *accessed = (pte_present(pte) && pte_young(pte)) ||
|
||||
+ !folio_test_idle(folio) ||
|
||||
+ mmu_notifier_test_young(vma->vm_mm, addr);
|
||||
+ } else {
|
||||
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
+ *accessed = pmd_young(pmdp_get(pvmw.pmd)) ||
|
||||
+ !folio_test_idle(folio) ||
|
||||
+ mmu_notifier_test_young(vma->vm_mm, addr);
|
||||
+#else
|
||||
+ WARN_ON_ONCE(1);
|
||||
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
+ }
|
||||
+ if (*accessed) {
|
||||
+ page_vma_mapped_walk_done(&pvmw);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* If accessed, stop walking */
|
||||
+ return *accessed == false;
|
||||
+}
|
||||
+
|
||||
+bool damon_folio_young(struct folio *folio)
|
||||
+{
|
||||
+ bool accessed = false;
|
||||
+ struct rmap_walk_control rwc = {
|
||||
+ .arg = &accessed,
|
||||
+ .rmap_one = damon_folio_young_one,
|
||||
+ .anon_lock = folio_lock_anon_vma_read,
|
||||
+ };
|
||||
+ bool need_lock;
|
||||
+
|
||||
+ if (!folio_mapped(folio) || !folio_raw_mapping(folio)) {
|
||||
+ if (folio_test_idle(folio))
|
||||
+ return false;
|
||||
+ else
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ need_lock = !folio_test_anon(folio) || folio_test_ksm(folio);
|
||||
+ if (need_lock && !folio_trylock(folio))
|
||||
+ return false;
|
||||
+
|
||||
+ rmap_walk(folio, &rwc);
|
||||
+
|
||||
+ if (need_lock)
|
||||
+ folio_unlock(folio);
|
||||
+
|
||||
+ return accessed;
|
||||
+}
|
||||
+
|
||||
+bool damos_folio_filter_match(struct damos_filter *filter, struct folio *folio)
|
||||
+{
|
||||
+ bool matched = false;
|
||||
+ struct mem_cgroup *memcg;
|
||||
+ size_t folio_sz;
|
||||
+
|
||||
+ switch (filter->type) {
|
||||
+ case DAMOS_FILTER_TYPE_ANON:
|
||||
+ matched = folio_test_anon(folio);
|
||||
+ break;
|
||||
+ case DAMOS_FILTER_TYPE_ACTIVE:
|
||||
+ matched = folio_test_active(folio);
|
||||
+ break;
|
||||
+ case DAMOS_FILTER_TYPE_MEMCG:
|
||||
+ rcu_read_lock();
|
||||
+ memcg = folio_memcg_check(folio);
|
||||
+ if (!memcg)
|
||||
+ matched = false;
|
||||
+ else
|
||||
+ matched = filter->memcg_id == mem_cgroup_id(memcg);
|
||||
+ rcu_read_unlock();
|
||||
+ break;
|
||||
+ case DAMOS_FILTER_TYPE_YOUNG:
|
||||
+ matched = damon_folio_young(folio);
|
||||
+ if (matched)
|
||||
+ damon_folio_mkold(folio);
|
||||
+ break;
|
||||
+ case DAMOS_FILTER_TYPE_HUGEPAGE_SIZE:
|
||||
+ folio_sz = folio_size(folio);
|
||||
+ matched = filter->sz_range.min <= folio_sz &&
|
||||
+ folio_sz <= filter->sz_range.max;
|
||||
+ break;
|
||||
+ case DAMOS_FILTER_TYPE_UNMAPPED:
|
||||
+ matched = !folio_mapped(folio) || !folio_raw_mapping(folio);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return matched == filter->matching;
|
||||
+}
|
||||
+
|
||||
static unsigned int __damon_migrate_folio_list(
|
||||
struct list_head *migrate_folios, struct pglist_data *pgdat,
|
||||
int target_nid)
|
||||
--- a/mm/damon/ops-common.h
|
||||
+++ b/mm/damon/ops-common.h
|
||||
@@ -11,10 +11,13 @@ struct folio *damon_get_folio(unsigned l
|
||||
|
||||
void damon_ptep_mkold(pte_t *pte, struct vm_area_struct *vma, unsigned long addr);
|
||||
void damon_pmdp_mkold(pmd_t *pmd, struct vm_area_struct *vma, unsigned long addr);
|
||||
+void damon_folio_mkold(struct folio *folio);
|
||||
+bool damon_folio_young(struct folio *folio);
|
||||
|
||||
int damon_cold_score(struct damon_ctx *c, struct damon_region *r,
|
||||
struct damos *s);
|
||||
int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
|
||||
struct damos *s);
|
||||
|
||||
+bool damos_folio_filter_match(struct damos_filter *filter, struct folio *folio);
|
||||
unsigned long damon_migrate_pages(struct list_head *folio_list, int target_nid);
|
||||
--- a/mm/damon/paddr.c
|
||||
+++ b/mm/damon/paddr.c
|
||||
@@ -18,45 +18,6 @@
|
||||
#include "../internal.h"
|
||||
#include "ops-common.h"
|
||||
|
||||
-static bool damon_folio_mkold_one(struct folio *folio,
|
||||
- struct vm_area_struct *vma, unsigned long addr, void *arg)
|
||||
-{
|
||||
- DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, addr, 0);
|
||||
-
|
||||
- while (page_vma_mapped_walk(&pvmw)) {
|
||||
- addr = pvmw.address;
|
||||
- if (pvmw.pte)
|
||||
- damon_ptep_mkold(pvmw.pte, vma, addr);
|
||||
- else
|
||||
- damon_pmdp_mkold(pvmw.pmd, vma, addr);
|
||||
- }
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-static void damon_folio_mkold(struct folio *folio)
|
||||
-{
|
||||
- struct rmap_walk_control rwc = {
|
||||
- .rmap_one = damon_folio_mkold_one,
|
||||
- .anon_lock = folio_lock_anon_vma_read,
|
||||
- };
|
||||
- bool need_lock;
|
||||
-
|
||||
- if (!folio_mapped(folio) || !folio_raw_mapping(folio)) {
|
||||
- folio_set_idle(folio);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- need_lock = !folio_test_anon(folio) || folio_test_ksm(folio);
|
||||
- if (need_lock && !folio_trylock(folio))
|
||||
- return;
|
||||
-
|
||||
- rmap_walk(folio, &rwc);
|
||||
-
|
||||
- if (need_lock)
|
||||
- folio_unlock(folio);
|
||||
-
|
||||
-}
|
||||
-
|
||||
static void damon_pa_mkold(unsigned long paddr)
|
||||
{
|
||||
struct folio *folio = damon_get_folio(PHYS_PFN(paddr));
|
||||
@@ -86,75 +47,6 @@ static void damon_pa_prepare_access_chec
|
||||
}
|
||||
}
|
||||
|
||||
-static bool damon_folio_young_one(struct folio *folio,
|
||||
- struct vm_area_struct *vma, unsigned long addr, void *arg)
|
||||
-{
|
||||
- bool *accessed = arg;
|
||||
- DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, addr, 0);
|
||||
- pte_t pte;
|
||||
-
|
||||
- *accessed = false;
|
||||
- while (page_vma_mapped_walk(&pvmw)) {
|
||||
- addr = pvmw.address;
|
||||
- if (pvmw.pte) {
|
||||
- pte = ptep_get(pvmw.pte);
|
||||
-
|
||||
- /*
|
||||
- * PFN swap PTEs, such as device-exclusive ones, that
|
||||
- * actually map pages are "old" from a CPU perspective.
|
||||
- * The MMU notifier takes care of any device aspects.
|
||||
- */
|
||||
- *accessed = (pte_present(pte) && pte_young(pte)) ||
|
||||
- !folio_test_idle(folio) ||
|
||||
- mmu_notifier_test_young(vma->vm_mm, addr);
|
||||
- } else {
|
||||
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
- *accessed = pmd_young(pmdp_get(pvmw.pmd)) ||
|
||||
- !folio_test_idle(folio) ||
|
||||
- mmu_notifier_test_young(vma->vm_mm, addr);
|
||||
-#else
|
||||
- WARN_ON_ONCE(1);
|
||||
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
- }
|
||||
- if (*accessed) {
|
||||
- page_vma_mapped_walk_done(&pvmw);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* If accessed, stop walking */
|
||||
- return *accessed == false;
|
||||
-}
|
||||
-
|
||||
-static bool damon_folio_young(struct folio *folio)
|
||||
-{
|
||||
- bool accessed = false;
|
||||
- struct rmap_walk_control rwc = {
|
||||
- .arg = &accessed,
|
||||
- .rmap_one = damon_folio_young_one,
|
||||
- .anon_lock = folio_lock_anon_vma_read,
|
||||
- };
|
||||
- bool need_lock;
|
||||
-
|
||||
- if (!folio_mapped(folio) || !folio_raw_mapping(folio)) {
|
||||
- if (folio_test_idle(folio))
|
||||
- return false;
|
||||
- else
|
||||
- return true;
|
||||
- }
|
||||
-
|
||||
- need_lock = !folio_test_anon(folio) || folio_test_ksm(folio);
|
||||
- if (need_lock && !folio_trylock(folio))
|
||||
- return false;
|
||||
-
|
||||
- rmap_walk(folio, &rwc);
|
||||
-
|
||||
- if (need_lock)
|
||||
- folio_unlock(folio);
|
||||
-
|
||||
- return accessed;
|
||||
-}
|
||||
-
|
||||
static bool damon_pa_young(unsigned long paddr, unsigned long *folio_sz)
|
||||
{
|
||||
struct folio *folio = damon_get_folio(PHYS_PFN(paddr));
|
||||
@@ -205,49 +97,6 @@ static unsigned int damon_pa_check_acces
|
||||
return max_nr_accesses;
|
||||
}
|
||||
|
||||
-static bool damos_pa_filter_match(struct damos_filter *filter,
|
||||
- struct folio *folio)
|
||||
-{
|
||||
- bool matched = false;
|
||||
- struct mem_cgroup *memcg;
|
||||
- size_t folio_sz;
|
||||
-
|
||||
- switch (filter->type) {
|
||||
- case DAMOS_FILTER_TYPE_ANON:
|
||||
- matched = folio_test_anon(folio);
|
||||
- break;
|
||||
- case DAMOS_FILTER_TYPE_ACTIVE:
|
||||
- matched = folio_test_active(folio);
|
||||
- break;
|
||||
- case DAMOS_FILTER_TYPE_MEMCG:
|
||||
- rcu_read_lock();
|
||||
- memcg = folio_memcg_check(folio);
|
||||
- if (!memcg)
|
||||
- matched = false;
|
||||
- else
|
||||
- matched = filter->memcg_id == mem_cgroup_id(memcg);
|
||||
- rcu_read_unlock();
|
||||
- break;
|
||||
- case DAMOS_FILTER_TYPE_YOUNG:
|
||||
- matched = damon_folio_young(folio);
|
||||
- if (matched)
|
||||
- damon_folio_mkold(folio);
|
||||
- break;
|
||||
- case DAMOS_FILTER_TYPE_HUGEPAGE_SIZE:
|
||||
- folio_sz = folio_size(folio);
|
||||
- matched = filter->sz_range.min <= folio_sz &&
|
||||
- folio_sz <= filter->sz_range.max;
|
||||
- break;
|
||||
- case DAMOS_FILTER_TYPE_UNMAPPED:
|
||||
- matched = !folio_mapped(folio) || !folio_raw_mapping(folio);
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return matched == filter->matching;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* damos_pa_filter_out - Return true if the page should be filtered out.
|
||||
*/
|
||||
@@ -259,7 +108,7 @@ static bool damos_pa_filter_out(struct d
|
||||
return false;
|
||||
|
||||
damos_for_each_ops_filter(filter, scheme) {
|
||||
- if (damos_pa_filter_match(filter, folio))
|
||||
+ if (damos_folio_filter_match(filter, folio))
|
||||
return !filter->allow;
|
||||
}
|
||||
return scheme->ops_filters_default_reject;
|
@@ -1,58 +0,0 @@
|
||||
From 28ceaa34f71077b305a2fae3abf9e8af606fbae7 Mon Sep 17 00:00:00 2001
|
||||
From: SeongJae Park <sj@kernel.org>
|
||||
Date: Sun, 20 Jul 2025 11:58:22 -0700
|
||||
Subject: mm/damon/ops-common: ignore migration request to invalid nodes
|
||||
|
||||
damon_migrate_pages() tries migration even if the target node is invalid.
|
||||
If users mistakenly make such invalid requests via
|
||||
DAMOS_MIGRATE_{HOT,COLD} action, the below kernel BUG can happen.
|
||||
|
||||
[ 7831.883495] BUG: unable to handle page fault for address: 0000000000001f48
|
||||
[ 7831.884160] #PF: supervisor read access in kernel mode
|
||||
[ 7831.884681] #PF: error_code(0x0000) - not-present page
|
||||
[ 7831.885203] PGD 0 P4D 0
|
||||
[ 7831.885468] Oops: Oops: 0000 [#1] SMP PTI
|
||||
[ 7831.885852] CPU: 31 UID: 0 PID: 94202 Comm: kdamond.0 Not tainted 6.16.0-rc5-mm-new-damon+ #93 PREEMPT(voluntary)
|
||||
[ 7831.886913] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-4.el9 04/01/2014
|
||||
[ 7831.887777] RIP: 0010:__alloc_frozen_pages_noprof (include/linux/mmzone.h:1724 include/linux/mmzone.h:1750 mm/page_alloc.c:4936 mm/page_alloc.c:5137)
|
||||
[...]
|
||||
[ 7831.895953] Call Trace:
|
||||
[ 7831.896195] <TASK>
|
||||
[ 7831.896397] __folio_alloc_noprof (mm/page_alloc.c:5183 mm/page_alloc.c:5192)
|
||||
[ 7831.896787] migrate_pages_batch (mm/migrate.c:1189 mm/migrate.c:1851)
|
||||
[ 7831.897228] ? __pfx_alloc_migration_target (mm/migrate.c:2137)
|
||||
[ 7831.897735] migrate_pages (mm/migrate.c:2078)
|
||||
[ 7831.898141] ? __pfx_alloc_migration_target (mm/migrate.c:2137)
|
||||
[ 7831.898664] damon_migrate_folio_list (mm/damon/ops-common.c:321 mm/damon/ops-common.c:354)
|
||||
[ 7831.899140] damon_migrate_pages (mm/damon/ops-common.c:405)
|
||||
[...]
|
||||
|
||||
Add a target node validity check in damon_migrate_pages(). The validity
|
||||
check is stolen from that of do_pages_move(), which is being used for the
|
||||
move_pages() system call.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250720185822.1451-1-sj@kernel.org
|
||||
Fixes: b51820ebea65 ("mm/damon/paddr: introduce DAMOS_MIGRATE_COLD action for demotion") [6.11.x]
|
||||
Signed-off-by: SeongJae Park <sj@kernel.org>
|
||||
Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>
|
||||
Cc: Honggyu Kim <honggyu.kim@sk.com>
|
||||
Cc: Hyeongtak Ji <hyeongtak.ji@sk.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/damon/ops-common.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/mm/damon/ops-common.c
|
||||
+++ b/mm/damon/ops-common.c
|
||||
@@ -383,6 +383,10 @@ unsigned long damon_migrate_pages(struct
|
||||
if (list_empty(folio_list))
|
||||
return nr_migrated;
|
||||
|
||||
+ if (target_nid < 0 || target_nid >= MAX_NUMNODES ||
|
||||
+ !node_state(target_nid, N_MEMORY))
|
||||
+ return nr_migrated;
|
||||
+
|
||||
noreclaim_flag = memalloc_noreclaim_save();
|
||||
|
||||
nid = folio_nid(lru_to_folio(folio_list));
|
@@ -1,28 +0,0 @@
|
||||
From 20235e70d4e5f0f66e0b037e9e02ca7ec0cf97a5 Mon Sep 17 00:00:00 2001
|
||||
From: Johan Hovold <johan@kernel.org>
|
||||
Date: Thu, 24 Jul 2025 11:19:08 +0200
|
||||
Subject: usb: gadget: udc: renesas_usb3: fix device leak at unbind
|
||||
|
||||
Make sure to drop the reference to the companion device taken during
|
||||
probe when the driver is unbound.
|
||||
|
||||
Fixes: 39facfa01c9f ("usb: gadget: udc: renesas_usb3: Add register of usb role switch")
|
||||
Cc: stable@vger.kernel.org # 4.19
|
||||
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250724091910.21092-4-johan@kernel.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/gadget/udc/renesas_usb3.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/usb/gadget/udc/renesas_usb3.c
|
||||
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
|
||||
@@ -2657,6 +2657,7 @@ static void renesas_usb3_remove(struct p
|
||||
struct renesas_usb3 *usb3 = platform_get_drvdata(pdev);
|
||||
|
||||
debugfs_remove_recursive(usb3->dentry);
|
||||
+ put_device(usb3->host_dev);
|
||||
device_remove_file(&pdev->dev, &dev_attr_role);
|
||||
|
||||
cancel_work_sync(&usb3->role_work);
|
@@ -1,36 +0,0 @@
|
||||
From b958aba8ee0d90742627dd46324cd29fd3e3abce Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Wunner <lukas@wunner.de>
|
||||
Date: Sun, 13 Jul 2025 16:31:02 +0200
|
||||
Subject: PCI/portdrv: Use is_pciehp instead of is_hotplug_bridge
|
||||
|
||||
The PCIe port driver erroneously creates a subdevice for hotplug on ACPI
|
||||
slots which are handled by the ACPI hotplug driver.
|
||||
|
||||
Avoid by checking the is_pciehp flag instead of is_hotplug_bridge when
|
||||
deciding whether to create a subdevice. The latter encompasses ACPI slots
|
||||
whereas the former doesn't.
|
||||
|
||||
The superfluous subdevice has no real negative impact, it occupies memory
|
||||
and interrupt resources but otherwise just sits there waiting for
|
||||
interrupts from the slot that are never signaled.
|
||||
|
||||
Fixes: f8415222837b ("PCI: Use cached copy of PCI_EXP_SLTCAP_HPC bit")
|
||||
Signed-off-by: Lukas Wunner <lukas@wunner.de>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Cc: stable@vger.kernel.org # v4.7+
|
||||
Link: https://patch.msgid.link/40d5a5fe8d40595d505949c620a067fa110ee85e.1752390102.git.lukas@wunner.de
|
||||
---
|
||||
drivers/pci/pcie/portdrv.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/pci/pcie/portdrv.c
|
||||
+++ b/drivers/pci/pcie/portdrv.c
|
||||
@@ -220,7 +220,7 @@ static int get_port_device_capability(st
|
||||
struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
|
||||
int services = 0;
|
||||
|
||||
- if (dev->is_hotplug_bridge &&
|
||||
+ if (dev->is_pciehp &&
|
||||
(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&
|
||||
(pcie_ports_native || host->native_pcie_hotplug)) {
|
@@ -1,85 +0,0 @@
|
||||
From eb5df6a83646eb2ecd7eda995b5632031acf94b3 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Le Moal <dlemoal@kernel.org>
|
||||
Date: Tue, 29 Jul 2025 18:28:07 +0900
|
||||
Subject: ata: libata-scsi: Fix ata_to_sense_error() status handling
|
||||
|
||||
Commit 8ae720449fca ("libata: whitespace fixes in ata_to_sense_error()")
|
||||
inadvertantly added the entry 0x40 (ATA_DRDY) to the stat_table array in
|
||||
the function ata_to_sense_error(). This entry ties a failed qc which has
|
||||
a status filed equal to ATA_DRDY to the sense key ILLEGAL REQUEST with
|
||||
the additional sense code UNALIGNED WRITE COMMAND. This entry will be
|
||||
used to generate a failed qc sense key and sense code when the qc is
|
||||
missing sense data and there is no match for the qc error field in the
|
||||
sense_table array of ata_to_sense_error().
|
||||
|
||||
As a result, for a failed qc for which we failed to get sense data (e.g.
|
||||
read log 10h failed if qc is an NCQ command, or REQUEST SENSE EXT
|
||||
command failed for the non-ncq case, the user very often end up seeing
|
||||
the completely misleading "unaligned write command" error, even if qc
|
||||
was not a write command. E.g.:
|
||||
|
||||
sd 0:0:0:0: [sda] tag#12 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s
|
||||
sd 0:0:0:0: [sda] tag#12 Sense Key : Illegal Request [current]
|
||||
sd 0:0:0:0: [sda] tag#12 Add. Sense: Unaligned write command
|
||||
sd 0:0:0:0: [sda] tag#12 CDB: Read(10) 28 00 00 00 10 00 00 00 08 00
|
||||
I/O error, dev sda, sector 4096 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0
|
||||
|
||||
Fix this by removing the ATA_DRDY entry from the stat_table array so
|
||||
that we default to always returning ABORTED COMMAND without any
|
||||
additional sense code, since we do not know any better. The entry 0x08
|
||||
(ATA_DRQ) is also removed since signaling ABORTED COMMAND with a parity
|
||||
error is also misleading (as a parity error would likely be signaled
|
||||
through a bus error). So for this case, also default to returning
|
||||
ABORTED COMMAND without any additional sense code. With this, the
|
||||
previous example error case becomes:
|
||||
|
||||
sd 0:0:0:0: [sda] tag#17 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s
|
||||
sd 0:0:0:0: [sda] tag#17 Sense Key : Aborted Command [current]
|
||||
sd 0:0:0:0: [sda] tag#17 Add. Sense: No additional sense information
|
||||
sd 0:0:0:0: [sda] tag#17 CDB: Read(10) 28 00 00 00 10 00 00 00 08 00
|
||||
I/O error, dev sda, sector 4096 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0
|
||||
|
||||
Together with these fixes, refactor stat_table to make it more readable
|
||||
by putting the entries comments in front of the entries and using the
|
||||
defined status bits macros instead of hardcoded values.
|
||||
|
||||
Reported-by: Lorenz Brun <lorenz@brun.one>
|
||||
Reported-by: Brandon Schwartz <Brandon.Schwartz@wdc.com>
|
||||
Fixes: 8ae720449fca ("libata: whitespace fixes in ata_to_sense_error()")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
|
||||
Reviewed-by: Hannes Reinecke <hare@suse.de>
|
||||
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
|
||||
---
|
||||
drivers/ata/libata-scsi.c | 20 ++++++++------------
|
||||
1 file changed, 8 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/ata/libata-scsi.c
|
||||
+++ b/drivers/ata/libata-scsi.c
|
||||
@@ -859,18 +859,14 @@ static void ata_to_sense_error(u8 drv_st
|
||||
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
|
||||
};
|
||||
static const unsigned char stat_table[][4] = {
|
||||
- /* Must be first because BUSY means no other bits valid */
|
||||
- {0x80, ABORTED_COMMAND, 0x47, 0x00},
|
||||
- // Busy, fake parity for now
|
||||
- {0x40, ILLEGAL_REQUEST, 0x21, 0x04},
|
||||
- // Device ready, unaligned write command
|
||||
- {0x20, HARDWARE_ERROR, 0x44, 0x00},
|
||||
- // Device fault, internal target failure
|
||||
- {0x08, ABORTED_COMMAND, 0x47, 0x00},
|
||||
- // Timed out in xfer, fake parity for now
|
||||
- {0x04, RECOVERED_ERROR, 0x11, 0x00},
|
||||
- // Recovered ECC error Medium error, recovered
|
||||
- {0xFF, 0xFF, 0xFF, 0xFF}, // END mark
|
||||
+ /* Busy: must be first because BUSY means no other bits valid */
|
||||
+ { ATA_BUSY, ABORTED_COMMAND, 0x00, 0x00 },
|
||||
+ /* Device fault: INTERNAL TARGET FAILURE */
|
||||
+ { ATA_DF, HARDWARE_ERROR, 0x44, 0x00 },
|
||||
+ /* Corrected data error */
|
||||
+ { ATA_CORR, RECOVERED_ERROR, 0x00, 0x00 },
|
||||
+
|
||||
+ { 0xFF, 0xFF, 0xFF, 0xFF }, /* END mark */
|
||||
};
|
||||
|
||||
/*
|
@@ -1,69 +0,0 @@
|
||||
From 222f2d776f617895a876ccd7047cbebc82175f38 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Le Moal <dlemoal@kernel.org>
|
||||
Date: Tue, 29 Jul 2025 19:37:12 +0900
|
||||
Subject: ata: libata-scsi: Return aborted command when missing sense and
|
||||
result TF
|
||||
|
||||
ata_gen_ata_sense() is always called for a failed qc missing sense data
|
||||
so that a sense key, code and code qualifier can be generated using
|
||||
ata_to_sense_error() from the qc status and error fields of its result
|
||||
task file. However, if the qc does not have its result task file filled,
|
||||
ata_gen_ata_sense() returns early without setting a sense key.
|
||||
|
||||
Improve this by defaulting to returning ABORTED COMMAND without any
|
||||
additional sense code, since we do not know the reason for the failure.
|
||||
The same fix is also applied in ata_gen_passthru_sense() with the
|
||||
additional check that the qc failed (qc->err_mask is set).
|
||||
|
||||
Fixes: 816be86c7993 ("ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
|
||||
Reviewed-by: Hannes Reinecke <hare@suse.de>
|
||||
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
|
||||
---
|
||||
drivers/ata/libata-scsi.c | 18 +++++++++++-------
|
||||
1 file changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/ata/libata-scsi.c
|
||||
+++ b/drivers/ata/libata-scsi.c
|
||||
@@ -938,6 +938,8 @@ static void ata_gen_passthru_sense(struc
|
||||
if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
|
||||
ata_dev_dbg(dev,
|
||||
"missing result TF: can't generate ATA PT sense data\n");
|
||||
+ if (qc->err_mask)
|
||||
+ ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -992,8 +994,8 @@ static void ata_gen_ata_sense(struct ata
|
||||
|
||||
if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
|
||||
ata_dev_dbg(dev,
|
||||
- "missing result TF: can't generate sense data\n");
|
||||
- return;
|
||||
+ "Missing result TF: reporting aborted command\n");
|
||||
+ goto aborted;
|
||||
}
|
||||
|
||||
/* Use ata_to_sense_error() to map status register bits
|
||||
@@ -1004,13 +1006,15 @@ static void ata_gen_ata_sense(struct ata
|
||||
ata_to_sense_error(tf->status, tf->error,
|
||||
&sense_key, &asc, &ascq);
|
||||
ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq);
|
||||
- } else {
|
||||
- /* Could not decode error */
|
||||
- ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n",
|
||||
- tf->status, qc->err_mask);
|
||||
- ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ /* Could not decode error */
|
||||
+ ata_dev_warn(dev,
|
||||
+ "Could not decode error 0x%x, status 0x%x (err_mask=0x%x)\n",
|
||||
+ tf->error, tf->status, qc->err_mask);
|
||||
+aborted:
|
||||
+ ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
|
||||
}
|
||||
|
||||
void ata_scsi_sdev_config(struct scsi_device *sdev)
|
@@ -1,48 +0,0 @@
|
||||
From 1696616a3e6e9d5eef2c39723ddaafb78a9a6eeb Mon Sep 17 00:00:00 2001
|
||||
From: Will Deacon <will@kernel.org>
|
||||
Date: Thu, 17 Jul 2025 10:01:08 +0100
|
||||
Subject: vhost/vsock: Avoid allocating arbitrarily-sized SKBs
|
||||
|
||||
vhost_vsock_alloc_skb() returns NULL for packets advertising a length
|
||||
larger than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE in the packet header. However,
|
||||
this is only checked once the SKB has been allocated and, if the length
|
||||
in the packet header is zero, the SKB may not be freed immediately.
|
||||
|
||||
Hoist the size check before the SKB allocation so that an iovec larger
|
||||
than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + the header size is rejected
|
||||
outright. The subsequent check on the length field in the header can
|
||||
then simply check that the allocated SKB is indeed large enough to hold
|
||||
the packet.
|
||||
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
|
||||
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Message-Id: <20250717090116.11987-2-will@kernel.org>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
drivers/vhost/vsock.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/vhost/vsock.c
|
||||
+++ b/drivers/vhost/vsock.c
|
||||
@@ -344,6 +344,9 @@ vhost_vsock_alloc_skb(struct vhost_virtq
|
||||
|
||||
len = iov_length(vq->iov, out);
|
||||
|
||||
+ if (len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
|
||||
+ return NULL;
|
||||
+
|
||||
/* len contains both payload and hdr */
|
||||
skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
@@ -367,8 +370,7 @@ vhost_vsock_alloc_skb(struct vhost_virtq
|
||||
return skb;
|
||||
|
||||
/* The pkt is too big or the length in the header is invalid */
|
||||
- if (payload_len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE ||
|
||||
- payload_len + sizeof(*hdr) > len) {
|
||||
+ if (payload_len + sizeof(*hdr) > len) {
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
From cfb5ffceff501d3ffe6529706d65a35e6068b638 Mon Sep 17 00:00:00 2001
|
||||
From: Will Deacon <will@kernel.org>
|
||||
Date: Thu, 17 Jul 2025 10:01:09 +0100
|
||||
Subject: vsock/virtio: Validate length in packet header before skb_put()
|
||||
|
||||
When receiving a vsock packet in the guest, only the virtqueue buffer
|
||||
size is validated prior to virtio_vsock_skb_rx_put(). Unfortunately,
|
||||
virtio_vsock_skb_rx_put() uses the length from the packet header as the
|
||||
length argument to skb_put(), potentially resulting in SKB overflow if
|
||||
the host has gone wonky.
|
||||
|
||||
Validate the length as advertised by the packet header before calling
|
||||
virtio_vsock_skb_rx_put().
|
||||
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Message-Id: <20250717090116.11987-3-will@kernel.org>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||
---
|
||||
net/vmw_vsock/virtio_transport.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/net/vmw_vsock/virtio_transport.c
|
||||
+++ b/net/vmw_vsock/virtio_transport.c
|
||||
@@ -624,8 +624,9 @@ static void virtio_transport_rx_work(str
|
||||
do {
|
||||
virtqueue_disable_cb(vq);
|
||||
for (;;) {
|
||||
+ unsigned int len, payload_len;
|
||||
+ struct virtio_vsock_hdr *hdr;
|
||||
struct sk_buff *skb;
|
||||
- unsigned int len;
|
||||
|
||||
if (!virtio_transport_more_replies(vsock)) {
|
||||
/* Stop rx until the device processes already
|
||||
@@ -642,11 +643,18 @@ static void virtio_transport_rx_work(str
|
||||
vsock->rx_buf_nr--;
|
||||
|
||||
/* Drop short/long packets */
|
||||
- if (unlikely(len < sizeof(struct virtio_vsock_hdr) ||
|
||||
+ if (unlikely(len < sizeof(*hdr) ||
|
||||
len > virtio_vsock_skb_len(skb))) {
|
||||
kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ hdr = virtio_vsock_hdr(skb);
|
||||
+ payload_len = le32_to_cpu(hdr->len);
|
||||
+ if (unlikely(payload_len > len - sizeof(*hdr))) {
|
||||
+ kfree_skb(skb);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
virtio_vsock_skb_rx_put(skb);
|
||||
virtio_transport_deliver_tap_pkt(skb);
|
@@ -1,36 +0,0 @@
|
||||
From 49442fb626f151f886cb5a860c972c300307fdff Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas.weissschuh@linutronix.de>
|
||||
Date: Mon, 28 Jul 2025 15:47:37 +0200
|
||||
Subject: kbuild: userprogs: use correct linker when mixing clang and GNU ld
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The userprogs infrastructure does not expect clang being used with GNU ld
|
||||
and in that case uses /usr/bin/ld for linking, not the configured $(LD).
|
||||
This fallback is problematic as it will break when cross-compiling.
|
||||
Mixing clang and GNU ld is used for example when building for SPARC64,
|
||||
as ld.lld is not sufficient; see Documentation/kbuild/llvm.rst.
|
||||
|
||||
Relax the check around --ld-path so it gets used for all linkers.
|
||||
|
||||
Fixes: dfc1b168a8c4 ("kbuild: userprogs: use correct lld when linking through clang")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
|
||||
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1154,7 +1154,7 @@ KBUILD_USERCFLAGS += $(filter -m32 -m64
|
||||
KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
|
||||
|
||||
# userspace programs are linked via the compiler, use the correct linker
|
||||
-ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy)
|
||||
+ifdef CONFIG_CC_IS_CLANG
|
||||
KBUILD_USERLDFLAGS += --ld-path=$(LD)
|
||||
endif
|
||||
|
@@ -1,36 +0,0 @@
|
||||
From 31a1e00a65d88e2f051fb6e9551340cc815d54d4 Mon Sep 17 00:00:00 2001
|
||||
From: Helge Deller <deller@gmx.de>
|
||||
Date: Sat, 2 Aug 2025 21:34:37 +0200
|
||||
Subject: Revert "vgacon: Add check for vc_origin address range in
|
||||
vgacon_scroll()"
|
||||
|
||||
This reverts commit 864f9963ec6b4b76d104d595ba28110b87158003.
|
||||
|
||||
The patch is wrong as it checks vc_origin against vc_screenbuf,
|
||||
while in text mode it should compare against vga_vram_base.
|
||||
|
||||
As such it broke VGA text scrolling, which can be reproduced like this:
|
||||
(1) boot a kernel that is configured to use text mode VGA-console
|
||||
(2) type commands: ls -l /usr/bin | less -S
|
||||
(3) scroll up/down with cursor-down/up keys
|
||||
|
||||
Reported-by: Jari Ruusu <jariruusu@protonmail.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Cc: Yi Yang <yiyang13@huawei.com>
|
||||
Cc: GONG Ruiqi <gongruiqi1@huawei.com>
|
||||
Signed-off-by: Helge Deller <deller@gmx.de>
|
||||
---
|
||||
drivers/video/console/vgacon.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/video/console/vgacon.c
|
||||
+++ b/drivers/video/console/vgacon.c
|
||||
@@ -1168,7 +1168,7 @@ static bool vgacon_scroll(struct vc_data
|
||||
c->vc_screenbuf_size - delta);
|
||||
c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
|
||||
vga_rolled_over = 0;
|
||||
- } else if (oldo - delta >= (unsigned long)c->vc_screenbuf)
|
||||
+ } else
|
||||
c->vc_origin -= delta;
|
||||
c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
|
||||
scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char,
|
@@ -1,28 +0,0 @@
|
||||
From 5c50d7a4d6580d6cc83d1231aa358defe43bc46d Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Thu, 31 Jul 2025 09:41:47 +0800
|
||||
Subject: crypto: hash - Increase HASH_MAX_DESCSIZE for hmac(sha3-224-s390)
|
||||
|
||||
The value of HASH_MAX_DESCSIZE is off by one for hmac(sha3-224-s390).
|
||||
Fix this so that hmac(sha3-224-s390) can be registered.
|
||||
|
||||
Reported-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reported-by: Eric Biggers <ebiggers@kernel.org>
|
||||
Fixes: 6f90ba706551 ("crypto: s390/sha3 - Use API partial block handling")
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
include/crypto/hash.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/include/crypto/hash.h
|
||||
+++ b/include/crypto/hash.h
|
||||
@@ -184,7 +184,7 @@ struct shash_desc {
|
||||
* Worst case is hmac(sha3-224-s390). Its context is a nested 'shash_desc'
|
||||
* containing a 'struct s390_sha_ctx'.
|
||||
*/
|
||||
-#define HASH_MAX_DESCSIZE (sizeof(struct shash_desc) + 360)
|
||||
+#define HASH_MAX_DESCSIZE (sizeof(struct shash_desc) + 361)
|
||||
#define MAX_SYNC_HASH_REQSIZE (sizeof(struct ahash_request) + \
|
||||
HASH_MAX_DESCSIZE)
|
||||
|
@@ -1,45 +0,0 @@
|
||||
From 8c47c2c4bebf98d0624c15cecef00536d50d79a6 Mon Sep 17 00:00:00 2001
|
||||
From: Jann Horn <jannh@google.com>
|
||||
Date: Mon, 28 Jul 2025 22:11:54 +0200
|
||||
Subject: kasan/test: fix protection against compiler elision
|
||||
|
||||
The kunit test is using assignments to
|
||||
"static volatile void *kasan_ptr_result" to prevent elision of memory
|
||||
loads, but that's not working:
|
||||
In this variable definition, the "volatile" applies to the "void", not to
|
||||
the pointer.
|
||||
To make "volatile" apply to the pointer as intended, it must follow
|
||||
after the "*".
|
||||
|
||||
This makes the kasan_memchr test pass again on my system. The
|
||||
kasan_strings test is still failing because all the definitions of
|
||||
load_unaligned_zeropad() are lacking explicit instrumentation hooks and
|
||||
ASAN does not instrument asm() memory operands.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250728-kasan-kunit-fix-volatile-v1-1-e7157c9af82d@google.com
|
||||
Fixes: 5f1c8108e7ad ("mm:kasan: fix sparse warnings: Should it be static?")
|
||||
Signed-off-by: Jann Horn <jannh@google.com>
|
||||
Cc: Alexander Potapenko <glider@google.com>
|
||||
Cc: Andrey Konovalov <andreyknvl@gmail.com>
|
||||
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
|
||||
Cc: Dmitriy Vyukov <dvyukov@google.com>
|
||||
Cc: Jann Horn <jannh@google.com>
|
||||
Cc: Nihar Chaithanya <niharchaithanya@gmail.com>
|
||||
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/kasan/kasan_test_c.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/mm/kasan/kasan_test_c.c
|
||||
+++ b/mm/kasan/kasan_test_c.c
|
||||
@@ -47,7 +47,7 @@ static struct {
|
||||
* Some tests use these global variables to store return values from function
|
||||
* calls that could otherwise be eliminated by the compiler as dead code.
|
||||
*/
|
||||
-static volatile void *kasan_ptr_result;
|
||||
+static void *volatile kasan_ptr_result;
|
||||
static volatile int kasan_int_result;
|
||||
|
||||
/* Probe for console output: obtains test_status lines of interest. */
|
@@ -1,42 +0,0 @@
|
||||
From d22a1695f7b89c228e60a9310d597597a6710666 Mon Sep 17 00:00:00 2001
|
||||
From: Jialin Wang <wjl.linux@gmail.com>
|
||||
Date: Fri, 8 Aug 2025 00:54:55 +0800
|
||||
Subject: proc: proc_maps_open allow proc_mem_open to return NULL
|
||||
|
||||
The commit 65c66047259f ("proc: fix the issue of proc_mem_open returning
|
||||
NULL") caused proc_maps_open() to return -ESRCH when proc_mem_open()
|
||||
returns NULL. This breaks legitimate /proc/<pid>/maps access for kernel
|
||||
threads since kernel threads have NULL mm_struct.
|
||||
|
||||
The regression causes perf to fail and exit when profiling a kernel
|
||||
thread:
|
||||
|
||||
# perf record -v -g -p $(pgrep kswapd0)
|
||||
...
|
||||
couldn't open /proc/65/task/65/maps
|
||||
|
||||
This patch partially reverts the commit to fix it.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250807165455.73656-1-wjl.linux@gmail.com
|
||||
Fixes: 65c66047259f ("proc: fix the issue of proc_mem_open returning NULL")
|
||||
Signed-off-by: Jialin Wang <wjl.linux@gmail.com>
|
||||
Cc: Penglei Jiang <superman.xpt@gmail.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
fs/proc/task_mmu.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/fs/proc/task_mmu.c
|
||||
+++ b/fs/proc/task_mmu.c
|
||||
@@ -215,8 +215,8 @@ static int proc_maps_open(struct inode *
|
||||
|
||||
priv->inode = inode;
|
||||
priv->mm = proc_mem_open(inode, PTRACE_MODE_READ);
|
||||
- if (IS_ERR_OR_NULL(priv->mm)) {
|
||||
- int err = priv->mm ? PTR_ERR(priv->mm) : -ESRCH;
|
||||
+ if (IS_ERR(priv->mm)) {
|
||||
+ int err = PTR_ERR(priv->mm);
|
||||
|
||||
seq_release_private(inode, file);
|
||||
return err;
|
@@ -1,56 +0,0 @@
|
||||
From ca0b04683be7bba50703eaec260167ec494d80b8 Mon Sep 17 00:00:00 2001
|
||||
From: Julian Sun <sunjunchao2870@gmail.com>
|
||||
Date: Tue, 12 Aug 2025 23:42:57 +0800
|
||||
Subject: block: restore default wbt enablement
|
||||
|
||||
The commit 245618f8e45f ("block: protect wbt_lat_usec using
|
||||
q->elevator_lock") protected wbt_enable_default() with
|
||||
q->elevator_lock; however, it also placed wbt_enable_default()
|
||||
before blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);, resulting
|
||||
in wbt failing to be enabled.
|
||||
|
||||
Moreover, the protection of wbt_enable_default() by q->elevator_lock
|
||||
was removed in commit 78c271344b6f ("block: move wbt_enable_default()
|
||||
out of queue freezing from sched ->exit()"), so we can directly fix
|
||||
this issue by placing wbt_enable_default() after
|
||||
blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);.
|
||||
|
||||
Additionally, this issue also causes the inability to read the
|
||||
wbt_lat_usec file, and the scenario is as follows:
|
||||
|
||||
root@q:/sys/block/sda/queue# cat wbt_lat_usec
|
||||
cat: wbt_lat_usec: Invalid argument
|
||||
|
||||
root@q:/data00/sjc/linux# ls /sys/kernel/debug/block/sda/rqos
|
||||
cannot access '/sys/kernel/debug/block/sda/rqos': No such file or directory
|
||||
|
||||
root@q:/data00/sjc/linux# find /sys -name wbt
|
||||
/sys/kernel/debug/tracing/events/wbt
|
||||
|
||||
After testing with this patch, wbt can be enabled normally.
|
||||
|
||||
Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 245618f8e45f ("block: protect wbt_lat_usec using q->elevator_lock")
|
||||
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
|
||||
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
|
||||
Reviewed-by: Ming Lei <ming.lei@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20250812154257.57540-1-sunjunchao@bytedance.com
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
---
|
||||
block/blk-sysfs.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/block/blk-sysfs.c
|
||||
+++ b/block/blk-sysfs.c
|
||||
@@ -876,9 +876,9 @@ int blk_register_queue(struct gendisk *d
|
||||
|
||||
if (queue_is_mq(q))
|
||||
elevator_set_default(q);
|
||||
- wbt_enable_default(disk);
|
||||
|
||||
blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
|
||||
+ wbt_enable_default(disk);
|
||||
|
||||
/* Now everything is ready and send out KOBJ_ADD uevent */
|
||||
kobject_uevent(&disk->queue_kobj, KOBJ_ADD);
|
@@ -1,50 +0,0 @@
|
||||
From 599815c47256ca7901fc5b0de5cbc6f08e803e48 Mon Sep 17 00:00:00 2001
|
||||
From: Christoph Hellwig <hch@lst.de>
|
||||
Date: Wed, 23 Jul 2025 14:19:44 +0200
|
||||
Subject: xfs: fully decouple XFS_IBULK* flags from XFS_IWALK* flags
|
||||
|
||||
Fix up xfs_inumbers to now pass in the XFS_IBULK* flags into the flags
|
||||
argument to xfs_inobt_walk, which expects the XFS_IWALK* flags.
|
||||
|
||||
Currently passing the wrong flags works for non-debug builds because
|
||||
the only XFS_IWALK* flag has the same encoding as the corresponding
|
||||
XFS_IBULK* flag, but in debug builds it can trigger an assert that no
|
||||
incorrect flag is passed. Instead just extra the relevant flag.
|
||||
|
||||
Fixes: 5b35d922c52798 ("xfs: Decouple XFS_IBULK flags from XFS_IWALK flags")
|
||||
Cc: <stable@vger.kernel.org> # v5.19
|
||||
Reported-by: cen zhang <zzzccc427@gmail.com>
|
||||
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
---
|
||||
fs/xfs/xfs_itable.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/fs/xfs/xfs_itable.c
|
||||
+++ b/fs/xfs/xfs_itable.c
|
||||
@@ -455,11 +455,15 @@ xfs_inumbers(
|
||||
.breq = breq,
|
||||
};
|
||||
struct xfs_trans *tp;
|
||||
+ unsigned int iwalk_flags = 0;
|
||||
int error = 0;
|
||||
|
||||
if (xfs_bulkstat_already_done(breq->mp, breq->startino))
|
||||
return 0;
|
||||
|
||||
+ if (breq->flags & XFS_IBULK_SAME_AG)
|
||||
+ iwalk_flags |= XFS_IWALK_SAME_AG;
|
||||
+
|
||||
/*
|
||||
* Grab an empty transaction so that we can use its recursive buffer
|
||||
* locking abilities to detect cycles in the inobt without deadlocking.
|
||||
@@ -468,7 +472,7 @@ xfs_inumbers(
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
- error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->flags,
|
||||
+ error = xfs_inobt_walk(breq->mp, tp, breq->startino, iwalk_flags,
|
||||
xfs_inumbers_walk, breq->icount, &ic);
|
||||
xfs_trans_cancel(tp);
|
||||
out:
|
@@ -1,62 +0,0 @@
|
||||
From 76511b0ae1da7f401fe06c8b4dd18a40c3a2b52b Mon Sep 17 00:00:00 2001
|
||||
From: JP Kobryn <inwardvessel@gmail.com>
|
||||
Date: Wed, 6 Aug 2025 17:33:50 -0700
|
||||
Subject: cgroup: avoid null de-ref in css_rstat_exit()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
css_rstat_exit() may be called asynchronously in scenarios where preceding
|
||||
calls to css_rstat_init() have not completed. One such example is this
|
||||
sequence below:
|
||||
|
||||
css_create(...)
|
||||
{
|
||||
...
|
||||
init_and_link_css(css, ...);
|
||||
|
||||
err = percpu_ref_init(...);
|
||||
if (err)
|
||||
goto err_free_css;
|
||||
err = cgroup_idr_alloc(...);
|
||||
if (err)
|
||||
goto err_free_css;
|
||||
err = css_rstat_init(css, ...);
|
||||
if (err)
|
||||
goto err_free_css;
|
||||
...
|
||||
err_free_css:
|
||||
INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn);
|
||||
queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
If any of the three goto jumps are taken, async cleanup will begin and
|
||||
css_rstat_exit() will be invoked on an uninitialized css->rstat_cpu.
|
||||
|
||||
Avoid accessing the unitialized field by returning early in
|
||||
css_rstat_exit() if this is the case.
|
||||
|
||||
Signed-off-by: JP Kobryn <inwardvessel@gmail.com>
|
||||
Suggested-by: Michal Koutný <mkoutny@suse.com>
|
||||
Fixes: 5da3bfa029d68 ("cgroup: use separate rstat trees for each subsystem")
|
||||
Cc: stable@vger.kernel.org # v6.16
|
||||
Reported-by: syzbot+8d052e8b99e40bc625ed@syzkaller.appspotmail.com
|
||||
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
---
|
||||
kernel/cgroup/rstat.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/kernel/cgroup/rstat.c
|
||||
+++ b/kernel/cgroup/rstat.c
|
||||
@@ -488,6 +488,9 @@ void css_rstat_exit(struct cgroup_subsys
|
||||
if (!css_uses_rstat(css))
|
||||
return;
|
||||
|
||||
+ if (!css->rstat_cpu)
|
||||
+ return;
|
||||
+
|
||||
css_rstat_flush(css);
|
||||
|
||||
/* sanity check */
|
@@ -1,43 +0,0 @@
|
||||
From 1b24003064570fdf29c55bac14d4728977195133 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <cyphar@cyphar.com>
|
||||
Date: Fri, 8 Aug 2025 03:55:05 +1000
|
||||
Subject: open_tree_attr: do not allow id-mapping changes without
|
||||
OPEN_TREE_CLONE
|
||||
|
||||
As described in commit 7a54947e727b ('Merge patch series "fs: allow
|
||||
changing idmappings"'), open_tree_attr(2) was necessary in order to
|
||||
allow for a detached mount to be created and have its idmappings changed
|
||||
without the risk of any racing threads operating on it. For this reason,
|
||||
mount_setattr(2) still does not allow for id-mappings to be changed.
|
||||
|
||||
However, there was a bug in commit 2462651ffa76 ("fs: allow changing
|
||||
idmappings") which allowed users to bypass this restriction by calling
|
||||
open_tree_attr(2) *without* OPEN_TREE_CLONE.
|
||||
|
||||
can_idmap_mount() prevented this bug from allowing an attached
|
||||
mountpoint's id-mapping from being modified (thanks to an is_anon_ns()
|
||||
check), but this still allows for detached (but visible) mounts to have
|
||||
their be id-mapping changed. This risks the same UAF and locking issues
|
||||
as described in the merge commit, and was likely unintentional.
|
||||
|
||||
Fixes: 2462651ffa76 ("fs: allow changing idmappings")
|
||||
Cc: stable@vger.kernel.org # v6.15+
|
||||
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
|
||||
Link: https://lore.kernel.org/20250808-open_tree_attr-bugfix-idmap-v1-1-0ec7bc05646c@cyphar.com
|
||||
Signed-off-by: Christian Brauner <brauner@kernel.org>
|
||||
---
|
||||
fs/namespace.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -5302,7 +5302,8 @@ SYSCALL_DEFINE5(open_tree_attr, int, dfd
|
||||
int ret;
|
||||
struct mount_kattr kattr = {};
|
||||
|
||||
- kattr.kflags = MOUNT_KATTR_IDMAP_REPLACE;
|
||||
+ if (flags & OPEN_TREE_CLONE)
|
||||
+ kattr.kflags = MOUNT_KATTR_IDMAP_REPLACE;
|
||||
if (flags & AT_RECURSIVE)
|
||||
kattr.kflags |= MOUNT_KATTR_RECURSE;
|
||||
|
@@ -1,53 +0,0 @@
|
||||
From 2435722a492f57a060202726a820b0da64f42105 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Wed, 30 Jul 2025 12:28:41 +0200
|
||||
Subject: iomap: Fix broken data integrity guarantees for O_SYNC writes
|
||||
|
||||
Commit d279c80e0bac ("iomap: inline iomap_dio_bio_opflags()") has broken
|
||||
the logic in iomap_dio_bio_iter() in a way that when the device does
|
||||
support FUA (or has no writeback cache) and the direct IO happens to
|
||||
freshly allocated or unwritten extents, we will *not* issue fsync after
|
||||
completing direct IO O_SYNC / O_DSYNC write because the
|
||||
IOMAP_DIO_WRITE_THROUGH flag stays mistakenly set. Fix the problem by
|
||||
clearing IOMAP_DIO_WRITE_THROUGH whenever we do not perform FUA write as
|
||||
it was originally intended.
|
||||
|
||||
CC: John Garry <john.g.garry@oracle.com>
|
||||
CC: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
|
||||
Fixes: d279c80e0bac ("iomap: inline iomap_dio_bio_opflags()")
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Link: https://lore.kernel.org/20250730102840.20470-2-jack@suse.cz
|
||||
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
|
||||
Reviewed-by: John Garry <john.g.garry@oracle.com>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Christian Brauner <brauner@kernel.org>
|
||||
---
|
||||
fs/iomap/direct-io.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/fs/iomap/direct-io.c
|
||||
+++ b/fs/iomap/direct-io.c
|
||||
@@ -368,14 +368,14 @@ static int iomap_dio_bio_iter(struct iom
|
||||
if (iomap->flags & IOMAP_F_SHARED)
|
||||
dio->flags |= IOMAP_DIO_COW;
|
||||
|
||||
- if (iomap->flags & IOMAP_F_NEW) {
|
||||
+ if (iomap->flags & IOMAP_F_NEW)
|
||||
need_zeroout = true;
|
||||
- } else if (iomap->type == IOMAP_MAPPED) {
|
||||
- if (iomap_dio_can_use_fua(iomap, dio))
|
||||
- bio_opf |= REQ_FUA;
|
||||
- else
|
||||
- dio->flags &= ~IOMAP_DIO_WRITE_THROUGH;
|
||||
- }
|
||||
+ else if (iomap->type == IOMAP_MAPPED &&
|
||||
+ iomap_dio_can_use_fua(iomap, dio))
|
||||
+ bio_opf |= REQ_FUA;
|
||||
+
|
||||
+ if (!(bio_opf & REQ_FUA))
|
||||
+ dio->flags &= ~IOMAP_DIO_WRITE_THROUGH;
|
||||
|
||||
/*
|
||||
* We can only do deferred completion for pure overwrites that
|
@@ -1,60 +0,0 @@
|
||||
From 77f4f1ca7b68d33c3841e740ae6b03378a77d281 Mon Sep 17 00:00:00 2001
|
||||
From: Andrea Righi <arighi@nvidia.com>
|
||||
Date: Tue, 5 Aug 2025 10:59:11 +0200
|
||||
Subject: sched/ext: Fix invalid task state transitions on class switch
|
||||
|
||||
When enabling a sched_ext scheduler, we may trigger invalid task state
|
||||
transitions, resulting in warnings like the following (which can be
|
||||
easily reproduced by running the hotplug selftest in a loop):
|
||||
|
||||
sched_ext: Invalid task state transition 0 -> 3 for fish[770]
|
||||
WARNING: CPU: 18 PID: 787 at kernel/sched/ext.c:3862 scx_set_task_state+0x7c/0xc0
|
||||
...
|
||||
RIP: 0010:scx_set_task_state+0x7c/0xc0
|
||||
...
|
||||
Call Trace:
|
||||
<TASK>
|
||||
scx_enable_task+0x11f/0x2e0
|
||||
switching_to_scx+0x24/0x110
|
||||
scx_enable.isra.0+0xd14/0x13d0
|
||||
bpf_struct_ops_link_create+0x136/0x1a0
|
||||
__sys_bpf+0x1edd/0x2c30
|
||||
__x64_sys_bpf+0x21/0x30
|
||||
do_syscall_64+0xbb/0x370
|
||||
entry_SYSCALL_64_after_hwframe+0x77/0x7f
|
||||
|
||||
This happens because we skip initialization for tasks that are already
|
||||
dead (with their usage counter set to zero), but we don't exclude them
|
||||
during the scheduling class transition phase.
|
||||
|
||||
Fix this by also skipping dead tasks during class swiching, preventing
|
||||
invalid task state transitions.
|
||||
|
||||
Fixes: a8532fac7b5d2 ("sched_ext: TASK_DEAD tasks must be switched into SCX on ops_enable")
|
||||
Cc: stable@vger.kernel.org # v6.12+
|
||||
Signed-off-by: Andrea Righi <arighi@nvidia.com>
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
---
|
||||
kernel/sched/ext.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/kernel/sched/ext.c
|
||||
+++ b/kernel/sched/ext.c
|
||||
@@ -5694,6 +5694,9 @@ static int scx_enable(struct sched_ext_o
|
||||
__setscheduler_class(p->policy, p->prio);
|
||||
struct sched_enq_and_set_ctx ctx;
|
||||
|
||||
+ if (!tryget_task_struct(p))
|
||||
+ continue;
|
||||
+
|
||||
if (old_class != new_class && p->se.sched_delayed)
|
||||
dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED);
|
||||
|
||||
@@ -5706,6 +5709,7 @@ static int scx_enable(struct sched_ext_o
|
||||
sched_enq_and_set_task(&ctx);
|
||||
|
||||
check_class_changed(task_rq(p), p, old_class, p->prio);
|
||||
+ put_task_struct(p);
|
||||
}
|
||||
scx_task_iter_stop(&sti);
|
||||
percpu_up_write(&scx_fork_rwsem);
|
@@ -1,39 +0,0 @@
|
||||
From f64fb7c5338fde361fdaef01b98697a52ee8467b Mon Sep 17 00:00:00 2001
|
||||
From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
Date: Sun, 27 Jul 2025 14:05:13 -0700
|
||||
Subject: platform/x86/intel-uncore-freq: Check write blocked for ELC
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add the missing write_blocked check for updating sysfs related to uncore
|
||||
efficiency latency control (ELC). If write operation is blocked return
|
||||
error.
|
||||
|
||||
Fixes: bb516dc79c4a ("platform/x86/intel-uncore-freq: Add support for efficiency latency control")
|
||||
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Link: https://lore.kernel.org/r/20250727210513.2898630-1-srinivas.pandruvada@linux.intel.com
|
||||
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
---
|
||||
.../x86/intel/uncore-frequency/uncore-frequency-tpmi.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
|
||||
+++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
|
||||
@@ -191,9 +191,14 @@ static int uncore_read_control_freq(stru
|
||||
static int write_eff_lat_ctrl(struct uncore_data *data, unsigned int val, enum uncore_index index)
|
||||
{
|
||||
struct tpmi_uncore_cluster_info *cluster_info;
|
||||
+ struct tpmi_uncore_struct *uncore_root;
|
||||
u64 control;
|
||||
|
||||
cluster_info = container_of(data, struct tpmi_uncore_cluster_info, uncore_data);
|
||||
+ uncore_root = cluster_info->uncore_root;
|
||||
+
|
||||
+ if (uncore_root->write_blocked)
|
||||
+ return -EPERM;
|
||||
|
||||
if (cluster_info->root_domain)
|
||||
return -ENODATA;
|
@@ -1,28 +0,0 @@
|
||||
From 882ab07bcf8574b1618863b6cd16200979cec30f Mon Sep 17 00:00:00 2001
|
||||
From: Miao Li <limiao@kylinos.cn>
|
||||
Date: Fri, 1 Aug 2025 16:27:28 +0800
|
||||
Subject: usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash
|
||||
Drive
|
||||
|
||||
Another SanDisk 3.2Gen1 Flash Drive also need DELAY_INIT quick,
|
||||
or it will randomly work incorrectly on Huawei hisi platforms
|
||||
when doing reboot test.
|
||||
|
||||
Signed-off-by: Miao Li <limiao@kylinos.cn>
|
||||
Cc: stable <stable@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250801082728.469406-1-limiao870622@163.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/core/quirks.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/usb/core/quirks.c
|
||||
+++ b/drivers/usb/core/quirks.c
|
||||
@@ -371,6 +371,7 @@ static const struct usb_device_id usb_qu
|
||||
{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* SanDisk Corp. SanDisk 3.2Gen1 */
|
||||
+ { USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
{ USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* SanDisk Extreme 55AE */
|
@@ -1,68 +0,0 @@
|
||||
From 024303e34931cae365cfeb28d00e3b9b704c1001 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
||||
Date: Sun, 3 Aug 2025 00:55:20 +0200
|
||||
Subject: usb: renesas-xhci: Fix External ROM access timeouts
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Increase the External ROM access timeouts to prevent failures during
|
||||
programming of External SPI EEPROM chips. The current timeouts are
|
||||
too short for some SPI EEPROMs used with uPD720201 controllers.
|
||||
|
||||
The current timeout for Chip Erase in renesas_rom_erase() is 100 ms ,
|
||||
the current timeout for Sector Erase issued by the controller before
|
||||
Page Program in renesas_fw_download_image() is also 100 ms. Neither
|
||||
timeout is sufficient for e.g. the Macronix MX25L5121E or MX25V5126F.
|
||||
|
||||
MX25L5121E reference manual [1] page 35 section "ERASE AND PROGRAMMING
|
||||
PERFORMANCE" and page 23 section "Table 8. AC CHARACTERISTICS (Temperature
|
||||
= 0°C to 70°C for Commercial grade, VCC = 2.7V ~ 3.6V)" row "tCE" indicate
|
||||
that the maximum time required for Chip Erase opcode to complete is 2 s,
|
||||
and for Sector Erase it is 300 ms .
|
||||
|
||||
MX25V5126F reference manual [2] page 47 section "13. ERASE AND PROGRAMMING
|
||||
PERFORMANCE (2.3V - 3.6V)" and page 42 section "Table 8. AC CHARACTERISTICS
|
||||
(Temperature = -40°C to 85°C for Industrial grade, VCC = 2.3V - 3.6V)" row
|
||||
"tCE" indicate that the maximum time required for Chip Erase opcode to
|
||||
complete is 3.2 s, and for Sector Erase it is 400 ms .
|
||||
|
||||
Update the timeouts such, that Chip Erase timeout is set to 5 seconds,
|
||||
and Sector Erase timeout is set to 500 ms. Such lengthy timeouts ought
|
||||
to be sufficient for majority of SPI EEPROM chips.
|
||||
|
||||
[1] https://www.macronix.com/Lists/Datasheet/Attachments/8634/MX25L5121E,%203V,%20512Kb,%20v1.3.pdf
|
||||
[2] https://www.macronix.com/Lists/Datasheet/Attachments/8750/MX25V5126F,%202.5V,%20512Kb,%20v1.1.pdf
|
||||
|
||||
Fixes: 2478be82de44 ("usb: renesas-xhci: Add ROM loader for uPD720201")
|
||||
Cc: stable <stable@kernel.org>
|
||||
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
||||
Link: https://lore.kernel.org/r/20250802225526.25431-1-marek.vasut+renesas@mailbox.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/xhci-pci-renesas.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/xhci-pci-renesas.c
|
||||
+++ b/drivers/usb/host/xhci-pci-renesas.c
|
||||
@@ -47,8 +47,9 @@
|
||||
#define RENESAS_ROM_ERASE_MAGIC 0x5A65726F
|
||||
#define RENESAS_ROM_WRITE_MAGIC 0x53524F4D
|
||||
|
||||
-#define RENESAS_RETRY 10000
|
||||
-#define RENESAS_DELAY 10
|
||||
+#define RENESAS_RETRY 50000 /* 50000 * RENESAS_DELAY ~= 500ms */
|
||||
+#define RENESAS_CHIP_ERASE_RETRY 500000 /* 500000 * RENESAS_DELAY ~= 5s */
|
||||
+#define RENESAS_DELAY 10
|
||||
|
||||
#define RENESAS_FW_NAME "renesas_usb_fw.mem"
|
||||
|
||||
@@ -407,7 +408,7 @@ static void renesas_rom_erase(struct pci
|
||||
/* sleep a bit while ROM is erased */
|
||||
msleep(20);
|
||||
|
||||
- for (i = 0; i < RENESAS_RETRY; i++) {
|
||||
+ for (i = 0; i < RENESAS_CHIP_ERASE_RETRY; i++) {
|
||||
retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS,
|
||||
&status);
|
||||
status &= RENESAS_ROM_STATUS_ERASE;
|
@@ -1,55 +0,0 @@
|
||||
From ed08be11433715381e5a67569d2eadd9264523e0 Mon Sep 17 00:00:00 2001
|
||||
From: Xu Yang <xu.yang_2@nxp.com>
|
||||
Date: Wed, 6 Aug 2025 16:39:55 +0800
|
||||
Subject: usb: core: hcd: fix accessing unmapped memory in
|
||||
SINGLE_STEP_SET_FEATURE test
|
||||
|
||||
The USB core will unmap urb->transfer_dma after SETUP stage completes.
|
||||
Then the USB controller will access unmapped memory when it received
|
||||
device descriptor. If iommu is equipped, the entire test can't be
|
||||
completed due to the memory accessing is blocked.
|
||||
|
||||
Fix it by calling map_urb_for_dma() again for IN stage. To reduce
|
||||
redundant map for urb->transfer_buffer, this will also set
|
||||
URB_NO_TRANSFER_DMA_MAP flag before first map_urb_for_dma() to skip
|
||||
dma map for urb->transfer_buffer and clear URB_NO_TRANSFER_DMA_MAP
|
||||
flag before second map_urb_for_dma().
|
||||
|
||||
Fixes: 216e0e563d81 ("usb: core: hcd: use map_urb_for_dma for single step set feature urb")
|
||||
Cc: stable <stable@kernel.org>
|
||||
Reviewed-by: Jun Li <jun.li@nxp.com>
|
||||
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Link: https://lore.kernel.org/r/20250806083955.3325299-1-xu.yang_2@nxp.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/core/hcd.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/core/hcd.c
|
||||
+++ b/drivers/usb/core/hcd.c
|
||||
@@ -2153,7 +2153,7 @@ static struct urb *request_single_step_s
|
||||
urb->complete = usb_ehset_completion;
|
||||
urb->status = -EINPROGRESS;
|
||||
urb->actual_length = 0;
|
||||
- urb->transfer_flags = URB_DIR_IN;
|
||||
+ urb->transfer_flags = URB_DIR_IN | URB_NO_TRANSFER_DMA_MAP;
|
||||
usb_get_urb(urb);
|
||||
atomic_inc(&urb->use_count);
|
||||
atomic_inc(&urb->dev->urbnum);
|
||||
@@ -2217,9 +2217,15 @@ int ehset_single_step_set_feature(struct
|
||||
|
||||
/* Complete remaining DATA and STATUS stages using the same URB */
|
||||
urb->status = -EINPROGRESS;
|
||||
+ urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;
|
||||
usb_get_urb(urb);
|
||||
atomic_inc(&urb->use_count);
|
||||
atomic_inc(&urb->dev->urbnum);
|
||||
+ if (map_urb_for_dma(hcd, urb, GFP_KERNEL)) {
|
||||
+ usb_put_urb(urb);
|
||||
+ goto out1;
|
||||
+ }
|
||||
+
|
||||
retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
|
||||
if (!retval && !wait_for_completion_timeout(&done,
|
||||
msecs_to_jiffies(2000))) {
|
@@ -1,51 +0,0 @@
|
||||
From 10e48c1c6c772eb9c6754dd2340843fe264f71f8 Mon Sep 17 00:00:00 2001
|
||||
From: Mael GUERIN <mael.guerin@murena.io>
|
||||
Date: Wed, 6 Aug 2025 18:44:03 +0200
|
||||
Subject: USB: storage: Add unusual-devs entry for Novatek NTK96550-based
|
||||
camera
|
||||
|
||||
Add the US_FL_BULK_IGNORE_TAG quirk for Novatek NTK96550-based camera
|
||||
to fix USB resets after sending SCSI vendor commands due to CBW and
|
||||
CSW tags difference, leading to undesired slowness while communicating
|
||||
with the device.
|
||||
|
||||
Please find below the copy of /sys/kernel/debug/usb/devices with my
|
||||
device plugged in (listed as TechSys USB mass storage here, the
|
||||
underlying chipset being the Novatek NTK96550-based camera):
|
||||
|
||||
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0
|
||||
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=0603 ProdID=8611 Rev= 0.01
|
||||
S: Manufacturer=TechSys
|
||||
S: Product=USB Mass Storage
|
||||
S: SerialNumber=966110000000100
|
||||
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA
|
||||
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
|
||||
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
|
||||
Signed-off-by: Mael GUERIN <mael.guerin@murena.io>
|
||||
Cc: stable <stable@kernel.org>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Link: https://lore.kernel.org/r/20250806164406.43450-1-mael.guerin@murena.io
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/storage/unusual_devs.h | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/usb/storage/unusual_devs.h
|
||||
+++ b/drivers/usb/storage/unusual_devs.h
|
||||
@@ -934,6 +934,13 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_SANE_SENSE ),
|
||||
|
||||
+/* Added by Maël GUERIN <mael.guerin@murena.io> */
|
||||
+UNUSUAL_DEV( 0x0603, 0x8611, 0x0000, 0xffff,
|
||||
+ "Novatek",
|
||||
+ "NTK96550-based camera",
|
||||
+ USB_SC_SCSI, USB_PR_BULK, NULL,
|
||||
+ US_FL_BULK_IGNORE_TAG ),
|
||||
+
|
||||
/*
|
||||
* Reported by Hanno Boeck <hanno@gmx.de>
|
||||
* Taken from the Lycoris Kernel
|
@@ -1,42 +0,0 @@
|
||||
From c6c200e7836ff1b131442200096a8fd14c600165 Mon Sep 17 00:00:00 2001
|
||||
From: Kuen-Han Tsai <khtsai@google.com>
|
||||
Date: Thu, 7 Aug 2025 17:06:55 +0800
|
||||
Subject: usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
|
||||
|
||||
During a device-initiated disconnect, the End Transfer command resets
|
||||
the event filter, allowing a new xferNotReady event to be generated
|
||||
before the controller is fully halted. Processing this late event
|
||||
incorrectly triggers a Start Transfer, which prevents the controller
|
||||
from halting and results in a DSTS.DEVCTLHLT bit polling timeout.
|
||||
|
||||
Ignore the late xferNotReady event if the controller is already in a
|
||||
disconnected state.
|
||||
|
||||
Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
|
||||
Cc: stable <stable@kernel.org>
|
||||
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
|
||||
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
|
||||
Link: https://lore.kernel.org/r/20250807090700.2397190-1-khtsai@google.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/dwc3/gadget.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/usb/dwc3/gadget.c
|
||||
+++ b/drivers/usb/dwc3/gadget.c
|
||||
@@ -3779,6 +3779,15 @@ static void dwc3_gadget_endpoint_transfe
|
||||
static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
|
||||
const struct dwc3_event_depevt *event)
|
||||
{
|
||||
+ /*
|
||||
+ * During a device-initiated disconnect, a late xferNotReady event can
|
||||
+ * be generated after the End Transfer command resets the event filter,
|
||||
+ * but before the controller is halted. Ignore it to prevent a new
|
||||
+ * transfer from starting.
|
||||
+ */
|
||||
+ if (!dep->dwc->connected)
|
||||
+ return;
|
||||
+
|
||||
dwc3_gadget_endpoint_frame_from_event(dep, event);
|
||||
|
||||
/*
|
@@ -1,34 +0,0 @@
|
||||
From 50d8ed950819f18b60b2eaa7121e16cfb2dd16eb Mon Sep 17 00:00:00 2001
|
||||
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
|
||||
Date: Tue, 12 Aug 2025 16:11:00 +0300
|
||||
Subject: usb: dwc3: pci: add support for the Intel Wildcat Lake
|
||||
|
||||
This patch adds the necessary PCI ID for Intel Wildcat Lake
|
||||
devices.
|
||||
|
||||
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
|
||||
Cc: stable <stable@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250812131101.2930199-1-heikki.krogerus@linux.intel.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/dwc3/dwc3-pci.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/usb/dwc3/dwc3-pci.c
|
||||
+++ b/drivers/usb/dwc3/dwc3-pci.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_TGPLP 0xa0ee
|
||||
#define PCI_DEVICE_ID_INTEL_TGPH 0x43ee
|
||||
#define PCI_DEVICE_ID_INTEL_JSP 0x4dee
|
||||
+#define PCI_DEVICE_ID_INTEL_WCL 0x4d7e
|
||||
#define PCI_DEVICE_ID_INTEL_ADL 0x460e
|
||||
#define PCI_DEVICE_ID_INTEL_ADL_PCH 0x51ee
|
||||
#define PCI_DEVICE_ID_INTEL_ADLN 0x465e
|
||||
@@ -431,6 +432,7 @@ static const struct pci_device_id dwc3_p
|
||||
{ PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) },
|
||||
{ PCI_DEVICE_DATA(INTEL, TGPH, &dwc3_pci_intel_swnode) },
|
||||
{ PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) },
|
||||
+ { PCI_DEVICE_DATA(INTEL, WCL, &dwc3_pci_intel_swnode) },
|
||||
{ PCI_DEVICE_DATA(INTEL, ADL, &dwc3_pci_intel_swnode) },
|
||||
{ PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) },
|
||||
{ PCI_DEVICE_DATA(INTEL, ADLN, &dwc3_pci_intel_swnode) },
|
@@ -1,31 +0,0 @@
|
||||
From 3417b55b75b1ca1003f6a621c77b751958727729 Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Date: Wed, 13 Aug 2025 16:52:49 +0200
|
||||
Subject: usb: storage: realtek_cr: Use correct byte order for bcs->Residue
|
||||
|
||||
Since 'bcs->Residue' has the data type '__le32', convert it to the
|
||||
correct byte order of the CPU using this driver when assigning it to
|
||||
the local variable 'residue'.
|
||||
|
||||
Cc: stable <stable@kernel.org>
|
||||
Fixes: 50a6cb932d5c ("USB: usb_storage: add ums-realtek driver")
|
||||
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Link: https://lore.kernel.org/r/20250813145247.184717-3-thorsten.blum@linux.dev
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/storage/realtek_cr.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/storage/realtek_cr.c
|
||||
+++ b/drivers/usb/storage/realtek_cr.c
|
||||
@@ -252,7 +252,7 @@ static int rts51x_bulk_transport(struct
|
||||
return USB_STOR_TRANSPORT_ERROR;
|
||||
}
|
||||
|
||||
- residue = bcs->Residue;
|
||||
+ residue = le32_to_cpu(bcs->Residue);
|
||||
if (bcs->Tag != us->tag)
|
||||
return USB_STOR_TRANSPORT_ERROR;
|
||||
|
@@ -1,57 +0,0 @@
|
||||
From a9cbad46c051cf4467ba13638eddc86f96354c66 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Pylypiv <ipylypiv@google.com>
|
||||
Date: Wed, 13 Aug 2025 19:22:56 -0700
|
||||
Subject: ata: libata-scsi: Fix CDL control
|
||||
|
||||
Delete extra checks for the ATA_DFLAG_CDL_ENABLED flag that prevent
|
||||
SET FEATURES command from being issued to a drive when NCQ commands
|
||||
are active.
|
||||
|
||||
ata_mselect_control_ata_feature() sets / clears the ATA_DFLAG_CDL_ENABLED
|
||||
flag during the translation of MODE SELECT to SET FEATURES. If SET FEATURES
|
||||
gets deferred due to outstanding NCQ commands, the original MODE SELECT
|
||||
command will be re-queued. When the re-queued MODE SELECT goes through
|
||||
the ata_mselect_control_ata_feature() translation again, SET FEATURES
|
||||
will not be issued because ATA_DFLAG_CDL_ENABLED has been already set or
|
||||
cleared by the initial translation of MODE SELECT.
|
||||
|
||||
The ATA_DFLAG_CDL_ENABLED checks in ata_mselect_control_ata_feature()
|
||||
are safe to remove because scsi_cdl_enable() implements a similar logic
|
||||
that avoids enabling CDL if it has been enabled already.
|
||||
|
||||
Fixes: 17e897a45675 ("ata: libata-scsi: Improve CDL control")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Igor Pylypiv <ipylypiv@google.com>
|
||||
Reviewed-by: Niklas Cassel <cassel@kernel.org>
|
||||
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
|
||||
---
|
||||
drivers/ata/libata-scsi.c | 11 +++--------
|
||||
1 file changed, 3 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/ata/libata-scsi.c
|
||||
+++ b/drivers/ata/libata-scsi.c
|
||||
@@ -3905,21 +3905,16 @@ static int ata_mselect_control_ata_featu
|
||||
/* Check cdl_ctrl */
|
||||
switch (buf[0] & 0x03) {
|
||||
case 0:
|
||||
- /* Disable CDL if it is enabled */
|
||||
- if (!(dev->flags & ATA_DFLAG_CDL_ENABLED))
|
||||
- return 0;
|
||||
+ /* Disable CDL */
|
||||
ata_dev_dbg(dev, "Disabling CDL\n");
|
||||
cdl_action = 0;
|
||||
dev->flags &= ~ATA_DFLAG_CDL_ENABLED;
|
||||
break;
|
||||
case 0x02:
|
||||
/*
|
||||
- * Enable CDL if not already enabled. Since this is mutually
|
||||
- * exclusive with NCQ priority, allow this only if NCQ priority
|
||||
- * is disabled.
|
||||
+ * Enable CDL. Since CDL is mutually exclusive with NCQ
|
||||
+ * priority, allow this only if NCQ priority is disabled.
|
||||
*/
|
||||
- if (dev->flags & ATA_DFLAG_CDL_ENABLED)
|
||||
- return 0;
|
||||
if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) {
|
||||
ata_dev_err(dev,
|
||||
"NCQ priority must be disabled to enable CDL\n");
|
@@ -1,158 +0,0 @@
|
||||
From c9cb314a4e57bc486a8b563dd6df5f6975b97a2f Mon Sep 17 00:00:00 2001
|
||||
From: David Howells <dhowells@redhat.com>
|
||||
Date: Thu, 14 Aug 2025 22:45:50 +0100
|
||||
Subject: netfs: Fix unbuffered write error handling
|
||||
|
||||
If all the subrequests in an unbuffered write stream fail, the subrequest
|
||||
collector doesn't update the stream->transferred value and it retains its
|
||||
initial LONG_MAX value. Unfortunately, if all active streams fail, then we
|
||||
take the smallest value of { LONG_MAX, LONG_MAX, ... } as the value to set
|
||||
in wreq->transferred - which is then returned from ->write_iter().
|
||||
|
||||
LONG_MAX was chosen as the initial value so that all the streams can be
|
||||
quickly assessed by taking the smallest value of all stream->transferred -
|
||||
but this only works if we've set any of them.
|
||||
|
||||
Fix this by adding a flag to indicate whether the value in
|
||||
stream->transferred is valid and checking that when we integrate the
|
||||
values. stream->transferred can then be initialised to zero.
|
||||
|
||||
This was found by running the generic/750 xfstest against cifs with
|
||||
cache=none. It splices data to the target file. Once (if) it has used up
|
||||
all the available scratch space, the writes start failing with ENOSPC.
|
||||
This causes ->write_iter() to fail. However, it was returning
|
||||
wreq->transferred, i.e. LONG_MAX, rather than an error (because it thought
|
||||
the amount transferred was non-zero) and iter_file_splice_write() would
|
||||
then try to clean up that amount of pipe bufferage - leading to an oops
|
||||
when it overran. The kernel log showed:
|
||||
|
||||
CIFS: VFS: Send error in write = -28
|
||||
|
||||
followed by:
|
||||
|
||||
BUG: kernel NULL pointer dereference, address: 0000000000000008
|
||||
|
||||
with:
|
||||
|
||||
RIP: 0010:iter_file_splice_write+0x3a4/0x520
|
||||
do_splice+0x197/0x4e0
|
||||
|
||||
or:
|
||||
|
||||
RIP: 0010:pipe_buf_release (include/linux/pipe_fs_i.h:282)
|
||||
iter_file_splice_write (fs/splice.c:755)
|
||||
|
||||
Also put a warning check into splice to announce if ->write_iter() returned
|
||||
that it had written more than it was asked to.
|
||||
|
||||
Fixes: 288ace2f57c9 ("netfs: New writeback implementation")
|
||||
Reported-by: Xiaoli Feng <fengxiaoli0714@gmail.com>
|
||||
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220445
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
Link: https://lore.kernel.org/915443.1755207950@warthog.procyon.org.uk
|
||||
cc: Paulo Alcantara <pc@manguebit.org>
|
||||
cc: Steve French <sfrench@samba.org>
|
||||
cc: Shyam Prasad N <sprasad@microsoft.com>
|
||||
cc: netfs@lists.linux.dev
|
||||
cc: linux-cifs@vger.kernel.org
|
||||
cc: linux-fsdevel@vger.kernel.org
|
||||
cc: stable@vger.kernel.org
|
||||
Signed-off-by: Christian Brauner <brauner@kernel.org>
|
||||
---
|
||||
fs/netfs/read_collect.c | 4 +++-
|
||||
fs/netfs/write_collect.c | 10 ++++++++--
|
||||
fs/netfs/write_issue.c | 4 ++--
|
||||
fs/splice.c | 3 +++
|
||||
include/linux/netfs.h | 1 +
|
||||
5 files changed, 17 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/fs/netfs/read_collect.c
|
||||
+++ b/fs/netfs/read_collect.c
|
||||
@@ -281,8 +281,10 @@ reassess:
|
||||
} else if (test_bit(NETFS_RREQ_SHORT_TRANSFER, &rreq->flags)) {
|
||||
notes |= MADE_PROGRESS;
|
||||
} else {
|
||||
- if (!stream->failed)
|
||||
+ if (!stream->failed) {
|
||||
stream->transferred += transferred;
|
||||
+ stream->transferred_valid = true;
|
||||
+ }
|
||||
if (front->transferred < front->len)
|
||||
set_bit(NETFS_RREQ_SHORT_TRANSFER, &rreq->flags);
|
||||
notes |= MADE_PROGRESS;
|
||||
--- a/fs/netfs/write_collect.c
|
||||
+++ b/fs/netfs/write_collect.c
|
||||
@@ -254,6 +254,7 @@ reassess_streams:
|
||||
if (front->start + front->transferred > stream->collected_to) {
|
||||
stream->collected_to = front->start + front->transferred;
|
||||
stream->transferred = stream->collected_to - wreq->start;
|
||||
+ stream->transferred_valid = true;
|
||||
notes |= MADE_PROGRESS;
|
||||
}
|
||||
if (test_bit(NETFS_SREQ_FAILED, &front->flags)) {
|
||||
@@ -356,6 +357,7 @@ bool netfs_write_collection(struct netfs
|
||||
{
|
||||
struct netfs_inode *ictx = netfs_inode(wreq->inode);
|
||||
size_t transferred;
|
||||
+ bool transferred_valid = false;
|
||||
int s;
|
||||
|
||||
_enter("R=%x", wreq->debug_id);
|
||||
@@ -376,12 +378,16 @@ bool netfs_write_collection(struct netfs
|
||||
continue;
|
||||
if (!list_empty(&stream->subrequests))
|
||||
return false;
|
||||
- if (stream->transferred < transferred)
|
||||
+ if (stream->transferred_valid &&
|
||||
+ stream->transferred < transferred) {
|
||||
transferred = stream->transferred;
|
||||
+ transferred_valid = true;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Okay, declare that all I/O is complete. */
|
||||
- wreq->transferred = transferred;
|
||||
+ if (transferred_valid)
|
||||
+ wreq->transferred = transferred;
|
||||
trace_netfs_rreq(wreq, netfs_rreq_trace_write_done);
|
||||
|
||||
if (wreq->io_streams[1].active &&
|
||||
--- a/fs/netfs/write_issue.c
|
||||
+++ b/fs/netfs/write_issue.c
|
||||
@@ -118,12 +118,12 @@ struct netfs_io_request *netfs_create_wr
|
||||
wreq->io_streams[0].prepare_write = ictx->ops->prepare_write;
|
||||
wreq->io_streams[0].issue_write = ictx->ops->issue_write;
|
||||
wreq->io_streams[0].collected_to = start;
|
||||
- wreq->io_streams[0].transferred = LONG_MAX;
|
||||
+ wreq->io_streams[0].transferred = 0;
|
||||
|
||||
wreq->io_streams[1].stream_nr = 1;
|
||||
wreq->io_streams[1].source = NETFS_WRITE_TO_CACHE;
|
||||
wreq->io_streams[1].collected_to = start;
|
||||
- wreq->io_streams[1].transferred = LONG_MAX;
|
||||
+ wreq->io_streams[1].transferred = 0;
|
||||
if (fscache_resources_valid(&wreq->cache_resources)) {
|
||||
wreq->io_streams[1].avail = true;
|
||||
wreq->io_streams[1].active = true;
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -739,6 +739,9 @@ iter_file_splice_write(struct pipe_inode
|
||||
sd.pos = kiocb.ki_pos;
|
||||
if (ret <= 0)
|
||||
break;
|
||||
+ WARN_ONCE(ret > sd.total_len - left,
|
||||
+ "Splice Exceeded! ret=%zd tot=%zu left=%zu\n",
|
||||
+ ret, sd.total_len, left);
|
||||
|
||||
sd.num_spliced += ret;
|
||||
sd.total_len -= ret;
|
||||
--- a/include/linux/netfs.h
|
||||
+++ b/include/linux/netfs.h
|
||||
@@ -150,6 +150,7 @@ struct netfs_io_stream {
|
||||
bool active; /* T if stream is active */
|
||||
bool need_retry; /* T if this stream needs retrying */
|
||||
bool failed; /* T if this stream failed */
|
||||
+ bool transferred_valid; /* T is ->transferred is valid */
|
||||
};
|
||||
|
||||
/*
|
@@ -1,29 +0,0 @@
|
||||
From 53abd849fe02d16ae158b4f5f7264c761871089f Mon Sep 17 00:00:00 2001
|
||||
From: Evgeniy Harchenko <evgeniyharchenko.dev@gmail.com>
|
||||
Date: Fri, 15 Aug 2025 12:58:14 +0300
|
||||
Subject: ALSA: hda/realtek: Add support for HP EliteBook x360 830 G6 and
|
||||
EliteBook 830 G6
|
||||
|
||||
The HP EliteBook x360 830 G6 and HP EliteBook 830 G6 have
|
||||
Realtek HDA codec ALC215. It needs the ALC285_FIXUP_HP_GPIO_LED
|
||||
quirk to enable the mute LED.
|
||||
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Evgeniy Harchenko <evgeniyharchenko.dev@gmail.com>
|
||||
Link: https://patch.msgid.link/20250815095814.75845-1-evgeniyharchenko.dev@gmail.com
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -10662,6 +10662,8 @@ static const struct hda_quirk alc269_fix
|
||||
SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
||||
SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
|
||||
SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
+ SND_PCI_QUIRK(0x103c, 0x8548, "HP EliteBook x360 830 G6", ALC285_FIXUP_HP_GPIO_LED),
|
||||
+ SND_PCI_QUIRK(0x103c, 0x854a, "HP EliteBook 830 G6", ALC285_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x85c6, "HP Pavilion x360 Convertible 14-dy1xxx", ALC295_FIXUP_HP_MUTE_LED_COEFBIT11),
|
||||
SND_PCI_QUIRK(0x103c, 0x85de, "HP Envy x360 13-ar0xxx", ALC285_FIXUP_HP_ENVY_X360),
|
||||
SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT),
|
@@ -1,76 +0,0 @@
|
||||
From 23b7b20948f48844f17030dab3b1e556f37c803a Mon Sep 17 00:00:00 2001
|
||||
From: Zenm Chen <zenmchen@gmail.com>
|
||||
Date: Thu, 14 Aug 2025 00:24:15 +0800
|
||||
Subject: USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi
|
||||
dongles
|
||||
|
||||
Many Realtek USB Wi-Fi dongles released in recent years have two modes:
|
||||
one is driver CD mode which has Windows driver onboard, another one is
|
||||
Wi-Fi mode. Add the US_FL_IGNORE_DEVICE quirk for these multi-mode devices.
|
||||
Otherwise, usb_modeswitch may fail to switch them to Wi-Fi mode.
|
||||
|
||||
Currently there are only two USB IDs known to be used by these multi-mode
|
||||
Wi-Fi dongles: 0bda:1a2b and 0bda:a192.
|
||||
|
||||
Information about Mercury MW310UH in /sys/kernel/debug/usb/devices.
|
||||
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480 MxCh= 0
|
||||
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=0bda ProdID=a192 Rev= 2.00
|
||||
S: Manufacturer=Realtek
|
||||
S: Product=DISK
|
||||
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA
|
||||
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
|
||||
E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
|
||||
Information about D-Link AX9U rev. A1 in /sys/kernel/debug/usb/devices.
|
||||
T: Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 55 Spd=480 MxCh= 0
|
||||
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=0bda ProdID=1a2b Rev= 0.00
|
||||
S: Manufacturer=Realtek
|
||||
S: Product=DISK
|
||||
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA
|
||||
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
|
||||
E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
|
||||
Cc: stable <stable@kernel.org>
|
||||
Signed-off-by: Zenm Chen <zenmchen@gmail.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Link: https://lore.kernel.org/r/20250813162415.2630-1-zenmchen@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/storage/unusual_devs.h | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
--- a/drivers/usb/storage/unusual_devs.h
|
||||
+++ b/drivers/usb/storage/unusual_devs.h
|
||||
@@ -1501,6 +1501,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_NO_WP_DETECT ),
|
||||
|
||||
+/*
|
||||
+ * Reported by Zenm Chen <zenmchen@gmail.com>
|
||||
+ * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch
|
||||
+ * the device into Wi-Fi mode.
|
||||
+ */
|
||||
+UNUSUAL_DEV( 0x0bda, 0x1a2b, 0x0000, 0xffff,
|
||||
+ "Realtek",
|
||||
+ "DISK",
|
||||
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
+ US_FL_IGNORE_DEVICE ),
|
||||
+
|
||||
+/*
|
||||
+ * Reported by Zenm Chen <zenmchen@gmail.com>
|
||||
+ * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch
|
||||
+ * the device into Wi-Fi mode.
|
||||
+ */
|
||||
+UNUSUAL_DEV( 0x0bda, 0xa192, 0x0000, 0xffff,
|
||||
+ "Realtek",
|
||||
+ "DISK",
|
||||
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
+ US_FL_IGNORE_DEVICE ),
|
||||
+
|
||||
UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999,
|
||||
"Maxtor",
|
||||
"USB to SATA",
|
@@ -1,129 +0,0 @@
|
||||
From fc0576dcffc4ec82e728efe8bb3e3e753151fde0 Mon Sep 17 00:00:00 2001
|
||||
From: Selvarasu Ganesan <selvarasu.g@samsung.com>
|
||||
Date: Fri, 8 Aug 2025 18:23:05 +0530
|
||||
Subject: usb: dwc3: Remove WARN_ON for device endpoint command timeouts
|
||||
|
||||
This commit addresses a rarely observed endpoint command timeout
|
||||
which causes kernel panic due to warn when 'panic_on_warn' is enabled
|
||||
and unnecessary call trace prints when 'panic_on_warn' is disabled.
|
||||
It is seen during fast software-controlled connect/disconnect testcases.
|
||||
The following is one such endpoint command timeout that we observed:
|
||||
|
||||
1. Connect
|
||||
=======
|
||||
->dwc3_thread_interrupt
|
||||
->dwc3_ep0_interrupt
|
||||
->configfs_composite_setup
|
||||
->composite_setup
|
||||
->usb_ep_queue
|
||||
->dwc3_gadget_ep0_queue
|
||||
->__dwc3_gadget_ep0_queue
|
||||
->__dwc3_ep0_do_control_data
|
||||
->dwc3_send_gadget_ep_cmd
|
||||
|
||||
2. Disconnect
|
||||
==========
|
||||
->dwc3_thread_interrupt
|
||||
->dwc3_gadget_disconnect_interrupt
|
||||
->dwc3_ep0_reset_state
|
||||
->dwc3_ep0_end_control_data
|
||||
->dwc3_send_gadget_ep_cmd
|
||||
|
||||
In the issue scenario, in Exynos platforms, we observed that control
|
||||
transfers for the previous connect have not yet been completed and end
|
||||
transfer command sent as a part of the disconnect sequence and
|
||||
processing of USB_ENDPOINT_HALT feature request from the host timeout.
|
||||
This maybe an expected scenario since the controller is processing EP
|
||||
commands sent as a part of the previous connect. It maybe better to
|
||||
remove WARN_ON in all places where device endpoint commands are sent to
|
||||
avoid unnecessary kernel panic due to warn.
|
||||
|
||||
Cc: stable <stable@kernel.org>
|
||||
Co-developed-by: Akash M <akash.m5@samsung.com>
|
||||
Signed-off-by: Akash M <akash.m5@samsung.com>
|
||||
Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com>
|
||||
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
|
||||
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Link: https://lore.kernel.org/r/20250808125315.1607-1-selvarasu.g@samsung.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/dwc3/ep0.c | 20 ++++++++++++++++----
|
||||
drivers/usb/dwc3/gadget.c | 10 ++++++++--
|
||||
2 files changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/usb/dwc3/ep0.c
|
||||
+++ b/drivers/usb/dwc3/ep0.c
|
||||
@@ -288,7 +288,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc
|
||||
dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 8,
|
||||
DWC3_TRBCTL_CONTROL_SETUP, false);
|
||||
ret = dwc3_ep0_start_trans(dep);
|
||||
- WARN_ON(ret < 0);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(dwc->dev, "ep0 out start transfer failed: %d\n", ret);
|
||||
+
|
||||
for (i = 2; i < DWC3_ENDPOINTS_NUM; i++) {
|
||||
struct dwc3_ep *dwc3_ep;
|
||||
|
||||
@@ -1061,7 +1063,9 @@ static void __dwc3_ep0_do_control_data(s
|
||||
ret = dwc3_ep0_start_trans(dep);
|
||||
}
|
||||
|
||||
- WARN_ON(ret < 0);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(dwc->dev,
|
||||
+ "ep0 data phase start transfer failed: %d\n", ret);
|
||||
}
|
||||
|
||||
static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
|
||||
@@ -1078,7 +1082,12 @@ static int dwc3_ep0_start_control_status
|
||||
|
||||
static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
|
||||
{
|
||||
- WARN_ON(dwc3_ep0_start_control_status(dep));
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = dwc3_ep0_start_control_status(dep);
|
||||
+ if (ret)
|
||||
+ dev_err(dwc->dev,
|
||||
+ "ep0 status phase start transfer failed: %d\n", ret);
|
||||
}
|
||||
|
||||
static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
|
||||
@@ -1121,7 +1130,10 @@ void dwc3_ep0_end_control_data(struct dw
|
||||
cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
|
||||
- WARN_ON_ONCE(ret);
|
||||
+ if (ret)
|
||||
+ dev_err_ratelimited(dwc->dev,
|
||||
+ "ep0 data phase end transfer failed: %d\n", ret);
|
||||
+
|
||||
dep->resource_index = 0;
|
||||
}
|
||||
|
||||
--- a/drivers/usb/dwc3/gadget.c
|
||||
+++ b/drivers/usb/dwc3/gadget.c
|
||||
@@ -1774,7 +1774,11 @@ static int __dwc3_stop_active_transfer(s
|
||||
dep->flags |= DWC3_EP_DELAY_STOP;
|
||||
return 0;
|
||||
}
|
||||
- WARN_ON_ONCE(ret);
|
||||
+
|
||||
+ if (ret)
|
||||
+ dev_err_ratelimited(dep->dwc->dev,
|
||||
+ "end transfer failed: %d\n", ret);
|
||||
+
|
||||
dep->resource_index = 0;
|
||||
|
||||
if (!interrupt)
|
||||
@@ -4050,7 +4054,9 @@ static void dwc3_clear_stall_all_ep(stru
|
||||
dep->flags &= ~DWC3_EP_STALL;
|
||||
|
||||
ret = dwc3_send_clear_stall_ep_cmd(dep);
|
||||
- WARN_ON_ONCE(ret);
|
||||
+ if (ret)
|
||||
+ dev_err_ratelimited(dwc->dev,
|
||||
+ "failed to clear STALL on %s\n", dep->name);
|
||||
}
|
||||
}
|
||||
|
@@ -1,51 +0,0 @@
|
||||
From ce921c8404b2574fe419d3c0efee185b4a951d70 Mon Sep 17 00:00:00 2001
|
||||
From: Amit Sunil Dhamne <amitsd@google.com>
|
||||
Date: Fri, 15 Aug 2025 11:31:51 -0700
|
||||
Subject: usb: typec: maxim_contaminant: disable low power mode when reading
|
||||
comparator values
|
||||
|
||||
Low power mode is enabled when reading CC resistance as part of
|
||||
`max_contaminant_read_resistance_kohm()` and left in that state.
|
||||
However, it's supposed to work with 1uA current source. To read CC
|
||||
comparator values current source is changed to 80uA. This causes a storm
|
||||
of CC interrupts as it (falsely) detects a potential contaminant. To
|
||||
prevent this, disable low power mode current sourcing before reading
|
||||
comparator values.
|
||||
|
||||
Fixes: 02b332a06397 ("usb: typec: maxim_contaminant: Implement check_contaminant callback")
|
||||
Cc: stable <stable@kernel.org>
|
||||
Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
|
||||
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
|
||||
Rule: add
|
||||
Link: https://lore.kernel.org/stable/20250814-fix-upstream-contaminant-v1-1-801ce8089031%40google.com
|
||||
Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-1-6c8d6c3adafb@google.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/typec/tcpm/maxim_contaminant.c | 5 +++++
|
||||
drivers/usb/typec/tcpm/tcpci_maxim.h | 1 +
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/usb/typec/tcpm/maxim_contaminant.c
|
||||
+++ b/drivers/usb/typec/tcpm/maxim_contaminant.c
|
||||
@@ -188,6 +188,11 @@ static int max_contaminant_read_comparat
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ /* Disable low power mode */
|
||||
+ ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
|
||||
+ FIELD_PREP(CCLPMODESEL,
|
||||
+ LOW_POWER_MODE_DISABLE));
|
||||
+
|
||||
/* Sleep to allow comparators settle */
|
||||
usleep_range(5000, 6000);
|
||||
ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_ORIENTATION, PLUG_ORNT_CC1);
|
||||
--- a/drivers/usb/typec/tcpm/tcpci_maxim.h
|
||||
+++ b/drivers/usb/typec/tcpm/tcpci_maxim.h
|
||||
@@ -21,6 +21,7 @@
|
||||
#define CCOVPDIS BIT(6)
|
||||
#define SBURPCTRL BIT(5)
|
||||
#define CCLPMODESEL GENMASK(4, 3)
|
||||
+#define LOW_POWER_MODE_DISABLE 0
|
||||
#define ULTRA_LOW_POWER_MODE 1
|
||||
#define CCRPCTRL GENMASK(2, 0)
|
||||
#define UA_1_SRC 1
|
@@ -1,114 +0,0 @@
|
||||
From 9a6bb08b2f28ebc163784da8c61a1ed1d086dc7b Mon Sep 17 00:00:00 2001
|
||||
From: Amit Sunil Dhamne <amitsd@google.com>
|
||||
Date: Fri, 15 Aug 2025 11:31:52 -0700
|
||||
Subject: usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and
|
||||
port is clean
|
||||
|
||||
Presently in `max_contaminant_is_contaminant()` if there's no
|
||||
contaminant detected previously, CC is open & stopped toggling and no
|
||||
contaminant is currently present, TCPC.RC would be programmed to do DRP
|
||||
toggling. However, it didn't actively look for a connection. This would
|
||||
lead to Type-C not detect *any* new connections. Hence, in the above
|
||||
situation, re-enable toggling & program TCPC to look for a new
|
||||
connection.
|
||||
|
||||
Also, return early if TCPC was looking for connection as this indicates
|
||||
TCPC has neither detected a potential connection nor a change in
|
||||
contaminant state.
|
||||
|
||||
In addition, once dry detection is complete (port is dry), restart
|
||||
toggling.
|
||||
|
||||
Fixes: 02b332a06397e ("usb: typec: maxim_contaminant: Implement check_contaminant callback")
|
||||
Cc: stable <stable@kernel.org>
|
||||
Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
|
||||
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
|
||||
Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-2-6c8d6c3adafb@google.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/typec/tcpm/maxim_contaminant.c | 53 ++++++++++++++++++++++
|
||||
1 file changed, 53 insertions(+)
|
||||
|
||||
--- a/drivers/usb/typec/tcpm/maxim_contaminant.c
|
||||
+++ b/drivers/usb/typec/tcpm/maxim_contaminant.c
|
||||
@@ -329,6 +329,39 @@ static int max_contaminant_enable_dry_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int max_contaminant_enable_toggling(struct max_tcpci_chip *chip)
|
||||
+{
|
||||
+ struct regmap *regmap = chip->data.regmap;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Disable dry detection if enabled. */
|
||||
+ ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
|
||||
+ FIELD_PREP(CCLPMODESEL,
|
||||
+ LOW_POWER_MODE_DISABLE));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCONNDRY, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, TCPC_ROLE_CTRL_DRP |
|
||||
+ FIELD_PREP(TCPC_ROLE_CTRL_CC1,
|
||||
+ TCPC_ROLE_CTRL_CC_RD) |
|
||||
+ FIELD_PREP(TCPC_ROLE_CTRL_CC2,
|
||||
+ TCPC_ROLE_CTRL_CC_RD));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL,
|
||||
+ TCPC_TCPC_CTRL_EN_LK4CONN_ALRT,
|
||||
+ TCPC_TCPC_CTRL_EN_LK4CONN_ALRT);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return max_tcpci_write8(chip, TCPC_COMMAND, TCPC_CMD_LOOK4CONNECTION);
|
||||
+}
|
||||
+
|
||||
bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect_while_debounce,
|
||||
bool *cc_handled)
|
||||
{
|
||||
@@ -345,6 +378,12 @@ bool max_contaminant_is_contaminant(stru
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
+ if (cc_status & TCPC_CC_STATUS_TOGGLING) {
|
||||
+ if (chip->contaminant_state == DETECTED)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (chip->contaminant_state == NOT_DETECTED || chip->contaminant_state == SINK) {
|
||||
if (!disconnect_while_debounce)
|
||||
msleep(100);
|
||||
@@ -377,6 +416,12 @@ bool max_contaminant_is_contaminant(stru
|
||||
max_contaminant_enable_dry_detection(chip);
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+ ret = max_contaminant_enable_toggling(chip);
|
||||
+ if (ret)
|
||||
+ dev_err(chip->dev,
|
||||
+ "Failed to enable toggling, ret=%d",
|
||||
+ ret);
|
||||
}
|
||||
} else if (chip->contaminant_state == DETECTED) {
|
||||
if (!(cc_status & TCPC_CC_STATUS_TOGGLING)) {
|
||||
@@ -384,6 +429,14 @@ bool max_contaminant_is_contaminant(stru
|
||||
if (chip->contaminant_state == DETECTED) {
|
||||
max_contaminant_enable_dry_detection(chip);
|
||||
return true;
|
||||
+ } else {
|
||||
+ ret = max_contaminant_enable_toggling(chip);
|
||||
+ if (ret) {
|
||||
+ dev_err(chip->dev,
|
||||
+ "Failed to enable toggling, ret=%d",
|
||||
+ ret);
|
||||
+ return true;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
From 576b70e92168f38ab3167768acb6b65cd5bf8aa7 Mon Sep 17 00:00:00 2001
|
||||
From: Charalampos Mitrodimas <charmitro@posteo.net>
|
||||
Date: Sat, 16 Aug 2025 14:14:37 +0000
|
||||
Subject: debugfs: fix mount options not being applied
|
||||
|
||||
Mount options (uid, gid, mode) are silently ignored when debugfs is
|
||||
mounted. This is a regression introduced during the conversion to the
|
||||
new mount API.
|
||||
|
||||
When the mount API conversion was done, the parsed options were never
|
||||
applied to the superblock when it was reused. As a result, the mount
|
||||
options were ignored when debugfs was mounted.
|
||||
|
||||
Fix this by following the same pattern as the tracefs fix in commit
|
||||
e4d32142d1de ("tracing: Fix tracefs mount options"). Call
|
||||
debugfs_reconfigure() in debugfs_get_tree() to apply the mount options
|
||||
to the superblock after it has been created or reused.
|
||||
|
||||
As an example, with the bug the "mode" mount option is ignored:
|
||||
|
||||
$ mount -o mode=0666 -t debugfs debugfs /tmp/debugfs_test
|
||||
$ mount | grep debugfs_test
|
||||
debugfs on /tmp/debugfs_test type debugfs (rw,relatime)
|
||||
$ ls -ld /tmp/debugfs_test
|
||||
drwx------ 25 root root 0 Aug 4 14:16 /tmp/debugfs_test
|
||||
|
||||
With the fix applied, it works as expected:
|
||||
|
||||
$ mount -o mode=0666 -t debugfs debugfs /tmp/debugfs_test
|
||||
$ mount | grep debugfs_test
|
||||
debugfs on /tmp/debugfs_test type debugfs (rw,relatime,mode=666)
|
||||
$ ls -ld /tmp/debugfs_test
|
||||
drw-rw-rw- 37 root root 0 Aug 2 17:28 /tmp/debugfs_test
|
||||
|
||||
Fixes: a20971c18752 ("vfs: Convert debugfs to use the new mount API")
|
||||
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220406
|
||||
Cc: stable <stable@kernel.org>
|
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
|
||||
Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
|
||||
Link: https://lore.kernel.org/r/20250816-debugfs-mount-opts-v3-1-d271dad57b5b@posteo.net
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/debugfs/inode.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/fs/debugfs/inode.c
|
||||
+++ b/fs/debugfs/inode.c
|
||||
@@ -183,6 +183,9 @@ static int debugfs_reconfigure(struct fs
|
||||
struct debugfs_fs_info *sb_opts = sb->s_fs_info;
|
||||
struct debugfs_fs_info *new_opts = fc->s_fs_info;
|
||||
|
||||
+ if (!new_opts)
|
||||
+ return 0;
|
||||
+
|
||||
sync_filesystem(sb);
|
||||
|
||||
/* structure copy of new mount options to sb */
|
||||
@@ -282,10 +285,16 @@ static int debugfs_fill_super(struct sup
|
||||
|
||||
static int debugfs_get_tree(struct fs_context *fc)
|
||||
{
|
||||
+ int err;
|
||||
+
|
||||
if (!(debugfs_allow & DEBUGFS_ALLOW_API))
|
||||
return -EPERM;
|
||||
|
||||
- return get_tree_single(fc, debugfs_fill_super);
|
||||
+ err = get_tree_single(fc, debugfs_fill_super);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return debugfs_reconfigure(fc);
|
||||
}
|
||||
|
||||
static void debugfs_free_fc(struct fs_context *fc)
|
@@ -1,88 +0,0 @@
|
||||
From 80250ddfb13b64a0fef53806669893094a731956 Mon Sep 17 00:00:00 2001
|
||||
From: Namjae Jeon <linkinjeon@kernel.org>
|
||||
Date: Sun, 17 Aug 2025 09:48:40 +0900
|
||||
Subject: ksmbd: extend the connection limiting mechanism to support IPv6
|
||||
|
||||
Update the connection tracking logic to handle both IPv4 and IPv6
|
||||
address families.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: e6bb91939740 ("ksmbd: limit repeated connections from clients with the same IP")
|
||||
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/server/connection.h | 7 ++++++-
|
||||
fs/smb/server/transport_tcp.c | 26 +++++++++++++++++++++++---
|
||||
2 files changed, 29 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/fs/smb/server/connection.h
|
||||
+++ b/fs/smb/server/connection.h
|
||||
@@ -46,7 +46,12 @@ struct ksmbd_conn {
|
||||
struct mutex srv_mutex;
|
||||
int status;
|
||||
unsigned int cli_cap;
|
||||
- __be32 inet_addr;
|
||||
+ union {
|
||||
+ __be32 inet_addr;
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+ u8 inet6_addr[16];
|
||||
+#endif
|
||||
+ };
|
||||
char *request_buf;
|
||||
struct ksmbd_transport *transport;
|
||||
struct nls_table *local_nls;
|
||||
--- a/fs/smb/server/transport_tcp.c
|
||||
+++ b/fs/smb/server/transport_tcp.c
|
||||
@@ -87,7 +87,14 @@ static struct tcp_transport *alloc_trans
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+ if (client_sk->sk->sk_family == AF_INET6)
|
||||
+ memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16);
|
||||
+ else
|
||||
+ conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
|
||||
+#else
|
||||
conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
|
||||
+#endif
|
||||
conn->transport = KSMBD_TRANS(t);
|
||||
KSMBD_TRANS(t)->conn = conn;
|
||||
KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
|
||||
@@ -231,7 +238,6 @@ static int ksmbd_kthread_fn(void *p)
|
||||
{
|
||||
struct socket *client_sk = NULL;
|
||||
struct interface *iface = (struct interface *)p;
|
||||
- struct inet_sock *csk_inet;
|
||||
struct ksmbd_conn *conn;
|
||||
int ret;
|
||||
|
||||
@@ -254,13 +260,27 @@ static int ksmbd_kthread_fn(void *p)
|
||||
/*
|
||||
* Limits repeated connections from clients with the same IP.
|
||||
*/
|
||||
- csk_inet = inet_sk(client_sk->sk);
|
||||
down_read(&conn_list_lock);
|
||||
list_for_each_entry(conn, &conn_list, conns_list)
|
||||
- if (csk_inet->inet_daddr == conn->inet_addr) {
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+ if (client_sk->sk->sk_family == AF_INET6) {
|
||||
+ if (memcmp(&client_sk->sk->sk_v6_daddr,
|
||||
+ &conn->inet6_addr, 16) == 0) {
|
||||
+ ret = -EAGAIN;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (inet_sk(client_sk->sk)->inet_daddr ==
|
||||
+ conn->inet_addr) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
+#else
|
||||
+ if (inet_sk(client_sk->sk)->inet_daddr ==
|
||||
+ conn->inet_addr) {
|
||||
+ ret = -EAGAIN;
|
||||
+ break;
|
||||
+ }
|
||||
+#endif
|
||||
up_read(&conn_list_lock);
|
||||
if (ret == -EAGAIN)
|
||||
continue;
|
@@ -1,56 +0,0 @@
|
||||
From 053ed640e99b096f155a404b3d919b3475bd4275 Mon Sep 17 00:00:00 2001
|
||||
From: Ziyan Xu <ziyan@securitygossip.com>
|
||||
Date: Sat, 16 Aug 2025 10:20:05 +0900
|
||||
Subject: ksmbd: fix refcount leak causing resource not released
|
||||
|
||||
When ksmbd_conn_releasing(opinfo->conn) returns true,the refcount was not
|
||||
decremented properly, causing a refcount leak that prevents the count from
|
||||
reaching zero and the memory from being released.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Ziyan Xu <ziyan@securitygossip.com>
|
||||
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/server/oplock.c | 13 ++++++++++---
|
||||
1 file changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/fs/smb/server/oplock.c
|
||||
+++ b/fs/smb/server/oplock.c
|
||||
@@ -1102,8 +1102,10 @@ void smb_send_parent_lease_break_noti(st
|
||||
if (!atomic_inc_not_zero(&opinfo->refcount))
|
||||
continue;
|
||||
|
||||
- if (ksmbd_conn_releasing(opinfo->conn))
|
||||
+ if (ksmbd_conn_releasing(opinfo->conn)) {
|
||||
+ opinfo_put(opinfo);
|
||||
continue;
|
||||
+ }
|
||||
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
|
||||
opinfo_put(opinfo);
|
||||
@@ -1139,8 +1141,11 @@ void smb_lazy_parent_lease_break_close(s
|
||||
if (!atomic_inc_not_zero(&opinfo->refcount))
|
||||
continue;
|
||||
|
||||
- if (ksmbd_conn_releasing(opinfo->conn))
|
||||
+ if (ksmbd_conn_releasing(opinfo->conn)) {
|
||||
+ opinfo_put(opinfo);
|
||||
continue;
|
||||
+ }
|
||||
+
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
|
||||
opinfo_put(opinfo);
|
||||
}
|
||||
@@ -1343,8 +1348,10 @@ void smb_break_all_levII_oplock(struct k
|
||||
if (!atomic_inc_not_zero(&brk_op->refcount))
|
||||
continue;
|
||||
|
||||
- if (ksmbd_conn_releasing(brk_op->conn))
|
||||
+ if (ksmbd_conn_releasing(brk_op->conn)) {
|
||||
+ opinfo_put(brk_op);
|
||||
continue;
|
||||
+ }
|
||||
|
||||
if (brk_op->is_lease && (brk_op->o_lease->state &
|
||||
(~(SMB2_LEASE_READ_CACHING_LE |
|
@@ -1,86 +0,0 @@
|
||||
From 4d73be13721834ee79ae45bd66102501f17a779d Mon Sep 17 00:00:00 2001
|
||||
From: Victor Shih <victor.shih@genesyslogic.com.tw>
|
||||
Date: Thu, 31 Jul 2025 14:57:50 +0800
|
||||
Subject: mmc: sdhci-pci-gli: Add a new function to simplify the code
|
||||
|
||||
In preparation to fix replay timer timeout, add
|
||||
sdhci_gli_mask_replay_timer_timeout() function
|
||||
to simplify some of the code, allowing it to be re-used.
|
||||
|
||||
Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw>
|
||||
Fixes: 1ae1d2d6e555 ("mmc: sdhci-pci-gli: Add Genesys Logic GL9763E support")
|
||||
Cc: stable@vger.kernel.org
|
||||
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Link: https://lore.kernel.org/r/20250731065752.450231-2-victorshihgli@gmail.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/mmc/host/sdhci-pci-gli.c | 30 ++++++++++++++++--------------
|
||||
1 file changed, 16 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-pci-gli.c
|
||||
+++ b/drivers/mmc/host/sdhci-pci-gli.c
|
||||
@@ -287,6 +287,20 @@
|
||||
#define GLI_MAX_TUNING_LOOP 40
|
||||
|
||||
/* Genesys Logic chipset */
|
||||
+static void sdhci_gli_mask_replay_timer_timeout(struct pci_dev *pdev)
|
||||
+{
|
||||
+ int aer;
|
||||
+ u32 value;
|
||||
+
|
||||
+ /* mask the replay timer timeout of AER */
|
||||
+ aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
||||
+ if (aer) {
|
||||
+ pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value);
|
||||
+ value |= PCI_ERR_COR_REP_TIMER;
|
||||
+ pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static inline void gl9750_wt_on(struct sdhci_host *host)
|
||||
{
|
||||
u32 wt_value;
|
||||
@@ -607,7 +621,6 @@ static void gl9750_hw_setting(struct sdh
|
||||
{
|
||||
struct sdhci_pci_slot *slot = sdhci_priv(host);
|
||||
struct pci_dev *pdev;
|
||||
- int aer;
|
||||
u32 value;
|
||||
|
||||
pdev = slot->chip->pdev;
|
||||
@@ -626,12 +639,7 @@ static void gl9750_hw_setting(struct sdh
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
/* mask the replay timer timeout of AER */
|
||||
- aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
||||
- if (aer) {
|
||||
- pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value);
|
||||
- value |= PCI_ERR_COR_REP_TIMER;
|
||||
- pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value);
|
||||
- }
|
||||
+ sdhci_gli_mask_replay_timer_timeout(pdev);
|
||||
|
||||
gl9750_wt_off(host);
|
||||
}
|
||||
@@ -806,7 +814,6 @@ static void sdhci_gl9755_set_clock(struc
|
||||
static void gl9755_hw_setting(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *pdev = slot->chip->pdev;
|
||||
- int aer;
|
||||
u32 value;
|
||||
|
||||
gl9755_wt_on(pdev);
|
||||
@@ -841,12 +848,7 @@ static void gl9755_hw_setting(struct sdh
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
/* mask the replay timer timeout of AER */
|
||||
- aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
||||
- if (aer) {
|
||||
- pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value);
|
||||
- value |= PCI_ERR_COR_REP_TIMER;
|
||||
- pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value);
|
||||
- }
|
||||
+ sdhci_gli_mask_replay_timer_timeout(pdev);
|
||||
|
||||
gl9755_wt_off(pdev);
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
From dfc8d4137cf986bac6a07e4b202423b0e3d32f9e Mon Sep 17 00:00:00 2001
|
||||
From: Victor Shih <victor.shih@genesyslogic.com.tw>
|
||||
Date: Thu, 31 Jul 2025 14:57:51 +0800
|
||||
Subject: mmc: sdhci-pci-gli: GL9763e: Rename the gli_set_gl9763e() for
|
||||
consistency
|
||||
|
||||
In preparation to fix replay timer timeout, rename the
|
||||
gli_set_gl9763e() to gl9763e_hw_setting() for consistency.
|
||||
|
||||
Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw>
|
||||
Fixes: 1ae1d2d6e555 ("mmc: sdhci-pci-gli: Add Genesys Logic GL9763E support")
|
||||
Cc: stable@vger.kernel.org
|
||||
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Link: https://lore.kernel.org/r/20250731065752.450231-3-victorshihgli@gmail.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/mmc/host/sdhci-pci-gli.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-pci-gli.c
|
||||
+++ b/drivers/mmc/host/sdhci-pci-gli.c
|
||||
@@ -1753,7 +1753,7 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void gli_set_gl9763e(struct sdhci_pci_slot *slot)
|
||||
+static void gl9763e_hw_setting(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *pdev = slot->chip->pdev;
|
||||
u32 value;
|
||||
@@ -1925,7 +1925,7 @@ static int gli_probe_slot_gl9763e(struct
|
||||
gli_pcie_enable_msi(slot);
|
||||
host->mmc_host_ops.hs400_enhanced_strobe =
|
||||
gl9763e_hs400_enhanced_strobe;
|
||||
- gli_set_gl9763e(slot);
|
||||
+ gl9763e_hw_setting(slot);
|
||||
sdhci_enable_v4_mode(host);
|
||||
|
||||
return 0;
|
@@ -1,32 +0,0 @@
|
||||
From d36b9a791450aec781a3276dd3544bdfb147e539 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Shih <victor.shih@genesyslogic.com.tw>
|
||||
Date: Thu, 31 Jul 2025 14:57:52 +0800
|
||||
Subject: mmc: sdhci-pci-gli: GL9763e: Mask the replay timer timeout of AER
|
||||
|
||||
Due to a flaw in the hardware design, the GL9763e replay timer frequently
|
||||
times out when ASPM is enabled. As a result, the warning messages will
|
||||
often appear in the system log when the system accesses the GL9763e
|
||||
PCI config. Therefore, the replay timer timeout must be masked.
|
||||
|
||||
Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw>
|
||||
Fixes: 1ae1d2d6e555 ("mmc: sdhci-pci-gli: Add Genesys Logic GL9763E support")
|
||||
Cc: stable@vger.kernel.org
|
||||
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Link: https://lore.kernel.org/r/20250731065752.450231-4-victorshihgli@gmail.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/mmc/host/sdhci-pci-gli.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-pci-gli.c
|
||||
+++ b/drivers/mmc/host/sdhci-pci-gli.c
|
||||
@@ -1782,6 +1782,9 @@ static void gl9763e_hw_setting(struct sd
|
||||
value |= FIELD_PREP(GLI_9763E_HS400_RXDLY, GLI_9763E_HS400_RXDLY_5);
|
||||
pci_write_config_dword(pdev, PCIE_GLI_9763E_CLKRXDLY, value);
|
||||
|
||||
+ /* mask the replay timer timeout of AER */
|
||||
+ sdhci_gli_mask_replay_timer_timeout(pdev);
|
||||
+
|
||||
pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value);
|
||||
value &= ~GLI_9763E_VHS_REV;
|
||||
value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R);
|
@@ -1,128 +0,0 @@
|
||||
From 848beabc268b0e12a5bc0dbe71c45c5db7a12b43 Mon Sep 17 00:00:00 2001
|
||||
From: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
|
||||
Date: Wed, 30 Jul 2025 11:35:43 +0530
|
||||
Subject: mmc: sdhci-of-arasan: Ensure CD logic stabilization before power-up
|
||||
|
||||
During SD suspend/resume without a full card rescan (when using
|
||||
non-removable SD cards for rootfs), the SD card initialization may fail
|
||||
after resume. This occurs because, after a host controller reset, the
|
||||
card detect logic may take time to stabilize due to debounce logic.
|
||||
Without waiting for stabilization, the host may attempt powering up the
|
||||
card prematurely, leading to command timeouts during resume flow.
|
||||
Add sdhci_arasan_set_power_and_bus_voltage() to wait for the card detect
|
||||
stable bit before power up the card. Since the stabilization time
|
||||
is not fixed, a maximum timeout of one second is used to ensure
|
||||
sufficient wait time for the card detect signal to stabilize.
|
||||
|
||||
Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Link: https://lore.kernel.org/r/20250730060543.1735971-1-sai.krishna.potthuri@amd.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/mmc/host/sdhci-of-arasan.c | 33 ++++++++++++++++++++++++++++--
|
||||
1 file changed, 31 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-of-arasan.c
|
||||
+++ b/drivers/mmc/host/sdhci-of-arasan.c
|
||||
@@ -99,6 +99,9 @@
|
||||
#define HIWORD_UPDATE(val, mask, shift) \
|
||||
((val) << (shift) | (mask) << ((shift) + 16))
|
||||
|
||||
+#define CD_STABLE_TIMEOUT_US 1000000
|
||||
+#define CD_STABLE_MAX_SLEEP_US 10
|
||||
+
|
||||
/**
|
||||
* struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map
|
||||
*
|
||||
@@ -206,12 +209,15 @@ struct sdhci_arasan_data {
|
||||
* 19MHz instead
|
||||
*/
|
||||
#define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2)
|
||||
+/* Enable CD stable check before power-up */
|
||||
+#define SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE BIT(3)
|
||||
};
|
||||
|
||||
struct sdhci_arasan_of_data {
|
||||
const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
|
||||
const struct sdhci_pltfm_data *pdata;
|
||||
const struct sdhci_arasan_clk_ops *clk_ops;
|
||||
+ u32 quirks;
|
||||
};
|
||||
|
||||
static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = {
|
||||
@@ -514,6 +520,24 @@ static int sdhci_arasan_voltage_switch(s
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+static void sdhci_arasan_set_power_and_bus_voltage(struct sdhci_host *host, unsigned char mode,
|
||||
+ unsigned short vdd)
|
||||
+{
|
||||
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
+ struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
|
||||
+ u32 reg;
|
||||
+
|
||||
+ /*
|
||||
+ * Ensure that the card detect logic has stabilized before powering up, this is
|
||||
+ * necessary after a host controller reset.
|
||||
+ */
|
||||
+ if (mode == MMC_POWER_UP && sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE)
|
||||
+ read_poll_timeout(sdhci_readl, reg, reg & SDHCI_CD_STABLE, CD_STABLE_MAX_SLEEP_US,
|
||||
+ CD_STABLE_TIMEOUT_US, false, host, SDHCI_PRESENT_STATE);
|
||||
+
|
||||
+ sdhci_set_power_and_bus_voltage(host, mode, vdd);
|
||||
+}
|
||||
+
|
||||
static const struct sdhci_ops sdhci_arasan_ops = {
|
||||
.set_clock = sdhci_arasan_set_clock,
|
||||
.get_max_clock = sdhci_pltfm_clk_get_max_clock,
|
||||
@@ -521,7 +545,7 @@ static const struct sdhci_ops sdhci_aras
|
||||
.set_bus_width = sdhci_set_bus_width,
|
||||
.reset = sdhci_arasan_reset,
|
||||
.set_uhs_signaling = sdhci_set_uhs_signaling,
|
||||
- .set_power = sdhci_set_power_and_bus_voltage,
|
||||
+ .set_power = sdhci_arasan_set_power_and_bus_voltage,
|
||||
.hw_reset = sdhci_arasan_hw_reset,
|
||||
};
|
||||
|
||||
@@ -570,7 +594,7 @@ static const struct sdhci_ops sdhci_aras
|
||||
.set_bus_width = sdhci_set_bus_width,
|
||||
.reset = sdhci_arasan_reset,
|
||||
.set_uhs_signaling = sdhci_set_uhs_signaling,
|
||||
- .set_power = sdhci_set_power_and_bus_voltage,
|
||||
+ .set_power = sdhci_arasan_set_power_and_bus_voltage,
|
||||
.irq = sdhci_arasan_cqhci_irq,
|
||||
};
|
||||
|
||||
@@ -1447,6 +1471,7 @@ static const struct sdhci_arasan_clk_ops
|
||||
static struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = {
|
||||
.pdata = &sdhci_arasan_zynqmp_pdata,
|
||||
.clk_ops = &zynqmp_clk_ops,
|
||||
+ .quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE,
|
||||
};
|
||||
|
||||
static const struct sdhci_arasan_clk_ops versal_clk_ops = {
|
||||
@@ -1457,6 +1482,7 @@ static const struct sdhci_arasan_clk_ops
|
||||
static struct sdhci_arasan_of_data sdhci_arasan_versal_data = {
|
||||
.pdata = &sdhci_arasan_zynqmp_pdata,
|
||||
.clk_ops = &versal_clk_ops,
|
||||
+ .quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE,
|
||||
};
|
||||
|
||||
static const struct sdhci_arasan_clk_ops versal_net_clk_ops = {
|
||||
@@ -1467,6 +1493,7 @@ static const struct sdhci_arasan_clk_ops
|
||||
static struct sdhci_arasan_of_data sdhci_arasan_versal_net_data = {
|
||||
.pdata = &sdhci_arasan_versal_net_pdata,
|
||||
.clk_ops = &versal_net_clk_ops,
|
||||
+ .quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE,
|
||||
};
|
||||
|
||||
static struct sdhci_arasan_of_data intel_keembay_emmc_data = {
|
||||
@@ -1945,6 +1972,8 @@ static int sdhci_arasan_probe(struct pla
|
||||
if (of_device_is_compatible(np, "rockchip,rk3399-sdhci-5.1"))
|
||||
sdhci_arasan_update_clockmultiplier(host, 0x0);
|
||||
|
||||
+ sdhci_arasan->quirks |= data->quirks;
|
||||
+
|
||||
if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
|
||||
of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
|
||||
of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
|
@@ -1,75 +0,0 @@
|
||||
From 6b13747a602e6e119a0cfd03d967e0726d12ba26 Mon Sep 17 00:00:00 2001
|
||||
From: Jiayi Li <lijiayi@kylinos.cn>
|
||||
Date: Mon, 4 Aug 2025 09:36:04 +0800
|
||||
Subject: memstick: Fix deadlock by moving removing flag earlier
|
||||
|
||||
The existing memstick core patch: commit 62c59a8786e6 ("memstick: Skip
|
||||
allocating card when removing host") sets host->removing in
|
||||
memstick_remove_host(),but still exists a critical time window where
|
||||
memstick_check can run after host->eject is set but before removing is set.
|
||||
|
||||
In the rtsx_usb_ms driver, the problematic sequence is:
|
||||
|
||||
rtsx_usb_ms_drv_remove: memstick_check:
|
||||
host->eject = true
|
||||
cancel_work_sync(handle_req) if(!host->removing)
|
||||
... memstick_alloc_card()
|
||||
memstick_set_rw_addr()
|
||||
memstick_new_req()
|
||||
rtsx_usb_ms_request()
|
||||
if(!host->eject)
|
||||
skip schedule_work
|
||||
wait_for_completion()
|
||||
memstick_remove_host: [blocks indefinitely]
|
||||
host->removing = true
|
||||
flush_workqueue()
|
||||
[block]
|
||||
|
||||
1. rtsx_usb_ms_drv_remove sets host->eject = true
|
||||
2. cancel_work_sync(&host->handle_req) runs
|
||||
3. memstick_check work may be executed here <-- danger window
|
||||
4. memstick_remove_host sets removing = 1
|
||||
|
||||
During this window (step 3), memstick_check calls memstick_alloc_card,
|
||||
which may indefinitely waiting for mrq_complete completion that will
|
||||
never occur because rtsx_usb_ms_request sees eject=true and skips
|
||||
scheduling work, memstick_set_rw_addr waits forever for completion.
|
||||
|
||||
This causes a deadlock when memstick_remove_host tries to flush_workqueue,
|
||||
waiting for memstick_check to complete, while memstick_check is blocked
|
||||
waiting for mrq_complete completion.
|
||||
|
||||
Fix this by setting removing=true at the start of rtsx_usb_ms_drv_remove,
|
||||
before any work cancellation. This ensures memstick_check will see the
|
||||
removing flag immediately and exit early, avoiding the deadlock.
|
||||
|
||||
Fixes: 62c59a8786e6 ("memstick: Skip allocating card when removing host")
|
||||
Signed-off-by: Jiayi Li <lijiayi@kylinos.cn>
|
||||
Cc: stable@vger.kernel.org
|
||||
Link: https://lore.kernel.org/r/20250804013604.1311218-1-lijiayi@kylinos.cn
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/memstick/core/memstick.c | 1 -
|
||||
drivers/memstick/host/rtsx_usb_ms.c | 1 +
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/memstick/core/memstick.c
|
||||
+++ b/drivers/memstick/core/memstick.c
|
||||
@@ -555,7 +555,6 @@ EXPORT_SYMBOL(memstick_add_host);
|
||||
*/
|
||||
void memstick_remove_host(struct memstick_host *host)
|
||||
{
|
||||
- host->removing = 1;
|
||||
flush_workqueue(workqueue);
|
||||
mutex_lock(&host->lock);
|
||||
if (host->card)
|
||||
--- a/drivers/memstick/host/rtsx_usb_ms.c
|
||||
+++ b/drivers/memstick/host/rtsx_usb_ms.c
|
||||
@@ -812,6 +812,7 @@ static void rtsx_usb_ms_drv_remove(struc
|
||||
int err;
|
||||
|
||||
host->eject = true;
|
||||
+ msh->removing = true;
|
||||
cancel_work_sync(&host->handle_req);
|
||||
cancel_delayed_work_sync(&host->poll_card);
|
||||
|
@@ -1,63 +0,0 @@
|
||||
From c09f6cef1d27da9baec950c8949926c9fc42a3e7 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Date: Mon, 14 Apr 2025 16:41:07 +0200
|
||||
Subject: compiler: remove __ADDRESSABLE_ASM{_STR,}() again
|
||||
|
||||
__ADDRESSABLE_ASM_STR() is where the necessary stringification happens.
|
||||
As long as "sym" doesn't contain any odd characters, no quoting is
|
||||
required for its use with .quad / .long. In fact the quotation gets in
|
||||
the way with gas 2.25; it's only from 2.26 onwards that quoted symbols
|
||||
are half-way properly supported.
|
||||
|
||||
However, assembly being different from C anyway, drop
|
||||
__ADDRESSABLE_ASM_STR() and its helper macro altogether. A simple
|
||||
.global directive will suffice to get the symbol "declared", i.e. into
|
||||
the symbol table. While there also stop open-coding STATIC_CALL_TRAMP()
|
||||
and STATIC_CALL_KEY().
|
||||
|
||||
Fixes: 0ef8047b737d ("x86/static-call: provide a way to do very early static-call updates")
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Juergen Gross <jgross@suse.com>
|
||||
Message-ID: <609d2c74-de13-4fae-ab1a-1ec44afb948d@suse.com>
|
||||
---
|
||||
arch/x86/include/asm/xen/hypercall.h | 5 +++--
|
||||
include/linux/compiler.h | 8 --------
|
||||
2 files changed, 3 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/arch/x86/include/asm/xen/hypercall.h
|
||||
+++ b/arch/x86/include/asm/xen/hypercall.h
|
||||
@@ -94,12 +94,13 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_h
|
||||
#ifdef MODULE
|
||||
#define __ADDRESSABLE_xen_hypercall
|
||||
#else
|
||||
-#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall)
|
||||
+#define __ADDRESSABLE_xen_hypercall \
|
||||
+ __stringify(.global STATIC_CALL_KEY(xen_hypercall);)
|
||||
#endif
|
||||
|
||||
#define __HYPERCALL \
|
||||
__ADDRESSABLE_xen_hypercall \
|
||||
- "call __SCT__xen_hypercall"
|
||||
+ __stringify(call STATIC_CALL_TRAMP(xen_hypercall))
|
||||
|
||||
#define __HYPERCALL_ENTRY(x) "a" (x)
|
||||
|
||||
--- a/include/linux/compiler.h
|
||||
+++ b/include/linux/compiler.h
|
||||
@@ -288,14 +288,6 @@ static inline void *offset_to_ptr(const
|
||||
#define __ADDRESSABLE(sym) \
|
||||
___ADDRESSABLE(sym, __section(".discard.addressable"))
|
||||
|
||||
-#define __ADDRESSABLE_ASM(sym) \
|
||||
- .pushsection .discard.addressable,"aw"; \
|
||||
- .align ARCH_SEL(8,4); \
|
||||
- ARCH_SEL(.quad, .long) __stringify(sym); \
|
||||
- .popsection;
|
||||
-
|
||||
-#define __ADDRESSABLE_ASM_STR(sym) __stringify(__ADDRESSABLE_ASM(sym))
|
||||
-
|
||||
/*
|
||||
* This returns a constant expression while determining if an argument is
|
||||
* a constant expression, most importantly without evaluating the argument.
|
@@ -1,55 +0,0 @@
|
||||
From 3ba50a386db1ab9c1bdabbdcea6e7063bd7f875d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@baylibre.com>
|
||||
Date: Thu, 14 Aug 2025 07:11:57 +0200
|
||||
Subject: ACPI: APEI: EINJ: Fix resource leak by remove callback in .exit.text
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The .remove() callback is also used during error handling in
|
||||
faux_probe(). As einj_remove() was marked with __exit it's not linked
|
||||
into the kernel if the driver is built-in, potentially resulting in
|
||||
resource leaks.
|
||||
|
||||
Also remove the comment justifying the __exit annotation which doesn't
|
||||
apply any more since the driver was converted to the faux device
|
||||
interface.
|
||||
|
||||
Fixes: 6cb9441bfe8d ("ACPI: APEI: EINJ: Transition to the faux device interface")
|
||||
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
|
||||
Cc: 6.16+ <stable@vger.kernel.org> # 6.16+
|
||||
Link: https://patch.msgid.link/20250814051157.35867-2-u.kleine-koenig@baylibre.com
|
||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
---
|
||||
drivers/acpi/apei/einj-core.c | 12 +++---------
|
||||
1 file changed, 3 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/acpi/apei/einj-core.c
|
||||
+++ b/drivers/acpi/apei/einj-core.c
|
||||
@@ -842,7 +842,7 @@ err_put_table:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static void __exit einj_remove(struct faux_device *fdev)
|
||||
+static void einj_remove(struct faux_device *fdev)
|
||||
{
|
||||
struct apei_exec_context ctx;
|
||||
|
||||
@@ -864,15 +864,9 @@ static void __exit einj_remove(struct fa
|
||||
}
|
||||
|
||||
static struct faux_device *einj_dev;
|
||||
-/*
|
||||
- * einj_remove() lives in .exit.text. For drivers registered via
|
||||
- * platform_driver_probe() this is ok because they cannot get unbound at
|
||||
- * runtime. So mark the driver struct with __refdata to prevent modpost
|
||||
- * triggering a section mismatch warning.
|
||||
- */
|
||||
-static struct faux_device_ops einj_device_ops __refdata = {
|
||||
+static struct faux_device_ops einj_device_ops = {
|
||||
.probe = einj_probe,
|
||||
- .remove = __exit_p(einj_remove),
|
||||
+ .remove = einj_remove,
|
||||
};
|
||||
|
||||
static int __init einj_init(void)
|
@@ -1,118 +0,0 @@
|
||||
From 2d8daa84e1cb9681d49a29cf829eb5678850210e Mon Sep 17 00:00:00 2001
|
||||
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
|
||||
Date: Wed, 13 Aug 2025 12:25:58 +0200
|
||||
Subject: cpuidle: governors: menu: Avoid selecting states with too much
|
||||
latency
|
||||
|
||||
Occasionally, the exit latency of the idle state selected by the menu
|
||||
governor may exceed the PM QoS CPU wakeup latency limit. Namely, if the
|
||||
scheduler tick has been stopped already and predicted_ns is greater than
|
||||
the tick period length, the governor may return an idle state whose exit
|
||||
latency exceeds latency_req because that decision is made before
|
||||
checking the current idle state's exit latency.
|
||||
|
||||
For instance, say that there are 3 idle states, 0, 1, and 2. For idle
|
||||
states 0 and 1, the exit latency is equal to the target residency and
|
||||
the values are 0 and 5 us, respectively. State 2 is deeper and has the
|
||||
exit latency and target residency of 200 us and 2 ms (which is greater
|
||||
than the tick period length), respectively.
|
||||
|
||||
Say that predicted_ns is equal to TICK_NSEC and the PM QoS latency
|
||||
limit is 20 us. After the first two iterations of the main loop in
|
||||
menu_select(), idx becomes 1 and in the third iteration of it the target
|
||||
residency of the current state (state 2) is greater than predicted_ns.
|
||||
State 2 is not a polling one and predicted_ns is not less than TICK_NSEC,
|
||||
so the check on whether or not the tick has been stopped is done. Say
|
||||
that the tick has been stopped already and there are no imminent timers
|
||||
(that is, delta_tick is greater than the target residency of state 2).
|
||||
In that case, idx becomes 2 and it is returned immediately, but the exit
|
||||
latency of state 2 exceeds the latency limit.
|
||||
|
||||
Address this issue by modifying the code to compare the exit latency of
|
||||
the current idle state (idle state i) with the latency limit before
|
||||
comparing its target residency with predicted_ns, which allows one
|
||||
more exit_latency_ns check that becomes redundant to be dropped.
|
||||
|
||||
However, after the above change, latency_req cannot take the predicted_ns
|
||||
value any more, which takes place after commit 38f83090f515 ("cpuidle:
|
||||
menu: Remove iowait influence"), because it may cause a polling state
|
||||
to be returned prematurely.
|
||||
|
||||
In the context of the previous example say that predicted_ns is 3000 and
|
||||
the PM QoS latency limit is still 20 us. Additionally, say that idle
|
||||
state 0 is a polling one. Moving the exit_latency_ns check before the
|
||||
target_residency_ns one causes the loop to terminate in the second
|
||||
iteration, before the target_residency_ns check, so idle state 0 will be
|
||||
returned even though previously state 1 would be returned if there were
|
||||
no imminent timers.
|
||||
|
||||
For this reason, remove the assignment of the predicted_ns value to
|
||||
latency_req from the code.
|
||||
|
||||
Fixes: 5ef499cd571c ("cpuidle: menu: Handle stopped tick more aggressively")
|
||||
Cc: 4.17+ <stable@vger.kernel.org> # 4.17+
|
||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Reviewed-by: Christian Loehle <christian.loehle@arm.com>
|
||||
Link: https://patch.msgid.link/5043159.31r3eYUQgx@rafael.j.wysocki
|
||||
---
|
||||
drivers/cpuidle/governors/menu.c | 29 ++++++++++++-----------------
|
||||
1 file changed, 12 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/cpuidle/governors/menu.c
|
||||
+++ b/drivers/cpuidle/governors/menu.c
|
||||
@@ -287,20 +287,15 @@ static int menu_select(struct cpuidle_dr
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (tick_nohz_tick_stopped()) {
|
||||
- /*
|
||||
- * If the tick is already stopped, the cost of possible short
|
||||
- * idle duration misprediction is much higher, because the CPU
|
||||
- * may be stuck in a shallow idle state for a long time as a
|
||||
- * result of it. In that case say we might mispredict and use
|
||||
- * the known time till the closest timer event for the idle
|
||||
- * state selection.
|
||||
- */
|
||||
- if (predicted_ns < TICK_NSEC)
|
||||
- predicted_ns = data->next_timer_ns;
|
||||
- } else if (latency_req > predicted_ns) {
|
||||
- latency_req = predicted_ns;
|
||||
- }
|
||||
+ /*
|
||||
+ * If the tick is already stopped, the cost of possible short idle
|
||||
+ * duration misprediction is much higher, because the CPU may be stuck
|
||||
+ * in a shallow idle state for a long time as a result of it. In that
|
||||
+ * case, say we might mispredict and use the known time till the closest
|
||||
+ * timer event for the idle state selection.
|
||||
+ */
|
||||
+ if (tick_nohz_tick_stopped() && predicted_ns < TICK_NSEC)
|
||||
+ predicted_ns = data->next_timer_ns;
|
||||
|
||||
/*
|
||||
* Find the idle state with the lowest power while satisfying
|
||||
@@ -316,13 +311,15 @@ static int menu_select(struct cpuidle_dr
|
||||
if (idx == -1)
|
||||
idx = i; /* first enabled state */
|
||||
|
||||
+ if (s->exit_latency_ns > latency_req)
|
||||
+ break;
|
||||
+
|
||||
if (s->target_residency_ns > predicted_ns) {
|
||||
/*
|
||||
* Use a physical idle state, not busy polling, unless
|
||||
* a timer is going to trigger soon enough.
|
||||
*/
|
||||
if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) &&
|
||||
- s->exit_latency_ns <= latency_req &&
|
||||
s->target_residency_ns <= data->next_timer_ns) {
|
||||
predicted_ns = s->target_residency_ns;
|
||||
idx = i;
|
||||
@@ -354,8 +351,6 @@ static int menu_select(struct cpuidle_dr
|
||||
|
||||
return idx;
|
||||
}
|
||||
- if (s->exit_latency_ns > latency_req)
|
||||
- break;
|
||||
|
||||
idx = i;
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
From 28803c739ac24f0b71167c2735fb35d04b19384a Mon Sep 17 00:00:00 2001
|
||||
From: Christoph Paasch <cpaasch@openai.com>
|
||||
Date: Fri, 15 Aug 2025 19:28:19 +0200
|
||||
Subject: mptcp: drop skb if MPTCP skb extension allocation fails
|
||||
|
||||
When skb_ext_add(skb, SKB_EXT_MPTCP) fails in mptcp_incoming_options(),
|
||||
we used to return true, letting the segment proceed through the TCP
|
||||
receive path without a DSS mapping. Such segments can leave inconsistent
|
||||
mapping state and trigger a mid-stream fallback to TCP, which in testing
|
||||
collapsed (by artificially forcing failures in skb_ext_add) throughput
|
||||
to zero.
|
||||
|
||||
Return false instead so the TCP input path drops the skb (see
|
||||
tcp_data_queue() and step-7 processing). This is the safer choice
|
||||
under memory pressure: it preserves MPTCP correctness and provides
|
||||
backpressure to the sender.
|
||||
|
||||
Control packets remain unaffected: ACK updates and DATA_FIN handling
|
||||
happen before attempting the extension allocation, and tcp_reset()
|
||||
continues to ignore the return value.
|
||||
|
||||
With this change, MPTCP continues to work at high throughput if we
|
||||
artificially inject failures into skb_ext_add.
|
||||
|
||||
Fixes: 6787b7e350d3 ("mptcp: avoid processing packet if a subflow reset")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Christoph Paasch <cpaasch@openai.com>
|
||||
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
|
||||
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
|
||||
Link: https://patch.msgid.link/20250815-net-mptcp-misc-fixes-6-17-rc2-v1-1-521fe9957892@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
net/mptcp/options.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/net/mptcp/options.c
|
||||
+++ b/net/mptcp/options.c
|
||||
@@ -1117,7 +1117,9 @@ static bool add_addr_hmac_valid(struct m
|
||||
return hmac == mp_opt->ahmac;
|
||||
}
|
||||
|
||||
-/* Return false if a subflow has been reset, else return true */
|
||||
+/* Return false in case of error (or subflow has been reset),
|
||||
+ * else return true.
|
||||
+ */
|
||||
bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
|
||||
@@ -1221,7 +1223,7 @@ bool mptcp_incoming_options(struct sock
|
||||
|
||||
mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
|
||||
if (!mpext)
|
||||
- return true;
|
||||
+ return false;
|
||||
|
||||
memset(mpext, 0, sizeof(*mpext));
|
||||
|
@@ -1,35 +0,0 @@
|
||||
From c4efb64dbe77b1db336896b9fd151d4f306cf521 Mon Sep 17 00:00:00 2001
|
||||
From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
|
||||
Date: Fri, 15 Aug 2025 19:28:20 +0200
|
||||
Subject: mptcp: pm: kernel: flush: do not reset ADD_ADDR limit
|
||||
|
||||
A flush of the MPTCP endpoints should not affect the MPTCP limits. In
|
||||
other words, 'ip mptcp endpoint flush' should not change 'ip mptcp
|
||||
limits'.
|
||||
|
||||
But it was the case: the MPTCP_PM_ATTR_RCV_ADD_ADDRS (add_addr_accepted)
|
||||
limit was reset by accident. Removing the reset of this counter during a
|
||||
flush fixes this issue.
|
||||
|
||||
Fixes: 01cacb00b35c ("mptcp: add netlink-based PM")
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Thomas Dreibholz <dreibh@simula.no>
|
||||
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/579
|
||||
Reviewed-by: Mat Martineau <martineau@kernel.org>
|
||||
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
|
||||
Link: https://patch.msgid.link/20250815-net-mptcp-misc-fixes-6-17-rc2-v1-2-521fe9957892@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
net/mptcp/pm_kernel.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/net/mptcp/pm_kernel.c
|
||||
+++ b/net/mptcp/pm_kernel.c
|
||||
@@ -1085,7 +1085,6 @@ static void __flush_addrs(struct list_he
|
||||
static void __reset_counters(struct pm_nl_pernet *pernet)
|
||||
{
|
||||
WRITE_ONCE(pernet->add_addr_signal_max, 0);
|
||||
- WRITE_ONCE(pernet->add_addr_accept_max, 0);
|
||||
WRITE_ONCE(pernet->local_addr_max, 0);
|
||||
pernet->addrs = 0;
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
From 135074416baed33c7e855827cf2d93d7fcb6d057 Mon Sep 17 00:00:00 2001
|
||||
From: Geliang Tang <tanggeliang@kylinos.cn>
|
||||
Date: Fri, 15 Aug 2025 19:28:22 +0200
|
||||
Subject: mptcp: remove duplicate sk_reset_timer call
|
||||
|
||||
sk_reset_timer() was called twice in mptcp_pm_alloc_anno_list.
|
||||
|
||||
Simplify the code by using a 'goto' statement to eliminate the
|
||||
duplication.
|
||||
|
||||
Note that this is not a fix, but it will help backporting the following
|
||||
patch. The same "Fixes" tag has been added for this reason.
|
||||
|
||||
Fixes: 93f323b9cccc ("mptcp: add a new sysctl add_addr_timeout")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
|
||||
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
|
||||
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
|
||||
Link: https://patch.msgid.link/20250815-net-mptcp-misc-fixes-6-17-rc2-v1-4-521fe9957892@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
net/mptcp/pm.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/net/mptcp/pm.c
|
||||
+++ b/net/mptcp/pm.c
|
||||
@@ -353,9 +353,7 @@ bool mptcp_pm_alloc_anno_list(struct mpt
|
||||
if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk)))
|
||||
return false;
|
||||
|
||||
- sk_reset_timer(sk, &add_entry->add_timer,
|
||||
- jiffies + mptcp_get_add_addr_timeout(net));
|
||||
- return true;
|
||||
+ goto reset_timer;
|
||||
}
|
||||
|
||||
add_entry = kmalloc(sizeof(*add_entry), GFP_ATOMIC);
|
||||
@@ -369,6 +367,7 @@ bool mptcp_pm_alloc_anno_list(struct mpt
|
||||
add_entry->retrans_times = 0;
|
||||
|
||||
timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
|
||||
+reset_timer:
|
||||
sk_reset_timer(sk, &add_entry->add_timer,
|
||||
jiffies + mptcp_get_add_addr_timeout(net));
|
||||
|
@@ -1,86 +0,0 @@
|
||||
From dda31fb26f0ac5d06db5d59daade7e9ced49667a Mon Sep 17 00:00:00 2001
|
||||
From: Geliang Tang <tanggeliang@kylinos.cn>
|
||||
Date: Fri, 15 Aug 2025 19:28:23 +0200
|
||||
Subject: mptcp: disable add_addr retransmission when timeout is 0
|
||||
|
||||
When add_addr_timeout was set to 0, this caused the ADD_ADDR to be
|
||||
retransmitted immediately, which looks like a buggy behaviour. Instead,
|
||||
interpret 0 as "no retransmissions needed".
|
||||
|
||||
The documentation is updated to explicitly state that setting the timeout
|
||||
to 0 disables retransmission.
|
||||
|
||||
Fixes: 93f323b9cccc ("mptcp: add a new sysctl add_addr_timeout")
|
||||
Cc: stable@vger.kernel.org
|
||||
Suggested-by: Matthieu Baerts <matttbe@kernel.org>
|
||||
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
|
||||
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
|
||||
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
|
||||
Link: https://patch.msgid.link/20250815-net-mptcp-misc-fixes-6-17-rc2-v1-5-521fe9957892@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
Documentation/networking/mptcp-sysctl.rst | 2 ++
|
||||
net/mptcp/pm.c | 13 ++++++++++---
|
||||
2 files changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/Documentation/networking/mptcp-sysctl.rst
|
||||
+++ b/Documentation/networking/mptcp-sysctl.rst
|
||||
@@ -12,6 +12,8 @@ add_addr_timeout - INTEGER (seconds)
|
||||
resent to an MPTCP peer that has not acknowledged a previous
|
||||
ADD_ADDR message.
|
||||
|
||||
+ Do not retransmit if set to 0.
|
||||
+
|
||||
The default value matches TCP_RTO_MAX. This is a per-namespace
|
||||
sysctl.
|
||||
|
||||
--- a/net/mptcp/pm.c
|
||||
+++ b/net/mptcp/pm.c
|
||||
@@ -274,6 +274,7 @@ static void mptcp_pm_add_timer(struct ti
|
||||
add_timer);
|
||||
struct mptcp_sock *msk = entry->sock;
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
+ unsigned int timeout;
|
||||
|
||||
pr_debug("msk=%p\n", msk);
|
||||
|
||||
@@ -291,6 +292,10 @@ static void mptcp_pm_add_timer(struct ti
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ timeout = mptcp_get_add_addr_timeout(sock_net(sk));
|
||||
+ if (!timeout)
|
||||
+ goto out;
|
||||
+
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
|
||||
if (!mptcp_pm_should_add_signal_addr(msk)) {
|
||||
@@ -302,7 +307,7 @@ static void mptcp_pm_add_timer(struct ti
|
||||
|
||||
if (entry->retrans_times < ADD_ADDR_RETRANS_MAX)
|
||||
sk_reset_timer(sk, timer,
|
||||
- jiffies + mptcp_get_add_addr_timeout(sock_net(sk)));
|
||||
+ jiffies + timeout);
|
||||
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
|
||||
@@ -344,6 +349,7 @@ bool mptcp_pm_alloc_anno_list(struct mpt
|
||||
struct mptcp_pm_add_entry *add_entry = NULL;
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
struct net *net = sock_net(sk);
|
||||
+ unsigned int timeout;
|
||||
|
||||
lockdep_assert_held(&msk->pm.lock);
|
||||
|
||||
@@ -368,8 +374,9 @@ bool mptcp_pm_alloc_anno_list(struct mpt
|
||||
|
||||
timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
|
||||
reset_timer:
|
||||
- sk_reset_timer(sk, &add_entry->add_timer,
|
||||
- jiffies + mptcp_get_add_addr_timeout(net));
|
||||
+ timeout = mptcp_get_add_addr_timeout(net);
|
||||
+ if (timeout)
|
||||
+ sk_reset_timer(sk, &add_entry->add_timer, jiffies + timeout);
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,217 +0,0 @@
|
||||
From 593c5009d3316e756dc882364ac67a78b39332ae Mon Sep 17 00:00:00 2001
|
||||
From: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
|
||||
Date: Tue, 19 Aug 2025 15:58:43 +0300
|
||||
Subject: usb: xhci: Fix slot_id resource race conflict
|
||||
|
||||
xHC controller may immediately reuse a slot_id after it's disabled,
|
||||
giving it to a new enumerating device before the xhci driver freed
|
||||
all resources related to the disabled device.
|
||||
|
||||
In such a scenario, device-A with slot_id equal to 1 is disconnecting
|
||||
while device-B is enumerating, device-B will fail to enumerate in the
|
||||
follow sequence.
|
||||
|
||||
1.[device-A] send disable slot command
|
||||
2.[device-B] send enable slot command
|
||||
3.[device-A] disable slot command completed and wakeup waiting thread
|
||||
4.[device-B] enable slot command completed with slot_id equal to 1 and
|
||||
wakeup waiting thread
|
||||
5.[device-B] driver checks that slot_id is still in use (by device-A) in
|
||||
xhci_alloc_virt_device, and fail to enumerate due to this
|
||||
conflict
|
||||
6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device
|
||||
|
||||
To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and
|
||||
xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context
|
||||
when disable slot command completes successfully. Simultaneously, adjust
|
||||
function xhci_free_virt_device to accurately handle device release.
|
||||
|
||||
[minor smatch warning and commit message fix -Mathias]
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend")
|
||||
Signed-off-by: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
|
||||
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/xhci-hub.c | 3 +--
|
||||
drivers/usb/host/xhci-mem.c | 22 +++++++++++-----------
|
||||
drivers/usb/host/xhci-ring.c | 9 +++++++--
|
||||
drivers/usb/host/xhci.c | 21 ++++++++++++++-------
|
||||
drivers/usb/host/xhci.h | 3 ++-
|
||||
5 files changed, 35 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/xhci-hub.c
|
||||
+++ b/drivers/usb/host/xhci-hub.c
|
||||
@@ -704,8 +704,7 @@ static int xhci_enter_test_mode(struct x
|
||||
if (!xhci->devs[i])
|
||||
continue;
|
||||
|
||||
- retval = xhci_disable_slot(xhci, i);
|
||||
- xhci_free_virt_device(xhci, i);
|
||||
+ retval = xhci_disable_and_free_slot(xhci, i);
|
||||
if (retval)
|
||||
xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n",
|
||||
i, retval);
|
||||
--- a/drivers/usb/host/xhci-mem.c
|
||||
+++ b/drivers/usb/host/xhci-mem.c
|
||||
@@ -865,21 +865,20 @@ free_tts:
|
||||
* will be manipulated by the configure endpoint, allocate device, or update
|
||||
* hub functions while this function is removing the TT entries from the list.
|
||||
*/
|
||||
-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
|
||||
+void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
|
||||
+ int slot_id)
|
||||
{
|
||||
- struct xhci_virt_device *dev;
|
||||
int i;
|
||||
int old_active_eps = 0;
|
||||
|
||||
/* Slot ID 0 is reserved */
|
||||
- if (slot_id == 0 || !xhci->devs[slot_id])
|
||||
+ if (slot_id == 0 || !dev)
|
||||
return;
|
||||
|
||||
- dev = xhci->devs[slot_id];
|
||||
-
|
||||
- xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
|
||||
- if (!dev)
|
||||
- return;
|
||||
+ /* If device ctx array still points to _this_ device, clear it */
|
||||
+ if (dev->out_ctx &&
|
||||
+ xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma))
|
||||
+ xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
|
||||
|
||||
trace_xhci_free_virt_device(dev);
|
||||
|
||||
@@ -920,8 +919,9 @@ void xhci_free_virt_device(struct xhci_h
|
||||
dev->udev->slot_id = 0;
|
||||
if (dev->rhub_port && dev->rhub_port->slot_id == slot_id)
|
||||
dev->rhub_port->slot_id = 0;
|
||||
- kfree(xhci->devs[slot_id]);
|
||||
- xhci->devs[slot_id] = NULL;
|
||||
+ if (xhci->devs[slot_id] == dev)
|
||||
+ xhci->devs[slot_id] = NULL;
|
||||
+ kfree(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -962,7 +962,7 @@ static void xhci_free_virt_devices_depth
|
||||
out:
|
||||
/* we are now at a leaf device */
|
||||
xhci_debugfs_remove_slot(xhci, slot_id);
|
||||
- xhci_free_virt_device(xhci, slot_id);
|
||||
+ xhci_free_virt_device(xhci, vdev, slot_id);
|
||||
}
|
||||
|
||||
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
|
||||
--- a/drivers/usb/host/xhci-ring.c
|
||||
+++ b/drivers/usb/host/xhci-ring.c
|
||||
@@ -1592,7 +1592,8 @@ static void xhci_handle_cmd_enable_slot(
|
||||
command->slot_id = 0;
|
||||
}
|
||||
|
||||
-static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
|
||||
+static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id,
|
||||
+ u32 cmd_comp_code)
|
||||
{
|
||||
struct xhci_virt_device *virt_dev;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
@@ -1607,6 +1608,10 @@ static void xhci_handle_cmd_disable_slot
|
||||
if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
|
||||
/* Delete default control endpoint resources */
|
||||
xhci_free_device_endpoint_resources(xhci, virt_dev, true);
|
||||
+ if (cmd_comp_code == COMP_SUCCESS) {
|
||||
+ xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
|
||||
+ xhci->devs[slot_id] = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id)
|
||||
@@ -1856,7 +1861,7 @@ static void handle_cmd_completion(struct
|
||||
xhci_handle_cmd_enable_slot(slot_id, cmd, cmd_comp_code);
|
||||
break;
|
||||
case TRB_DISABLE_SLOT:
|
||||
- xhci_handle_cmd_disable_slot(xhci, slot_id);
|
||||
+ xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code);
|
||||
break;
|
||||
case TRB_CONFIG_EP:
|
||||
if (!cmd->completion)
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -3932,8 +3932,7 @@ static int xhci_discover_or_reset_device
|
||||
* Obtaining a new device slot to inform the xHCI host that
|
||||
* the USB device has been reset.
|
||||
*/
|
||||
- ret = xhci_disable_slot(xhci, udev->slot_id);
|
||||
- xhci_free_virt_device(xhci, udev->slot_id);
|
||||
+ ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
|
||||
if (!ret) {
|
||||
ret = xhci_alloc_dev(hcd, udev);
|
||||
if (ret == 1)
|
||||
@@ -4090,7 +4089,7 @@ static void xhci_free_dev(struct usb_hcd
|
||||
xhci_disable_slot(xhci, udev->slot_id);
|
||||
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
- xhci_free_virt_device(xhci, udev->slot_id);
|
||||
+ xhci_free_virt_device(xhci, virt_dev, udev->slot_id);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
|
||||
}
|
||||
@@ -4139,6 +4138,16 @@ int xhci_disable_slot(struct xhci_hcd *x
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id)
|
||||
+{
|
||||
+ struct xhci_virt_device *vdev = xhci->devs[slot_id];
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = xhci_disable_slot(xhci, slot_id);
|
||||
+ xhci_free_virt_device(xhci, vdev, slot_id);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Checks if we have enough host controller resources for the default control
|
||||
* endpoint.
|
||||
@@ -4245,8 +4254,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd,
|
||||
return 1;
|
||||
|
||||
disable_slot:
|
||||
- xhci_disable_slot(xhci, udev->slot_id);
|
||||
- xhci_free_virt_device(xhci, udev->slot_id);
|
||||
+ xhci_disable_and_free_slot(xhci, udev->slot_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4382,8 +4390,7 @@ static int xhci_setup_device(struct usb_
|
||||
dev_warn(&udev->dev, "Device not responding to setup %s.\n", act);
|
||||
|
||||
mutex_unlock(&xhci->mutex);
|
||||
- ret = xhci_disable_slot(xhci, udev->slot_id);
|
||||
- xhci_free_virt_device(xhci, udev->slot_id);
|
||||
+ ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
|
||||
if (!ret) {
|
||||
if (xhci_alloc_dev(hcd, udev) == 1)
|
||||
xhci_setup_addressable_virt_dev(xhci, udev);
|
||||
--- a/drivers/usb/host/xhci.h
|
||||
+++ b/drivers/usb/host/xhci.h
|
||||
@@ -1791,7 +1791,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhc
|
||||
/* xHCI memory management */
|
||||
void xhci_mem_cleanup(struct xhci_hcd *xhci);
|
||||
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags);
|
||||
-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id);
|
||||
+void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id);
|
||||
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags);
|
||||
int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
|
||||
void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
|
||||
@@ -1888,6 +1888,7 @@ void xhci_reset_bandwidth(struct usb_hcd
|
||||
int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
|
||||
struct usb_tt *tt, gfp_t mem_flags);
|
||||
int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
|
||||
+int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id);
|
||||
int xhci_ext_cap_init(struct xhci_hcd *xhci);
|
||||
|
||||
int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);
|
@@ -1,48 +0,0 @@
|
||||
From af9d38028438d5893403b1bea8bd493186f8d2b7 Mon Sep 17 00:00:00 2001
|
||||
From: Niklas Neronin <niklas.neronin@linux.intel.com>
|
||||
Date: Tue, 19 Aug 2025 15:58:44 +0300
|
||||
Subject: usb: xhci: fix host not responding after suspend and resume
|
||||
|
||||
Partially revert commit e1db856bd288 ("usb: xhci: remove '0' write to
|
||||
write-1-to-clear register") because the patch cleared the Interrupt Pending
|
||||
bit during interrupt enabling and disabling. The Interrupt Pending bit
|
||||
should only be cleared when the driver has handled the interrupt.
|
||||
|
||||
Ideally, all interrupts should be handled before disabling the interrupt;
|
||||
consequently, no interrupt should be pending when enabling the interrupt.
|
||||
For this reason, keep the debug message informing if an interrupt is still
|
||||
pending when an interrupt is disabled.
|
||||
|
||||
Because the Interrupt Pending bit is write-1-to-clear, writing '0' to it
|
||||
ensures that the state does not change.
|
||||
|
||||
Link: https://lore.kernel.org/linux-usb/20250818231103.672ec7ed@foxbook
|
||||
Fixes: e1db856bd288 ("usb: xhci: remove '0' write to write-1-to-clear register")
|
||||
Closes: https://bbs.archlinux.org/viewtopic.php?id=307641
|
||||
cc: stable@vger.kernel.org # 6.16+
|
||||
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
|
||||
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Link: https://lore.kernel.org/r/20250819125844.2042452-3-mathias.nyman@linux.intel.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/xhci.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -309,6 +309,7 @@ int xhci_enable_interrupter(struct xhci_
|
||||
return -EINVAL;
|
||||
|
||||
iman = readl(&ir->ir_set->iman);
|
||||
+ iman &= ~IMAN_IP;
|
||||
iman |= IMAN_IE;
|
||||
writel(iman, &ir->ir_set->iman);
|
||||
|
||||
@@ -325,6 +326,7 @@ int xhci_disable_interrupter(struct xhci
|
||||
return -EINVAL;
|
||||
|
||||
iman = readl(&ir->ir_set->iman);
|
||||
+ iman &= ~IMAN_IP;
|
||||
iman &= ~IMAN_IE;
|
||||
writel(iman, &ir->ir_set->iman);
|
||||
|
@@ -1,128 +0,0 @@
|
||||
From 89a721716c46752ff3a1e6b4005130aeb22c107e Mon Sep 17 00:00:00 2001
|
||||
From: Trond Myklebust <trond.myklebust@hammerspace.com>
|
||||
Date: Sat, 16 Aug 2025 07:25:20 -0700
|
||||
Subject: NFS: Fix a race when updating an existing write
|
||||
|
||||
After nfs_lock_and_join_requests() tests for whether the request is
|
||||
still attached to the mapping, nothing prevents a call to
|
||||
nfs_inode_remove_request() from succeeding until we actually lock the
|
||||
page group.
|
||||
The reason is that whoever called nfs_inode_remove_request() doesn't
|
||||
necessarily have a lock on the page group head.
|
||||
|
||||
So in order to avoid races, let's take the page group lock earlier in
|
||||
nfs_lock_and_join_requests(), and hold it across the removal of the
|
||||
request in nfs_inode_remove_request().
|
||||
|
||||
Reported-by: Jeff Layton <jlayton@kernel.org>
|
||||
Tested-by: Joe Quanaim <jdq@meta.com>
|
||||
Tested-by: Andrew Steffen <aksteffen@meta.com>
|
||||
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
||||
Fixes: bd37d6fce184 ("NFSv4: Convert nfs_lock_and_join_requests() to use nfs_page_find_head_request()")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
|
||||
---
|
||||
fs/nfs/pagelist.c | 9 +++++----
|
||||
fs/nfs/write.c | 29 ++++++++++-------------------
|
||||
include/linux/nfs_page.h | 1 +
|
||||
3 files changed, 16 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/fs/nfs/pagelist.c
|
||||
+++ b/fs/nfs/pagelist.c
|
||||
@@ -253,13 +253,14 @@ nfs_page_group_unlock(struct nfs_page *r
|
||||
nfs_page_clear_headlock(req);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * nfs_page_group_sync_on_bit_locked
|
||||
+/**
|
||||
+ * nfs_page_group_sync_on_bit_locked - Test if all requests have @bit set
|
||||
+ * @req: request in page group
|
||||
+ * @bit: PG_* bit that is used to sync page group
|
||||
*
|
||||
* must be called with page group lock held
|
||||
*/
|
||||
-static bool
|
||||
-nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit)
|
||||
+bool nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit)
|
||||
{
|
||||
struct nfs_page *head = req->wb_head;
|
||||
struct nfs_page *tmp;
|
||||
--- a/fs/nfs/write.c
|
||||
+++ b/fs/nfs/write.c
|
||||
@@ -153,20 +153,10 @@ nfs_page_set_inode_ref(struct nfs_page *
|
||||
}
|
||||
}
|
||||
|
||||
-static int
|
||||
-nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode)
|
||||
+static void nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode)
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- if (!test_bit(PG_REMOVE, &req->wb_flags))
|
||||
- return 0;
|
||||
- ret = nfs_page_group_lock(req);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
if (test_and_clear_bit(PG_REMOVE, &req->wb_flags))
|
||||
nfs_page_set_inode_ref(req, inode);
|
||||
- nfs_page_group_unlock(req);
|
||||
- return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -585,19 +575,18 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
+ ret = nfs_page_group_lock(head);
|
||||
+ if (ret < 0)
|
||||
+ goto out_unlock;
|
||||
+
|
||||
/* Ensure that nobody removed the request before we locked it */
|
||||
if (head != folio->private) {
|
||||
+ nfs_page_group_unlock(head);
|
||||
nfs_unlock_and_release_request(head);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
- ret = nfs_cancel_remove_inode(head, inode);
|
||||
- if (ret < 0)
|
||||
- goto out_unlock;
|
||||
-
|
||||
- ret = nfs_page_group_lock(head);
|
||||
- if (ret < 0)
|
||||
- goto out_unlock;
|
||||
+ nfs_cancel_remove_inode(head, inode);
|
||||
|
||||
/* lock each request in the page group */
|
||||
for (subreq = head->wb_this_page;
|
||||
@@ -786,7 +775,8 @@ static void nfs_inode_remove_request(str
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req));
|
||||
|
||||
- if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) {
|
||||
+ nfs_page_group_lock(req);
|
||||
+ if (nfs_page_group_sync_on_bit_locked(req, PG_REMOVE)) {
|
||||
struct folio *folio = nfs_page_to_folio(req->wb_head);
|
||||
struct address_space *mapping = folio->mapping;
|
||||
|
||||
@@ -798,6 +788,7 @@ static void nfs_inode_remove_request(str
|
||||
}
|
||||
spin_unlock(&mapping->i_private_lock);
|
||||
}
|
||||
+ nfs_page_group_unlock(req);
|
||||
|
||||
if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) {
|
||||
atomic_long_dec(&nfsi->nrequests);
|
||||
--- a/include/linux/nfs_page.h
|
||||
+++ b/include/linux/nfs_page.h
|
||||
@@ -160,6 +160,7 @@ extern void nfs_join_page_group(struct n
|
||||
extern int nfs_page_group_lock(struct nfs_page *);
|
||||
extern void nfs_page_group_unlock(struct nfs_page *);
|
||||
extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
|
||||
+extern bool nfs_page_group_sync_on_bit_locked(struct nfs_page *, unsigned int);
|
||||
extern int nfs_page_set_headlock(struct nfs_page *req);
|
||||
extern void nfs_page_clear_headlock(struct nfs_page *req);
|
||||
extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
|
@@ -1,102 +0,0 @@
|
||||
From cb937c419cee16eb53a09e3c8cc16b675db0214f Mon Sep 17 00:00:00 2001
|
||||
From: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
Date: Fri, 8 Aug 2025 20:18:02 +0000
|
||||
Subject: kho: init new_physxa->phys_bits to fix lockdep
|
||||
|
||||
Patch series "Several KHO Hotfixes".
|
||||
|
||||
Three unrelated fixes for Kexec Handover.
|
||||
|
||||
|
||||
This patch (of 3):
|
||||
|
||||
Lockdep shows the following warning:
|
||||
|
||||
INFO: trying to register non-static key. The code is fine but needs
|
||||
lockdep annotation, or maybe you didn't initialize this object before use?
|
||||
turning off the locking correctness validator.
|
||||
|
||||
[<ffffffff810133a6>] dump_stack_lvl+0x66/0xa0
|
||||
[<ffffffff8136012c>] assign_lock_key+0x10c/0x120
|
||||
[<ffffffff81358bb4>] register_lock_class+0xf4/0x2f0
|
||||
[<ffffffff813597ff>] __lock_acquire+0x7f/0x2c40
|
||||
[<ffffffff81360cb0>] ? __pfx_hlock_conflict+0x10/0x10
|
||||
[<ffffffff811707be>] ? native_flush_tlb_global+0x8e/0xa0
|
||||
[<ffffffff8117096e>] ? __flush_tlb_all+0x4e/0xa0
|
||||
[<ffffffff81172fc2>] ? __kernel_map_pages+0x112/0x140
|
||||
[<ffffffff813ec327>] ? xa_load_or_alloc+0x67/0xe0
|
||||
[<ffffffff81359556>] lock_acquire+0xe6/0x280
|
||||
[<ffffffff813ec327>] ? xa_load_or_alloc+0x67/0xe0
|
||||
[<ffffffff8100b9e0>] _raw_spin_lock+0x30/0x40
|
||||
[<ffffffff813ec327>] ? xa_load_or_alloc+0x67/0xe0
|
||||
[<ffffffff813ec327>] xa_load_or_alloc+0x67/0xe0
|
||||
[<ffffffff813eb4c0>] kho_preserve_folio+0x90/0x100
|
||||
[<ffffffff813ebb7f>] __kho_finalize+0xcf/0x400
|
||||
[<ffffffff813ebef4>] kho_finalize+0x34/0x70
|
||||
|
||||
This is becase xa has its own lock, that is not initialized in
|
||||
xa_load_or_alloc.
|
||||
|
||||
Modifiy __kho_preserve_order(), to properly call
|
||||
xa_init(&new_physxa->phys_bits);
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250808201804.772010-2-pasha.tatashin@soleen.com
|
||||
Fixes: fc33e4b44b27 ("kexec: enable KHO support for memory preservation")
|
||||
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
|
||||
Cc: Alexander Graf <graf@amazon.com>
|
||||
Cc: Arnd Bergmann <arnd@arndb.de>
|
||||
Cc: Baoquan He <bhe@redhat.com>
|
||||
Cc: Changyuan Lyu <changyuanl@google.com>
|
||||
Cc: Coiby Xu <coxu@redhat.com>
|
||||
Cc: Dave Vasilevsky <dave@vasilevsky.ca>
|
||||
Cc: Eric Biggers <ebiggers@google.com>
|
||||
Cc: Kees Cook <kees@kernel.org>
|
||||
Cc: Pratyush Yadav <pratyush@kernel.org>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
kernel/kexec_handover.c | 28 ++++++++++++++++++++++++----
|
||||
1 file changed, 24 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/kernel/kexec_handover.c
|
||||
+++ b/kernel/kexec_handover.c
|
||||
@@ -144,14 +144,34 @@ static int __kho_preserve_order(struct k
|
||||
unsigned int order)
|
||||
{
|
||||
struct kho_mem_phys_bits *bits;
|
||||
- struct kho_mem_phys *physxa;
|
||||
+ struct kho_mem_phys *physxa, *new_physxa;
|
||||
const unsigned long pfn_high = pfn >> order;
|
||||
|
||||
might_sleep();
|
||||
|
||||
- physxa = xa_load_or_alloc(&track->orders, order, sizeof(*physxa));
|
||||
- if (IS_ERR(physxa))
|
||||
- return PTR_ERR(physxa);
|
||||
+ physxa = xa_load(&track->orders, order);
|
||||
+ if (!physxa) {
|
||||
+ int err;
|
||||
+
|
||||
+ new_physxa = kzalloc(sizeof(*physxa), GFP_KERNEL);
|
||||
+ if (!new_physxa)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ xa_init(&new_physxa->phys_bits);
|
||||
+ physxa = xa_cmpxchg(&track->orders, order, NULL, new_physxa,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ err = xa_err(physxa);
|
||||
+ if (err || physxa) {
|
||||
+ xa_destroy(&new_physxa->phys_bits);
|
||||
+ kfree(new_physxa);
|
||||
+
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ } else {
|
||||
+ physxa = new_physxa;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
bits = xa_load_or_alloc(&physxa->phys_bits, pfn_high / PRESERVE_BITS,
|
||||
sizeof(*bits));
|
@@ -1,44 +0,0 @@
|
||||
From 8f64c65c577701d4f11d4aa6b487126d52a471c5 Mon Sep 17 00:00:00 2001
|
||||
From: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
Date: Fri, 8 Aug 2025 20:18:03 +0000
|
||||
Subject: kho: mm: don't allow deferred struct page with KHO
|
||||
|
||||
KHO uses struct pages for the preserved memory early in boot, however,
|
||||
with deferred struct page initialization, only a small portion of memory
|
||||
has properly initialized struct pages.
|
||||
|
||||
This problem was detected where vmemmap is poisoned, and illegal flag
|
||||
combinations are detected.
|
||||
|
||||
Don't allow them to be enabled together, and later we will have to teach
|
||||
KHO to work properly with deferred struct page init kernel feature.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250808201804.772010-3-pasha.tatashin@soleen.com
|
||||
Fixes: 4e1d010e3bda ("kexec: add config option for KHO")
|
||||
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
|
||||
Acked-by: Pratyush Yadav <pratyush@kernel.org>
|
||||
Cc: Alexander Graf <graf@amazon.com>
|
||||
Cc: Arnd Bergmann <arnd@arndb.de>
|
||||
Cc: Baoquan He <bhe@redhat.com>
|
||||
Cc: Changyuan Lyu <changyuanl@google.com>
|
||||
Cc: Coiby Xu <coxu@redhat.com>
|
||||
Cc: Dave Vasilevsky <dave@vasilevsky.ca>
|
||||
Cc: Eric Biggers <ebiggers@google.com>
|
||||
Cc: Kees Cook <kees@kernel.org>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
kernel/Kconfig.kexec | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/kernel/Kconfig.kexec
|
||||
+++ b/kernel/Kconfig.kexec
|
||||
@@ -97,6 +97,7 @@ config KEXEC_JUMP
|
||||
config KEXEC_HANDOVER
|
||||
bool "kexec handover"
|
||||
depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE
|
||||
+ depends on !DEFERRED_STRUCT_PAGE_INIT
|
||||
select MEMBLOCK_KHO_SCRATCH
|
||||
select KEXEC_FILE
|
||||
select DEBUG_FS
|
@@ -1,39 +0,0 @@
|
||||
From b784ab2867996b84098abc798052aa503d981745 Mon Sep 17 00:00:00 2001
|
||||
From: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
Date: Fri, 8 Aug 2025 20:18:04 +0000
|
||||
Subject: kho: warn if KHO is disabled due to an error
|
||||
|
||||
During boot scratch area is allocated based on command line parameters or
|
||||
auto calculated. However, scratch area may fail to allocate, and in that
|
||||
case KHO is disabled. Currently, no warning is printed that KHO is
|
||||
disabled, which makes it confusing for the end user to figure out why KHO
|
||||
is not available. Add the missing warning message.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250808201804.772010-4-pasha.tatashin@soleen.com
|
||||
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
|
||||
Acked-by: Pratyush Yadav <pratyush@kernel.org>
|
||||
Cc: Alexander Graf <graf@amazon.com>
|
||||
Cc: Arnd Bergmann <arnd@arndb.de>
|
||||
Cc: Baoquan He <bhe@redhat.com>
|
||||
Cc: Changyuan Lyu <changyuanl@google.com>
|
||||
Cc: Coiby Xu <coxu@redhat.com>
|
||||
Cc: Dave Vasilevsky <dave@vasilevsky.ca>
|
||||
Cc: Eric Biggers <ebiggers@google.com>
|
||||
Cc: Kees Cook <kees@kernel.org>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
kernel/kexec_handover.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/kernel/kexec_handover.c
|
||||
+++ b/kernel/kexec_handover.c
|
||||
@@ -564,6 +564,7 @@ err_free_scratch_areas:
|
||||
err_free_scratch_desc:
|
||||
memblock_free(kho_scratch, kho_scratch_cnt * sizeof(*kho_scratch));
|
||||
err_disable_kho:
|
||||
+ pr_warn("Failed to reserve scratch area, disabling kexec handover\n");
|
||||
kho_enable = false;
|
||||
}
|
||||
|
@@ -1,55 +0,0 @@
|
||||
From ef787512b2a3a79de6aac63c9b715cd8791594e5 Mon Sep 17 00:00:00 2001
|
||||
From: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
Date: Mon, 11 Aug 2025 23:37:40 +0100
|
||||
Subject: squashfs: fix memory leak in squashfs_fill_super
|
||||
|
||||
If sb_min_blocksize returns 0, squashfs_fill_super exits without freeing
|
||||
allocated memory (sb->s_fs_info).
|
||||
|
||||
Fix this by moving the call to sb_min_blocksize to before memory is
|
||||
allocated.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250811223740.110392-1-phillip@squashfs.org.uk
|
||||
Fixes: 734aa85390ea ("Squashfs: check return result of sb_min_blocksize")
|
||||
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
Reported-by: Scott GUO <scottzhguo@tencent.com>
|
||||
Closes: https://lore.kernel.org/all/20250811061921.3807353-1-scott_gzh@163.com
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
fs/squashfs/super.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/fs/squashfs/super.c
|
||||
+++ b/fs/squashfs/super.c
|
||||
@@ -187,10 +187,15 @@ static int squashfs_fill_super(struct su
|
||||
unsigned short flags;
|
||||
unsigned int fragments;
|
||||
u64 lookup_table_start, xattr_id_table_start, next_table;
|
||||
- int err;
|
||||
+ int err, devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
|
||||
|
||||
TRACE("Entered squashfs_fill_superblock\n");
|
||||
|
||||
+ if (!devblksize) {
|
||||
+ errorf(fc, "squashfs: unable to set blocksize\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL);
|
||||
if (sb->s_fs_info == NULL) {
|
||||
ERROR("Failed to allocate squashfs_sb_info\n");
|
||||
@@ -201,12 +206,7 @@ static int squashfs_fill_super(struct su
|
||||
|
||||
msblk->panic_on_errors = (opts->errors == Opt_errors_panic);
|
||||
|
||||
- msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
|
||||
- if (!msblk->devblksize) {
|
||||
- errorf(fc, "squashfs: unable to set blocksize\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
+ msblk->devblksize = devblksize;
|
||||
msblk->devblksize_log2 = ffz(~msblk->devblksize);
|
||||
|
||||
mutex_init(&msblk->meta_index_mutex);
|
@@ -1,140 +0,0 @@
|
||||
From 94ccad3e78c9f1a90526b8ca4301d5e5c2df0f88 Mon Sep 17 00:00:00 2001
|
||||
From: "Herton R. Krzesinski" <herton@redhat.com>
|
||||
Date: Thu, 31 Jul 2025 18:40:51 -0300
|
||||
Subject: mm/debug_vm_pgtable: clear page table entries at destroy_args()
|
||||
|
||||
The mm/debug_vm_pagetable test allocates manually page table entries for
|
||||
the tests it runs, using also its manually allocated mm_struct. That in
|
||||
itself is ok, but when it exits, at destroy_args() it fails to clear those
|
||||
entries with the *_clear functions.
|
||||
|
||||
The problem is that leaves stale entries. If another process allocates an
|
||||
mm_struct with a pgd at the same address, it may end up running into the
|
||||
stale entry. This is happening in practice on a debug kernel with
|
||||
CONFIG_DEBUG_VM_PGTABLE=y, for example this is the output with some extra
|
||||
debugging I added (it prints a warning trace if pgtables_bytes goes
|
||||
negative, in addition to the warning at check_mm() function):
|
||||
|
||||
[ 2.539353] debug_vm_pgtable: [get_random_vaddr ]: random_vaddr is 0x7ea247140000
|
||||
[ 2.539366] kmem_cache info
|
||||
[ 2.539374] kmem_cachep 0x000000002ce82385 - freelist 0x0000000000000000 - offset 0x508
|
||||
[ 2.539447] debug_vm_pgtable: [init_args ]: args->mm is 0x000000002267cc9e
|
||||
(...)
|
||||
[ 2.552800] WARNING: CPU: 5 PID: 116 at include/linux/mm.h:2841 free_pud_range+0x8bc/0x8d0
|
||||
[ 2.552816] Modules linked in:
|
||||
[ 2.552843] CPU: 5 UID: 0 PID: 116 Comm: modprobe Not tainted 6.12.0-105.debug_vm2.el10.ppc64le+debug #1 VOLUNTARY
|
||||
[ 2.552859] Hardware name: IBM,9009-41A POWER9 (architected) 0x4e0202 0xf000005 of:IBM,FW910.00 (VL910_062) hv:phyp pSeries
|
||||
[ 2.552872] NIP: c0000000007eef3c LR: c0000000007eef30 CTR: c0000000003d8c90
|
||||
[ 2.552885] REGS: c0000000622e73b0 TRAP: 0700 Not tainted (6.12.0-105.debug_vm2.el10.ppc64le+debug)
|
||||
[ 2.552899] MSR: 800000000282b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 24002822 XER: 0000000a
|
||||
[ 2.552954] CFAR: c0000000008f03f0 IRQMASK: 0
|
||||
[ 2.552954] GPR00: c0000000007eef30 c0000000622e7650 c000000002b1ac00 0000000000000001
|
||||
[ 2.552954] GPR04: 0000000000000008 0000000000000000 c0000000007eef30 ffffffffffffffff
|
||||
[ 2.552954] GPR08: 00000000ffff00f5 0000000000000001 0000000000000048 0000000000004000
|
||||
[ 2.552954] GPR12: 00000003fa440000 c000000017ffa300 c0000000051d9f80 ffffffffffffffdb
|
||||
[ 2.552954] GPR16: 0000000000000000 0000000000000008 000000000000000a 60000000000000e0
|
||||
[ 2.552954] GPR20: 4080000000000000 c0000000113af038 00007fffcf130000 0000700000000000
|
||||
[ 2.552954] GPR24: c000000062a6a000 0000000000000001 8000000062a68000 0000000000000001
|
||||
[ 2.552954] GPR28: 000000000000000a c000000062ebc600 0000000000002000 c000000062ebc760
|
||||
[ 2.553170] NIP [c0000000007eef3c] free_pud_range+0x8bc/0x8d0
|
||||
[ 2.553185] LR [c0000000007eef30] free_pud_range+0x8b0/0x8d0
|
||||
[ 2.553199] Call Trace:
|
||||
[ 2.553207] [c0000000622e7650] [c0000000007eef30] free_pud_range+0x8b0/0x8d0 (unreliable)
|
||||
[ 2.553229] [c0000000622e7750] [c0000000007f40b4] free_pgd_range+0x284/0x3b0
|
||||
[ 2.553248] [c0000000622e7800] [c0000000007f4630] free_pgtables+0x450/0x570
|
||||
[ 2.553274] [c0000000622e78e0] [c0000000008161c0] exit_mmap+0x250/0x650
|
||||
[ 2.553292] [c0000000622e7a30] [c0000000001b95b8] __mmput+0x98/0x290
|
||||
[ 2.558344] [c0000000622e7a80] [c0000000001d1018] exit_mm+0x118/0x1b0
|
||||
[ 2.558361] [c0000000622e7ac0] [c0000000001d141c] do_exit+0x2ec/0x870
|
||||
[ 2.558376] [c0000000622e7b60] [c0000000001d1ca8] do_group_exit+0x88/0x150
|
||||
[ 2.558391] [c0000000622e7bb0] [c0000000001d1db8] sys_exit_group+0x48/0x50
|
||||
[ 2.558407] [c0000000622e7be0] [c00000000003d810] system_call_exception+0x1e0/0x4c0
|
||||
[ 2.558423] [c0000000622e7e50] [c00000000000d05c] system_call_vectored_common+0x15c/0x2ec
|
||||
(...)
|
||||
[ 2.558892] ---[ end trace 0000000000000000 ]---
|
||||
[ 2.559022] BUG: Bad rss-counter state mm:000000002267cc9e type:MM_ANONPAGES val:1
|
||||
[ 2.559037] BUG: non-zero pgtables_bytes on freeing mm: -6144
|
||||
|
||||
Here the modprobe process ended up with an allocated mm_struct from the
|
||||
mm_struct slab that was used before by the debug_vm_pgtable test. That is
|
||||
not a problem, since the mm_struct is initialized again etc., however, if
|
||||
it ends up using the same pgd table, it bumps into the old stale entry
|
||||
when clearing/freeing the page table entries, so it tries to free an entry
|
||||
already gone (that one which was allocated by the debug_vm_pgtable test),
|
||||
which also explains the negative pgtables_bytes since it's accounting for
|
||||
not allocated entries in the current process.
|
||||
|
||||
As far as I looked pgd_{alloc,free} etc. does not clear entries, and
|
||||
clearing of the entries is explicitly done in the free_pgtables->
|
||||
free_pgd_range->free_p4d_range->free_pud_range->free_pmd_range->
|
||||
free_pte_range path. However, the debug_vm_pgtable test does not call
|
||||
free_pgtables, since it allocates mm_struct and entries manually for its
|
||||
test and eg. not goes through page faults. So it also should clear
|
||||
manually the entries before exit at destroy_args().
|
||||
|
||||
This problem was noticed on a reboot X number of times test being done on
|
||||
a powerpc host, with a debug kernel with CONFIG_DEBUG_VM_PGTABLE enabled.
|
||||
Depends on the system, but on a 100 times reboot loop the problem could
|
||||
manifest once or twice, if a process ends up getting the right mm->pgd
|
||||
entry with the stale entries used by mm/debug_vm_pagetable. After using
|
||||
this patch, I couldn't reproduce/experience the problems anymore. I was
|
||||
able to reproduce the problem as well on latest upstream kernel (6.16).
|
||||
|
||||
I also modified destroy_args() to use mmput() instead of mmdrop(), there
|
||||
is no reason to hold mm_users reference and not release the mm_struct
|
||||
entirely, and in the output above with my debugging prints I already had
|
||||
patched it to use mmput, it did not fix the problem, but helped in the
|
||||
debugging as well.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250731214051.4115182-1-herton@redhat.com
|
||||
Fixes: 3c9b84f044a9 ("mm/debug_vm_pgtable: introduce struct pgtable_debug_args")
|
||||
Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
|
||||
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Gavin Shan <gshan@redhat.com>
|
||||
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/debug_vm_pgtable.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/mm/debug_vm_pgtable.c
|
||||
+++ b/mm/debug_vm_pgtable.c
|
||||
@@ -1041,29 +1041,34 @@ static void __init destroy_args(struct p
|
||||
|
||||
/* Free page table entries */
|
||||
if (args->start_ptep) {
|
||||
+ pmd_clear(args->pmdp);
|
||||
pte_free(args->mm, args->start_ptep);
|
||||
mm_dec_nr_ptes(args->mm);
|
||||
}
|
||||
|
||||
if (args->start_pmdp) {
|
||||
+ pud_clear(args->pudp);
|
||||
pmd_free(args->mm, args->start_pmdp);
|
||||
mm_dec_nr_pmds(args->mm);
|
||||
}
|
||||
|
||||
if (args->start_pudp) {
|
||||
+ p4d_clear(args->p4dp);
|
||||
pud_free(args->mm, args->start_pudp);
|
||||
mm_dec_nr_puds(args->mm);
|
||||
}
|
||||
|
||||
- if (args->start_p4dp)
|
||||
+ if (args->start_p4dp) {
|
||||
+ pgd_clear(args->pgdp);
|
||||
p4d_free(args->mm, args->start_p4dp);
|
||||
+ }
|
||||
|
||||
/* Free vma and mm struct */
|
||||
if (args->vma)
|
||||
vm_area_free(args->vma);
|
||||
|
||||
if (args->mm)
|
||||
- mmdrop(args->mm);
|
||||
+ mmput(args->mm);
|
||||
}
|
||||
|
||||
static struct page * __init
|
@@ -1,52 +0,0 @@
|
||||
From 8e0fc5bd3c988e47827d000f51ffa73512a4a5b6 Mon Sep 17 00:00:00 2001
|
||||
From: Sang-Heon Jeon <ekffu200098@gmail.com>
|
||||
Date: Sun, 10 Aug 2025 21:42:01 +0900
|
||||
Subject: mm/damon/core: fix commit_ops_filters by using correct nth function
|
||||
|
||||
damos_commit_ops_filters() incorrectly uses damos_nth_filter() which
|
||||
iterates core_filters. As a result, performing a commit unintentionally
|
||||
corrupts ops_filters.
|
||||
|
||||
Add damos_nth_ops_filter() which iterates ops_filters. Use this function
|
||||
to fix issues caused by wrong iteration.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250810124201.15743-1-ekffu200098@gmail.com
|
||||
Fixes: 3607cc590f18 ("mm/damon/core: support committing ops_filters") # 6.15.x
|
||||
Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
|
||||
Reviewed-by: SeongJae Park <sj@kernel.org>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/damon/core.c | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/mm/damon/core.c
|
||||
+++ b/mm/damon/core.c
|
||||
@@ -843,6 +843,18 @@ static struct damos_filter *damos_nth_fi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static struct damos_filter *damos_nth_ops_filter(int n, struct damos *s)
|
||||
+{
|
||||
+ struct damos_filter *filter;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ damos_for_each_ops_filter(filter, s) {
|
||||
+ if (i++ == n)
|
||||
+ return filter;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void damos_commit_filter_arg(
|
||||
struct damos_filter *dst, struct damos_filter *src)
|
||||
{
|
||||
@@ -906,7 +918,7 @@ static int damos_commit_ops_filters(stru
|
||||
int i = 0, j = 0;
|
||||
|
||||
damos_for_each_ops_filter_safe(dst_filter, next, dst) {
|
||||
- src_filter = damos_nth_filter(i++, src);
|
||||
+ src_filter = damos_nth_ops_filter(i++, src);
|
||||
if (src_filter)
|
||||
damos_commit_filter(dst_filter, src_filter);
|
||||
else
|
@@ -1,77 +0,0 @@
|
||||
From 0623d1f6690209880885deae614e8368488598c2 Mon Sep 17 00:00:00 2001
|
||||
From: Dominique Martinet <asmadeus@codewreck.org>
|
||||
Date: Wed, 13 Aug 2025 15:04:55 +0900
|
||||
Subject: iov_iter: iterate_folioq: fix handling of offset >= folio size
|
||||
|
||||
It's apparently possible to get an iov advanced all the way up to the end
|
||||
of the current page we're looking at, e.g.
|
||||
|
||||
(gdb) p *iter
|
||||
$24 = {iter_type = 4 '\004', nofault = false, data_source = false, iov_offset = 4096, {__ubuf_iovec = {
|
||||
iov_base = 0xffff88800f5bc000, iov_len = 655}, {{__iov = 0xffff88800f5bc000, kvec = 0xffff88800f5bc000,
|
||||
bvec = 0xffff88800f5bc000, folioq = 0xffff88800f5bc000, xarray = 0xffff88800f5bc000,
|
||||
ubuf = 0xffff88800f5bc000}, count = 655}}, {nr_segs = 2, folioq_slot = 2 '\002', xarray_start = 2}}
|
||||
|
||||
Where iov_offset is 4k with 4k-sized folios
|
||||
|
||||
This should have been fine because we're only in the 2nd slot and there's
|
||||
another one after this, but iterate_folioq should not try to map a folio
|
||||
that skips the whole size, and more importantly part here does not end up
|
||||
zero (because 'PAGE_SIZE - skip % PAGE_SIZE' ends up PAGE_SIZE and not
|
||||
zero..), so skip forward to the "advance to next folio" code
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250813-iot_iter_folio-v3-0-a0ffad2b665a@codewreck.org
|
||||
Link: https://lkml.kernel.org/r/20250813-iot_iter_folio-v3-1-a0ffad2b665a@codewreck.org
|
||||
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
|
||||
Fixes: db0aa2e9566f ("mm: Define struct folio_queue and ITER_FOLIOQ to handle a sequence of folios")
|
||||
Reported-by: Maximilian Bosch <maximilian@mbosch.me>
|
||||
Reported-by: Ryan Lahfa <ryan@lahfa.xyz>
|
||||
Reported-by: Christian Theune <ct@flyingcircus.io>
|
||||
Reported-by: Arnout Engelen <arnout@bzzt.net>
|
||||
Link: https://lkml.kernel.org/r/D4LHHUNLG79Y.12PI0X6BEHRHW@mbosch.me/
|
||||
Acked-by: David Howells <dhowells@redhat.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Christian Brauner <brauner@kernel.org>
|
||||
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
|
||||
Cc: <stable@vger.kernel.org> [6.12+]
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
include/linux/iov_iter.h | 20 +++++++++++---------
|
||||
1 file changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/include/linux/iov_iter.h
|
||||
+++ b/include/linux/iov_iter.h
|
||||
@@ -160,7 +160,7 @@ size_t iterate_folioq(struct iov_iter *i
|
||||
|
||||
do {
|
||||
struct folio *folio = folioq_folio(folioq, slot);
|
||||
- size_t part, remain, consumed;
|
||||
+ size_t part, remain = 0, consumed;
|
||||
size_t fsize;
|
||||
void *base;
|
||||
|
||||
@@ -168,14 +168,16 @@ size_t iterate_folioq(struct iov_iter *i
|
||||
break;
|
||||
|
||||
fsize = folioq_folio_size(folioq, slot);
|
||||
- base = kmap_local_folio(folio, skip);
|
||||
- part = umin(len, PAGE_SIZE - skip % PAGE_SIZE);
|
||||
- remain = step(base, progress, part, priv, priv2);
|
||||
- kunmap_local(base);
|
||||
- consumed = part - remain;
|
||||
- len -= consumed;
|
||||
- progress += consumed;
|
||||
- skip += consumed;
|
||||
+ if (skip < fsize) {
|
||||
+ base = kmap_local_folio(folio, skip);
|
||||
+ part = umin(len, PAGE_SIZE - skip % PAGE_SIZE);
|
||||
+ remain = step(base, progress, part, priv, priv2);
|
||||
+ kunmap_local(base);
|
||||
+ consumed = part - remain;
|
||||
+ len -= consumed;
|
||||
+ progress += consumed;
|
||||
+ skip += consumed;
|
||||
+ }
|
||||
if (skip >= fsize) {
|
||||
skip = 0;
|
||||
slot++;
|
@@ -1,57 +0,0 @@
|
||||
From 786e39b5e75b7d766b7930519d504a90eaf887da Mon Sep 17 00:00:00 2001
|
||||
From: Jinjiang Tu <tujinjiang@huawei.com>
|
||||
Date: Fri, 15 Aug 2025 15:32:09 +0800
|
||||
Subject: mm/memory-failure: fix infinite UCE for VM_PFNMAP pfn
|
||||
|
||||
When memory_failure() is called for a already hwpoisoned pfn,
|
||||
kill_accessing_process() will be called to kill current task. However, if
|
||||
the vma of the accessing vaddr is VM_PFNMAP, walk_page_range() will skip
|
||||
the vma in walk_page_test() and return 0.
|
||||
|
||||
Before commit aaf99ac2ceb7 ("mm/hwpoison: do not send SIGBUS to processes
|
||||
with recovered clean pages"), kill_accessing_process() will return EFAULT.
|
||||
For x86, the current task will be killed in kill_me_maybe().
|
||||
|
||||
However, after this commit, kill_accessing_process() simplies return 0,
|
||||
that means UCE is handled properly, but it doesn't actually. In such
|
||||
case, the user task will trigger UCE infinitely.
|
||||
|
||||
To fix it, add .test_walk callback for hwpoison_walk_ops to scan all vmas.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250815073209.1984582-1-tujinjiang@huawei.com
|
||||
Fixes: aaf99ac2ceb7 ("mm/hwpoison: do not send SIGBUS to processes with recovered clean pages")
|
||||
Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
|
||||
Acked-by: David Hildenbrand <david@redhat.com>
|
||||
Acked-by: Miaohe Lin <linmiaohe@huawei.com>
|
||||
Reviewed-by: Jane Chu <jane.chu@oracle.com>
|
||||
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
|
||||
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
|
||||
Cc: Oscar Salvador <osalvador@suse.de>
|
||||
Cc: Shuai Xue <xueshuai@linux.alibaba.com>
|
||||
Cc: Zi Yan <ziy@nvidia.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/memory-failure.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/mm/memory-failure.c
|
||||
+++ b/mm/memory-failure.c
|
||||
@@ -847,9 +847,17 @@ static int hwpoison_hugetlb_range(pte_t
|
||||
#define hwpoison_hugetlb_range NULL
|
||||
#endif
|
||||
|
||||
+static int hwpoison_test_walk(unsigned long start, unsigned long end,
|
||||
+ struct mm_walk *walk)
|
||||
+{
|
||||
+ /* We also want to consider pages mapped into VM_PFNMAP. */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct mm_walk_ops hwpoison_walk_ops = {
|
||||
.pmd_entry = hwpoison_pte_range,
|
||||
.hugetlb_entry = hwpoison_hugetlb_range,
|
||||
+ .test_walk = hwpoison_test_walk,
|
||||
.walk_lock = PGWALK_RDLOCK,
|
||||
};
|
||||
|
@@ -1,32 +0,0 @@
|
||||
From 40faa11c480476ef29d74f44c0126026b37d988d Mon Sep 17 00:00:00 2001
|
||||
From: Sang-Heon Jeon <ekffu200098@gmail.com>
|
||||
Date: Sat, 16 Aug 2025 10:51:16 +0900
|
||||
Subject: mm/damon/core: fix damos_commit_filter not changing allow
|
||||
|
||||
Current damos_commit_filter() does not persist the `allow' value of the
|
||||
filter. As a result, changing the `allow' value of a filter and
|
||||
committing doesn't change the `allow' value.
|
||||
|
||||
Add the missing `allow' value update, so committing the filter
|
||||
persistently changes the `allow' value well.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250816015116.194589-1-ekffu200098@gmail.com
|
||||
Fixes: fe6d7fdd6249 ("mm/damon/core: add damos_filter->allow field")
|
||||
Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
|
||||
Reviewed-by: SeongJae Park <sj@kernel.org>
|
||||
Cc: <stable@vger.kernel.org> [6.14.x]
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/damon/core.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/mm/damon/core.c
|
||||
+++ b/mm/damon/core.c
|
||||
@@ -881,6 +881,7 @@ static void damos_commit_filter(
|
||||
{
|
||||
dst->type = src->type;
|
||||
dst->matching = src->matching;
|
||||
+ dst->allow = src->allow;
|
||||
damos_commit_filter_arg(dst, src);
|
||||
}
|
||||
|
@@ -1,157 +0,0 @@
|
||||
From 148516b367dd591d31a2b98ad913417bc1b9c865 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Mon, 18 Aug 2025 19:53:58 +0200
|
||||
Subject: mm/mremap: fix WARN with uffd that has remap events disabled
|
||||
|
||||
Registering userfaultd on a VMA that spans at least one PMD and then
|
||||
mremap()'ing that VMA can trigger a WARN when recovering from a failed
|
||||
page table move due to a page table allocation error.
|
||||
|
||||
The code ends up doing the right thing (recurse, avoiding moving actual
|
||||
page tables), but triggering that WARN is unpleasant:
|
||||
|
||||
WARNING: CPU: 2 PID: 6133 at mm/mremap.c:357 move_normal_pmd mm/mremap.c:357 [inline]
|
||||
WARNING: CPU: 2 PID: 6133 at mm/mremap.c:357 move_pgt_entry mm/mremap.c:595 [inline]
|
||||
WARNING: CPU: 2 PID: 6133 at mm/mremap.c:357 move_page_tables+0x3832/0x44a0 mm/mremap.c:852
|
||||
Modules linked in:
|
||||
CPU: 2 UID: 0 PID: 6133 Comm: syz.0.19 Not tainted 6.17.0-rc1-syzkaller-00004-g53e760d89498 #0 PREEMPT(full)
|
||||
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
|
||||
RIP: 0010:move_normal_pmd mm/mremap.c:357 [inline]
|
||||
RIP: 0010:move_pgt_entry mm/mremap.c:595 [inline]
|
||||
RIP: 0010:move_page_tables+0x3832/0x44a0 mm/mremap.c:852
|
||||
Code: ...
|
||||
RSP: 0018:ffffc900037a76d8 EFLAGS: 00010293
|
||||
RAX: 0000000000000000 RBX: 0000000032930007 RCX: ffffffff820c6645
|
||||
RDX: ffff88802e56a440 RSI: ffffffff820c7201 RDI: 0000000000000007
|
||||
RBP: ffff888037728fc0 R08: 0000000000000007 R09: 0000000000000000
|
||||
R10: 0000000032930007 R11: 0000000000000000 R12: 0000000000000000
|
||||
R13: ffffc900037a79a8 R14: 0000000000000001 R15: dffffc0000000000
|
||||
FS: 000055556316a500(0000) GS:ffff8880d68bc000(0000) knlGS:0000000000000000
|
||||
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
CR2: 0000001b30863fff CR3: 0000000050171000 CR4: 0000000000352ef0
|
||||
Call Trace:
|
||||
<TASK>
|
||||
copy_vma_and_data+0x468/0x790 mm/mremap.c:1215
|
||||
move_vma+0x548/0x1780 mm/mremap.c:1282
|
||||
mremap_to+0x1b7/0x450 mm/mremap.c:1406
|
||||
do_mremap+0xfad/0x1f80 mm/mremap.c:1921
|
||||
__do_sys_mremap+0x119/0x170 mm/mremap.c:1977
|
||||
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
|
||||
do_syscall_64+0xcd/0x4c0 arch/x86/entry/syscall_64.c:94
|
||||
entry_SYSCALL_64_after_hwframe+0x77/0x7f
|
||||
RIP: 0033:0x7f00d0b8ebe9
|
||||
Code: ...
|
||||
RSP: 002b:00007ffe5ea5ee98 EFLAGS: 00000246 ORIG_RAX: 0000000000000019
|
||||
RAX: ffffffffffffffda RBX: 00007f00d0db5fa0 RCX: 00007f00d0b8ebe9
|
||||
RDX: 0000000000400000 RSI: 0000000000c00000 RDI: 0000200000000000
|
||||
RBP: 00007ffe5ea5eef0 R08: 0000200000c00000 R09: 0000000000000000
|
||||
R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000002
|
||||
R13: 00007f00d0db5fa0 R14: 00007f00d0db5fa0 R15: 0000000000000005
|
||||
</TASK>
|
||||
|
||||
The underlying issue is that we recurse during the original page table
|
||||
move, but not during the recovery move.
|
||||
|
||||
Fix it by checking for both VMAs and performing the check before the
|
||||
pmd_none() sanity check.
|
||||
|
||||
Add a new helper where we perform+document that check for the PMD and PUD
|
||||
level.
|
||||
|
||||
Thanks to Harry for bisecting.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250818175358.1184757-1-david@redhat.com
|
||||
Fixes: 0cef0bb836e3 ("mm: clear uffd-wp PTE/PMD state on mremap()")
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
Reported-by: syzbot+4d9a13f0797c46a29e42@syzkaller.appspotmail.com
|
||||
Closes: https://lkml.kernel.org/r/689bb893.050a0220.7f033.013a.GAE@google.com
|
||||
Tested-by: Harry Yoo <harry.yoo@oracle.com>
|
||||
Cc: "Liam R. Howlett" <Liam.Howlett@oracle.com>
|
||||
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
Cc: Vlastimil Babka <vbabka@suse.cz>
|
||||
Cc: Jann Horn <jannh@google.com>
|
||||
Cc: Pedro Falcato <pfalcato@suse.de>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
mm/mremap.c | 41 +++++++++++++++++++++++------------------
|
||||
1 file changed, 23 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/mm/mremap.c
|
||||
+++ b/mm/mremap.c
|
||||
@@ -294,6 +294,25 @@ static inline bool arch_supports_page_ta
|
||||
}
|
||||
#endif
|
||||
|
||||
+static inline bool uffd_supports_page_table_move(struct pagetable_move_control *pmc)
|
||||
+{
|
||||
+ /*
|
||||
+ * If we are moving a VMA that has uffd-wp registered but with
|
||||
+ * remap events disabled (new VMA will not be registered with uffd), we
|
||||
+ * need to ensure that the uffd-wp state is cleared from all pgtables.
|
||||
+ * This means recursing into lower page tables in move_page_tables().
|
||||
+ *
|
||||
+ * We might get called with VMAs reversed when recovering from a
|
||||
+ * failed page table move. In that case, the
|
||||
+ * "old"-but-actually-"originally new" VMA during recovery will not have
|
||||
+ * a uffd context. Recursing into lower page tables during the original
|
||||
+ * move but not during the recovery move will cause trouble, because we
|
||||
+ * run into already-existing page tables. So check both VMAs.
|
||||
+ */
|
||||
+ return !vma_has_uffd_without_event_remap(pmc->old) &&
|
||||
+ !vma_has_uffd_without_event_remap(pmc->new);
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_HAVE_MOVE_PMD
|
||||
static bool move_normal_pmd(struct pagetable_move_control *pmc,
|
||||
pmd_t *old_pmd, pmd_t *new_pmd)
|
||||
@@ -306,6 +325,8 @@ static bool move_normal_pmd(struct paget
|
||||
|
||||
if (!arch_supports_page_table_move())
|
||||
return false;
|
||||
+ if (!uffd_supports_page_table_move(pmc))
|
||||
+ return false;
|
||||
/*
|
||||
* The destination pmd shouldn't be established, free_pgtables()
|
||||
* should have released it.
|
||||
@@ -332,15 +353,6 @@ static bool move_normal_pmd(struct paget
|
||||
if (WARN_ON_ONCE(!pmd_none(*new_pmd)))
|
||||
return false;
|
||||
|
||||
- /* If this pmd belongs to a uffd vma with remap events disabled, we need
|
||||
- * to ensure that the uffd-wp state is cleared from all pgtables. This
|
||||
- * means recursing into lower page tables in move_page_tables(), and we
|
||||
- * can reuse the existing code if we simply treat the entry as "not
|
||||
- * moved".
|
||||
- */
|
||||
- if (vma_has_uffd_without_event_remap(vma))
|
||||
- return false;
|
||||
-
|
||||
/*
|
||||
* We don't have to worry about the ordering of src and dst
|
||||
* ptlocks because exclusive mmap_lock prevents deadlock.
|
||||
@@ -389,6 +401,8 @@ static bool move_normal_pud(struct paget
|
||||
|
||||
if (!arch_supports_page_table_move())
|
||||
return false;
|
||||
+ if (!uffd_supports_page_table_move(pmc))
|
||||
+ return false;
|
||||
/*
|
||||
* The destination pud shouldn't be established, free_pgtables()
|
||||
* should have released it.
|
||||
@@ -396,15 +410,6 @@ static bool move_normal_pud(struct paget
|
||||
if (WARN_ON_ONCE(!pud_none(*new_pud)))
|
||||
return false;
|
||||
|
||||
- /* If this pud belongs to a uffd vma with remap events disabled, we need
|
||||
- * to ensure that the uffd-wp state is cleared from all pgtables. This
|
||||
- * means recursing into lower page tables in move_page_tables(), and we
|
||||
- * can reuse the existing code if we simply treat the entry as "not
|
||||
- * moved".
|
||||
- */
|
||||
- if (vma_has_uffd_without_event_remap(vma))
|
||||
- return false;
|
||||
-
|
||||
/*
|
||||
* We don't have to worry about the ordering of src and dst
|
||||
* ptlocks because exclusive mmap_lock prevents deadlock.
|
@@ -1,31 +0,0 @@
|
||||
From 33950693dc7b0306b42d8efffbe26bfa5caa478b Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Wed, 20 Aug 2025 07:19:01 +0200
|
||||
Subject: ALSA: hda: tas2781: Fix wrong reference of tasdevice_priv
|
||||
|
||||
During the conversion to unify the calibration data management, the
|
||||
reference to tasdevice_priv was wrongly set to h->hda_priv instead of
|
||||
h->priv. This resulted in memory corruption and crashes eventually.
|
||||
Unfortunately it's a void pointer, hence the compiler couldn't know
|
||||
that it's wrong.
|
||||
|
||||
Fixes: 4fe238513407 ("ALSA: hda/tas2781: Move and unified the calibrated-data getting function for SPI and I2C into the tas2781_hda lib")
|
||||
Link: https://bugzilla.suse.com/show_bug.cgi?id=1248270
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Link: https://patch.msgid.link/20250820051902.4523-1-tiwai@suse.de
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/tas2781_hda_i2c.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/sound/pci/hda/tas2781_hda_i2c.c
|
||||
+++ b/sound/pci/hda/tas2781_hda_i2c.c
|
||||
@@ -287,7 +287,7 @@ static int tas2563_save_calibration(stru
|
||||
efi_char16_t efi_name[TAS2563_CAL_VAR_NAME_MAX];
|
||||
unsigned long max_size = TAS2563_CAL_DATA_SIZE;
|
||||
unsigned char var8[TAS2563_CAL_VAR_NAME_MAX];
|
||||
- struct tasdevice_priv *p = h->hda_priv;
|
||||
+ struct tasdevice_priv *p = h->priv;
|
||||
struct calidata *cd = &p->cali_data;
|
||||
struct cali_reg *r = &cd->cali_reg_array;
|
||||
unsigned int offset = 0;
|
@@ -1,142 +0,0 @@
|
||||
From f7a227320aab53c99656f21d40481af89dfb8923 Mon Sep 17 00:00:00 2001
|
||||
From: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Fri, 1 Aug 2025 16:37:23 -0400
|
||||
Subject: tracing: Remove unneeded goto out logic
|
||||
|
||||
Several places in the trace.c file there's a goto out where the out is
|
||||
simply a return. There's no reason to jump to the out label if it's not
|
||||
doing any more logic but simply returning from the function.
|
||||
|
||||
Replace the goto outs with a return and remove the out labels.
|
||||
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Link: https://lore.kernel.org/20250801203857.538726745@kernel.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
---
|
||||
kernel/trace/trace.c | 38 +++++++++++++++-----------------------
|
||||
1 file changed, 15 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/kernel/trace/trace.c
|
||||
+++ b/kernel/trace/trace.c
|
||||
@@ -1846,7 +1846,7 @@ int trace_get_user(struct trace_parser *
|
||||
|
||||
ret = get_user(ch, ubuf++);
|
||||
if (ret)
|
||||
- goto out;
|
||||
+ return ret;
|
||||
|
||||
read++;
|
||||
cnt--;
|
||||
@@ -1860,7 +1860,7 @@ int trace_get_user(struct trace_parser *
|
||||
while (cnt && isspace(ch)) {
|
||||
ret = get_user(ch, ubuf++);
|
||||
if (ret)
|
||||
- goto out;
|
||||
+ return ret;
|
||||
read++;
|
||||
cnt--;
|
||||
}
|
||||
@@ -1870,8 +1870,7 @@ int trace_get_user(struct trace_parser *
|
||||
/* only spaces were written */
|
||||
if (isspace(ch) || !ch) {
|
||||
*ppos += read;
|
||||
- ret = read;
|
||||
- goto out;
|
||||
+ return read;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1879,13 +1878,12 @@ int trace_get_user(struct trace_parser *
|
||||
while (cnt && !isspace(ch) && ch) {
|
||||
if (parser->idx < parser->size - 1)
|
||||
parser->buffer[parser->idx++] = ch;
|
||||
- else {
|
||||
- ret = -EINVAL;
|
||||
- goto out;
|
||||
- }
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
ret = get_user(ch, ubuf++);
|
||||
if (ret)
|
||||
- goto out;
|
||||
+ return ret;
|
||||
read++;
|
||||
cnt--;
|
||||
}
|
||||
@@ -1900,15 +1898,11 @@ int trace_get_user(struct trace_parser *
|
||||
/* Make sure the parsed string always terminates with '\0'. */
|
||||
parser->buffer[parser->idx] = 0;
|
||||
} else {
|
||||
- ret = -EINVAL;
|
||||
- goto out;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
*ppos += read;
|
||||
- ret = read;
|
||||
-
|
||||
-out:
|
||||
- return ret;
|
||||
+ return read;
|
||||
}
|
||||
|
||||
/* TODO add a seq_buf_to_buffer() */
|
||||
@@ -2410,10 +2404,10 @@ int __init register_tracer(struct tracer
|
||||
mutex_unlock(&trace_types_lock);
|
||||
|
||||
if (ret || !default_bootup_tracer)
|
||||
- goto out_unlock;
|
||||
+ return ret;
|
||||
|
||||
if (strncmp(default_bootup_tracer, type->name, MAX_TRACER_SIZE))
|
||||
- goto out_unlock;
|
||||
+ return 0;
|
||||
|
||||
printk(KERN_INFO "Starting tracer '%s'\n", type->name);
|
||||
/* Do we want this tracer to start on bootup? */
|
||||
@@ -2425,8 +2419,7 @@ int __init register_tracer(struct tracer
|
||||
/* disable other selftests, since this will break it. */
|
||||
disable_tracing_selftest("running a tracer");
|
||||
|
||||
- out_unlock:
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void tracing_reset_cpu(struct array_buffer *buf, int cpu)
|
||||
@@ -8954,12 +8947,12 @@ ftrace_trace_snapshot_callback(struct tr
|
||||
out_reg:
|
||||
ret = tracing_arm_snapshot(tr);
|
||||
if (ret < 0)
|
||||
- goto out;
|
||||
+ return ret;
|
||||
|
||||
ret = register_ftrace_function_probe(glob, tr, ops, count);
|
||||
if (ret < 0)
|
||||
tracing_disarm_snapshot(tr);
|
||||
- out:
|
||||
+
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
@@ -11057,7 +11050,7 @@ __init static int tracer_alloc_buffers(v
|
||||
BUILD_BUG_ON(TRACE_ITER_LAST_BIT > TRACE_FLAGS_MAX_SIZE);
|
||||
|
||||
if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL))
|
||||
- goto out;
|
||||
+ return -ENOMEM;
|
||||
|
||||
if (!alloc_cpumask_var(&global_trace.tracing_cpumask, GFP_KERNEL))
|
||||
goto out_free_buffer_mask;
|
||||
@@ -11175,7 +11168,6 @@ out_free_cpumask:
|
||||
free_cpumask_var(global_trace.tracing_cpumask);
|
||||
out_free_buffer_mask:
|
||||
free_cpumask_var(tracing_buffer_mask);
|
||||
-out:
|
||||
return ret;
|
||||
}
|
||||
|
@@ -1,133 +0,0 @@
|
||||
From 04b512d5cc10cec9e13eb434ea8d16d899244e6e Mon Sep 17 00:00:00 2001
|
||||
From: Pu Lehui <pulehui@huawei.com>
|
||||
Date: Wed, 13 Aug 2025 04:02:32 +0000
|
||||
Subject: tracing: Limit access to parser->buffer when trace_get_user failed
|
||||
|
||||
When the length of the string written to set_ftrace_filter exceeds
|
||||
FTRACE_BUFF_MAX, the following KASAN alarm will be triggered:
|
||||
|
||||
BUG: KASAN: slab-out-of-bounds in strsep+0x18c/0x1b0
|
||||
Read of size 1 at addr ffff0000d00bd5ba by task ash/165
|
||||
|
||||
CPU: 1 UID: 0 PID: 165 Comm: ash Not tainted 6.16.0-g6bcdbd62bd56-dirty
|
||||
Hardware name: linux,dummy-virt (DT)
|
||||
Call trace:
|
||||
show_stack+0x34/0x50 (C)
|
||||
dump_stack_lvl+0xa0/0x158
|
||||
print_address_description.constprop.0+0x88/0x398
|
||||
print_report+0xb0/0x280
|
||||
kasan_report+0xa4/0xf0
|
||||
__asan_report_load1_noabort+0x20/0x30
|
||||
strsep+0x18c/0x1b0
|
||||
ftrace_process_regex.isra.0+0x100/0x2d8
|
||||
ftrace_regex_release+0x484/0x618
|
||||
__fput+0x364/0xa58
|
||||
____fput+0x28/0x40
|
||||
task_work_run+0x154/0x278
|
||||
do_notify_resume+0x1f0/0x220
|
||||
el0_svc+0xec/0xf0
|
||||
el0t_64_sync_handler+0xa0/0xe8
|
||||
el0t_64_sync+0x1ac/0x1b0
|
||||
|
||||
The reason is that trace_get_user will fail when processing a string
|
||||
longer than FTRACE_BUFF_MAX, but not set the end of parser->buffer to 0.
|
||||
Then an OOB access will be triggered in ftrace_regex_release->
|
||||
ftrace_process_regex->strsep->strpbrk. We can solve this problem by
|
||||
limiting access to parser->buffer when trace_get_user failed.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Link: https://lore.kernel.org/20250813040232.1344527-1-pulehui@huaweicloud.com
|
||||
Fixes: 8c9af478c06b ("ftrace: Handle commands when closing set_ftrace_filter file")
|
||||
Signed-off-by: Pu Lehui <pulehui@huawei.com>
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
---
|
||||
kernel/trace/trace.c | 18 ++++++++++++------
|
||||
kernel/trace/trace.h | 8 +++++++-
|
||||
2 files changed, 19 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/kernel/trace/trace.c
|
||||
+++ b/kernel/trace/trace.c
|
||||
@@ -1846,7 +1846,7 @@ int trace_get_user(struct trace_parser *
|
||||
|
||||
ret = get_user(ch, ubuf++);
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto fail;
|
||||
|
||||
read++;
|
||||
cnt--;
|
||||
@@ -1860,7 +1860,7 @@ int trace_get_user(struct trace_parser *
|
||||
while (cnt && isspace(ch)) {
|
||||
ret = get_user(ch, ubuf++);
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto fail;
|
||||
read++;
|
||||
cnt--;
|
||||
}
|
||||
@@ -1878,12 +1878,14 @@ int trace_get_user(struct trace_parser *
|
||||
while (cnt && !isspace(ch) && ch) {
|
||||
if (parser->idx < parser->size - 1)
|
||||
parser->buffer[parser->idx++] = ch;
|
||||
- else
|
||||
- return -EINVAL;
|
||||
+ else {
|
||||
+ ret = -EINVAL;
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
ret = get_user(ch, ubuf++);
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto fail;
|
||||
read++;
|
||||
cnt--;
|
||||
}
|
||||
@@ -1898,11 +1900,15 @@ int trace_get_user(struct trace_parser *
|
||||
/* Make sure the parsed string always terminates with '\0'. */
|
||||
parser->buffer[parser->idx] = 0;
|
||||
} else {
|
||||
- return -EINVAL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto fail;
|
||||
}
|
||||
|
||||
*ppos += read;
|
||||
return read;
|
||||
+fail:
|
||||
+ trace_parser_fail(parser);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/* TODO add a seq_buf_to_buffer() */
|
||||
--- a/kernel/trace/trace.h
|
||||
+++ b/kernel/trace/trace.h
|
||||
@@ -1292,6 +1292,7 @@ bool ftrace_event_is_function(struct tra
|
||||
*/
|
||||
struct trace_parser {
|
||||
bool cont;
|
||||
+ bool fail;
|
||||
char *buffer;
|
||||
unsigned idx;
|
||||
unsigned size;
|
||||
@@ -1299,7 +1300,7 @@ struct trace_parser {
|
||||
|
||||
static inline bool trace_parser_loaded(struct trace_parser *parser)
|
||||
{
|
||||
- return (parser->idx != 0);
|
||||
+ return !parser->fail && parser->idx != 0;
|
||||
}
|
||||
|
||||
static inline bool trace_parser_cont(struct trace_parser *parser)
|
||||
@@ -1313,6 +1314,11 @@ static inline void trace_parser_clear(st
|
||||
parser->idx = 0;
|
||||
}
|
||||
|
||||
+static inline void trace_parser_fail(struct trace_parser *parser)
|
||||
+{
|
||||
+ parser->fail = true;
|
||||
+}
|
||||
+
|
||||
extern int trace_parser_get_init(struct trace_parser *parser, int size);
|
||||
extern void trace_parser_put(struct trace_parser *parser);
|
||||
extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
|
@@ -1,44 +0,0 @@
|
||||
From e127b3ec622c786e42ce3a05cf15bfc50f24adc3 Mon Sep 17 00:00:00 2001
|
||||
From: Chen Yu <yu.c.chen@intel.com>
|
||||
Date: Tue, 22 Jul 2025 22:32:33 +0800
|
||||
Subject: ACPI: pfr_update: Fix the driver update version check
|
||||
|
||||
The security-version-number check should be used rather
|
||||
than the runtime version check for driver updates.
|
||||
|
||||
Otherwise, the firmware update would fail when the update binary had
|
||||
a lower runtime version number than the current one.
|
||||
|
||||
Fixes: 0db89fa243e5 ("ACPI: Introduce Platform Firmware Runtime Update device driver")
|
||||
Cc: 5.17+ <stable@vger.kernel.org> # 5.17+
|
||||
Reported-by: "Govindarajulu, Hariganesh" <hariganesh.govindarajulu@intel.com>
|
||||
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
|
||||
Link: https://patch.msgid.link/20250722143233.3970607-1-yu.c.chen@intel.com
|
||||
[ rjw: Changelog edits ]
|
||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
---
|
||||
drivers/acpi/pfr_update.c | 2 +-
|
||||
include/uapi/linux/pfrut.h | 1 +
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/acpi/pfr_update.c
|
||||
+++ b/drivers/acpi/pfr_update.c
|
||||
@@ -310,7 +310,7 @@ static bool applicable_image(const void
|
||||
if (type == PFRU_CODE_INJECT_TYPE)
|
||||
return payload_hdr->rt_ver >= cap->code_rt_version;
|
||||
|
||||
- return payload_hdr->rt_ver >= cap->drv_rt_version;
|
||||
+ return payload_hdr->svn_ver >= cap->drv_svn;
|
||||
}
|
||||
|
||||
static void print_update_debug_info(struct pfru_updated_result *result,
|
||||
--- a/include/uapi/linux/pfrut.h
|
||||
+++ b/include/uapi/linux/pfrut.h
|
||||
@@ -89,6 +89,7 @@ struct pfru_payload_hdr {
|
||||
__u32 hw_ver;
|
||||
__u32 rt_ver;
|
||||
__u8 platform_id[16];
|
||||
+ __u32 svn_ver;
|
||||
};
|
||||
|
||||
enum pfru_dsm_status {
|
@@ -1,36 +0,0 @@
|
||||
From 3e5eb20e114e1bec6a762488a5a3b7aa9632e634 Mon Sep 17 00:00:00 2001
|
||||
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
|
||||
Date: Sat, 16 Aug 2025 23:10:51 +0900
|
||||
Subject: tracing: fprobe-event: Sanitize wildcard for fprobe event name
|
||||
|
||||
Fprobe event accepts wildcards for the target functions, but unless user
|
||||
specifies its event name, it makes an event with the wildcards.
|
||||
|
||||
/sys/kernel/tracing # echo 'f mutex*' >> dynamic_events
|
||||
/sys/kernel/tracing # cat dynamic_events
|
||||
f:fprobes/mutex*__entry mutex*
|
||||
/sys/kernel/tracing # ls events/fprobes/
|
||||
enable filter mutex*__entry
|
||||
|
||||
To fix this, replace the wildcard ('*') with an underscore.
|
||||
|
||||
Link: https://lore.kernel.org/all/175535345114.282990.12294108192847938710.stgit@devnote2/
|
||||
|
||||
Fixes: 334e5519c375 ("tracing/probes: Add fprobe events for tracing function entry and exit.")
|
||||
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
kernel/trace/trace.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/kernel/trace/trace.h
|
||||
+++ b/kernel/trace/trace.h
|
||||
@@ -2210,7 +2210,7 @@ static inline bool is_good_system_name(c
|
||||
static inline void sanitize_event_name(char *name)
|
||||
{
|
||||
while (*name++ != '\0')
|
||||
- if (*name == ':' || *name == '.')
|
||||
+ if (*name == ':' || *name == '.' || *name == '*')
|
||||
*name = '_';
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user